Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "SessionStorage.h"
8
#include "SessionStorageCache.h"
9
#include "SessionStorageManager.h"
10
11
#include "mozilla/dom/StorageBinding.h"
12
#include "mozilla/Preferences.h"
13
#include "nsContentUtils.h"
14
#include "nsIPrincipal.h"
15
#include "nsPIDOMWindow.h"
16
17
#define DATASET \
18
IsSessionOnly() ? SessionStorageCache::eSessionSetType \
19
: SessionStorageCache::eDefaultSetType
20
21
namespace mozilla {
22
namespace dom {
23
24
NS_IMPL_CYCLE_COLLECTION_INHERITED(SessionStorage, Storage, mManager);
25
26
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SessionStorage)
27
NS_INTERFACE_MAP_END_INHERITING(Storage)
28
29
NS_IMPL_ADDREF_INHERITED(SessionStorage, Storage)
30
NS_IMPL_RELEASE_INHERITED(SessionStorage, Storage)
31
32
SessionStorage::SessionStorage(nsPIDOMWindowInner* aWindow,
33
nsIPrincipal* aPrincipal,
34
SessionStorageCache* aCache,
35
SessionStorageManager* aManager,
36
const nsAString& aDocumentURI, bool aIsPrivate)
37
: Storage(aWindow, aPrincipal, aPrincipal),
38
mCache(aCache),
39
mManager(aManager),
40
mDocumentURI(aDocumentURI),
41
mIsPrivate(aIsPrivate) {
42
MOZ_ASSERT(aCache);
43
}
44
45
SessionStorage::~SessionStorage() {}
46
47
int64_t SessionStorage::GetOriginQuotaUsage() const {
48
return mCache->GetOriginQuotaUsage(DATASET);
49
}
50
51
uint32_t SessionStorage::GetLength(nsIPrincipal& aSubjectPrincipal,
52
ErrorResult& aRv) {
53
if (!CanUseStorage(aSubjectPrincipal)) {
54
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
55
return 0;
56
}
57
58
return mCache->Length(DATASET);
59
}
60
61
void SessionStorage::Key(uint32_t aIndex, nsAString& aResult,
62
nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
63
if (!CanUseStorage(aSubjectPrincipal)) {
64
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
65
return;
66
}
67
68
mCache->Key(DATASET, aIndex, aResult);
69
}
70
71
void SessionStorage::GetItem(const nsAString& aKey, nsAString& aResult,
72
nsIPrincipal& aSubjectPrincipal,
73
ErrorResult& aRv) {
74
if (!CanUseStorage(aSubjectPrincipal)) {
75
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
76
return;
77
}
78
79
mCache->GetItem(DATASET, aKey, aResult);
80
}
81
82
void SessionStorage::GetSupportedNames(nsTArray<nsString>& aKeys) {
83
if (!CanUseStorage(*nsContentUtils::SubjectPrincipal())) {
84
// return just an empty array
85
aKeys.Clear();
86
return;
87
}
88
89
mCache->GetKeys(DATASET, aKeys);
90
}
91
92
void SessionStorage::SetItem(const nsAString& aKey, const nsAString& aValue,
93
nsIPrincipal& aSubjectPrincipal,
94
ErrorResult& aRv) {
95
if (!CanUseStorage(aSubjectPrincipal)) {
96
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
97
return;
98
}
99
100
nsString oldValue;
101
nsresult rv = mCache->SetItem(DATASET, aKey, aValue, oldValue);
102
if (NS_WARN_IF(NS_FAILED(rv))) {
103
aRv.Throw(rv);
104
return;
105
}
106
107
if (rv == NS_SUCCESS_DOM_NO_OPERATION) {
108
return;
109
}
110
111
BroadcastChangeNotification(aKey, oldValue, aValue);
112
}
113
114
void SessionStorage::RemoveItem(const nsAString& aKey,
115
nsIPrincipal& aSubjectPrincipal,
116
ErrorResult& aRv) {
117
if (!CanUseStorage(aSubjectPrincipal)) {
118
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
119
return;
120
}
121
122
nsString oldValue;
123
nsresult rv = mCache->RemoveItem(DATASET, aKey, oldValue);
124
MOZ_ASSERT(NS_SUCCEEDED(rv));
125
126
if (rv == NS_SUCCESS_DOM_NO_OPERATION) {
127
return;
128
}
129
130
BroadcastChangeNotification(aKey, oldValue, VoidString());
131
}
132
133
void SessionStorage::Clear(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
134
uint32_t length = GetLength(aSubjectPrincipal, aRv);
135
if (!length) {
136
return;
137
}
138
139
mCache->Clear(DATASET);
140
BroadcastChangeNotification(VoidString(), VoidString(), VoidString());
141
}
142
143
void SessionStorage::BroadcastChangeNotification(const nsAString& aKey,
144
const nsAString& aOldValue,
145
const nsAString& aNewValue) {
146
NotifyChange(this, Principal(), aKey, aOldValue, aNewValue, u"sessionStorage",
147
mDocumentURI, mIsPrivate, false);
148
}
149
150
bool SessionStorage::IsForkOf(const Storage* aOther) const {
151
MOZ_ASSERT(aOther);
152
if (aOther->Type() != eSessionStorage) {
153
return false;
154
}
155
156
return mCache == static_cast<const SessionStorage*>(aOther)->mCache;
157
}
158
159
} // namespace dom
160
} // namespace mozilla