1 : /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
2 : /* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla DOM Storage.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * The Mozilla Foundation.
20 : * Portions created by the Initial Developer are Copyright (C) 2010
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Josh Matthews <josh@joshmatthews.net> (original author)
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "StorageChild.h"
41 : #include "mozilla/dom/ContentChild.h"
42 : #include "nsDOMError.h"
43 :
44 : namespace mozilla {
45 : namespace dom {
46 :
47 1464 : NS_IMPL_CYCLE_COLLECTION_1(StorageChild, mStorage)
48 :
49 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(StorageChild)
50 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StorageChild)
51 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
52 0 : NS_INTERFACE_MAP_END
53 :
54 0 : NS_IMETHODIMP_(nsrefcnt) StorageChild::Release(void)
55 : {
56 0 : NS_PRECONDITION(0 != mRefCnt, "dup release");
57 0 : NS_ASSERT_OWNINGTHREAD(StorageChild);
58 0 : nsISupports* base = NS_CYCLE_COLLECTION_CLASSNAME(StorageChild)::Upcast(this);
59 0 : nsrefcnt count = mRefCnt.decr(base);
60 0 : NS_LOG_RELEASE(this, count, "StorageChild");
61 0 : if (count == 1 && mIPCOpen) {
62 0 : Send__delete__(this);
63 0 : return 0;
64 : }
65 0 : if (count == 0) {
66 0 : mRefCnt.stabilizeForDeletion(base);
67 0 : delete this;
68 0 : return 0;
69 : }
70 0 : return count;
71 : }
72 :
73 0 : StorageChild::StorageChild(nsDOMStorage* aOwner)
74 : : mStorage(aOwner)
75 0 : , mIPCOpen(false)
76 : {
77 0 : }
78 :
79 0 : StorageChild::StorageChild(nsDOMStorage* aOwner, StorageChild& aOther)
80 : : DOMStorageBase(aOther)
81 : , mStorage(aOwner)
82 0 : , mIPCOpen(false)
83 : {
84 0 : }
85 :
86 : void
87 0 : StorageChild::AddIPDLReference()
88 : {
89 0 : NS_ABORT_IF_FALSE(!mIPCOpen, "Attempting to retain multiple IPDL references");
90 0 : mIPCOpen = true;
91 0 : AddRef();
92 0 : }
93 :
94 : void
95 0 : StorageChild::ReleaseIPDLReference()
96 : {
97 0 : NS_ABORT_IF_FALSE(mIPCOpen, "Attempting to release non-existent IPDL reference");
98 0 : mIPCOpen = false;
99 0 : Release();
100 0 : }
101 :
102 : bool
103 0 : StorageChild::CacheStoragePermissions()
104 : {
105 0 : nsDOMStorage* storage = static_cast<nsDOMStorage*>(mStorage.get());
106 0 : return storage->CacheStoragePermissions();
107 : }
108 :
109 : void
110 0 : StorageChild::InitRemote()
111 : {
112 0 : ContentChild* child = ContentChild::GetSingleton();
113 0 : AddIPDLReference();
114 0 : child->SendPStorageConstructor(this, null_t());
115 : SendInit(mUseDB, mCanUseChromePersist, mSessionOnly, mDomain, mScopeDBKey,
116 0 : mQuotaDomainDBKey, mQuotaETLDplus1DomainDBKey, mStorageType);
117 0 : }
118 :
119 : void
120 0 : StorageChild::InitAsSessionStorage(nsIURI* aDomainURI)
121 : {
122 0 : DOMStorageBase::InitAsSessionStorage(aDomainURI);
123 0 : InitRemote();
124 0 : }
125 :
126 : void
127 0 : StorageChild::InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist)
128 : {
129 0 : DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist);
130 0 : InitRemote();
131 0 : }
132 :
133 : void
134 0 : StorageChild::InitAsGlobalStorage(const nsACString& aDomainDemanded)
135 : {
136 0 : DOMStorageBase::InitAsGlobalStorage(aDomainDemanded);
137 0 : InitRemote();
138 0 : }
139 :
140 : nsTArray<nsString>*
141 0 : StorageChild::GetKeys(bool aCallerSecure)
142 : {
143 0 : InfallibleTArray<nsString> remoteKeys;
144 0 : SendGetKeys(aCallerSecure, &remoteKeys);
145 0 : nsTArray<nsString>* keys = new nsTArray<nsString>;
146 0 : *keys = remoteKeys;
147 0 : return keys;
148 : }
149 :
150 : nsresult
151 0 : StorageChild::GetLength(bool aCallerSecure, PRUint32* aLength)
152 : {
153 : nsresult rv;
154 0 : SendGetLength(aCallerSecure, mSessionOnly, aLength, &rv);
155 0 : return rv;
156 : }
157 :
158 : nsresult
159 0 : StorageChild::GetKey(bool aCallerSecure, PRUint32 aIndex, nsAString& aKey)
160 : {
161 : nsresult rv;
162 0 : nsString key;
163 0 : SendGetKey(aCallerSecure, mSessionOnly, aIndex, &key, &rv);
164 0 : if (NS_FAILED(rv))
165 0 : return rv;
166 0 : aKey = key;
167 0 : return NS_OK;
168 : }
169 :
170 : // Unlike other cross-process forwarding methods, GetValue needs to replicate
171 : // the following behaviour of DOMStorageImpl::GetValue:
172 : //
173 : // - if a security error occurs, or the item isn't found, return null without
174 : // propogating the error.
175 : //
176 : // If DOMStorageImpl::GetValue ever changes its behaviour, this should be kept
177 : // in sync.
178 : nsIDOMStorageItem*
179 0 : StorageChild::GetValue(bool aCallerSecure, const nsAString& aKey, nsresult* rv)
180 : {
181 0 : nsresult rv2 = *rv = NS_OK;
182 0 : StorageItem storageItem;
183 0 : SendGetValue(aCallerSecure, mSessionOnly, nsString(aKey), &storageItem, &rv2);
184 0 : if (rv2 == NS_ERROR_DOM_SECURITY_ERR || rv2 == NS_ERROR_DOM_NOT_FOUND_ERR)
185 0 : return nsnull;
186 0 : *rv = rv2;
187 0 : if (NS_FAILED(*rv) || storageItem.type() == StorageItem::Tnull_t)
188 0 : return nsnull;
189 0 : const ItemData& data = storageItem.get_ItemData();
190 0 : nsIDOMStorageItem* item = new nsDOMStorageItem(this, aKey, data.value(),
191 0 : data.secure());
192 0 : return item;
193 : }
194 :
195 : nsresult
196 0 : StorageChild::SetValue(bool aCallerSecure, const nsAString& aKey,
197 : const nsAString& aData, nsAString& aOldData)
198 : {
199 : nsresult rv;
200 0 : nsString oldData;
201 0 : SendSetValue(aCallerSecure, mSessionOnly, nsString(aKey), nsString(aData),
202 0 : &oldData, &rv);
203 0 : if (NS_FAILED(rv))
204 0 : return rv;
205 0 : aOldData = oldData;
206 0 : return NS_OK;
207 : }
208 :
209 : nsresult
210 0 : StorageChild::RemoveValue(bool aCallerSecure, const nsAString& aKey,
211 : nsAString& aOldData)
212 : {
213 : nsresult rv;
214 0 : nsString oldData;
215 0 : SendRemoveValue(aCallerSecure, mSessionOnly, nsString(aKey), &oldData, &rv);
216 0 : if (NS_FAILED(rv))
217 0 : return rv;
218 0 : aOldData = oldData;
219 0 : return NS_OK;
220 : }
221 :
222 : nsresult
223 0 : StorageChild::Clear(bool aCallerSecure, PRInt32* aOldCount)
224 : {
225 : nsresult rv;
226 : PRInt32 oldCount;
227 0 : SendClear(aCallerSecure, mSessionOnly, &oldCount, &rv);
228 0 : if (NS_FAILED(rv))
229 0 : return rv;
230 0 : *aOldCount = oldCount;
231 0 : return NS_OK;
232 : }
233 :
234 : bool
235 0 : StorageChild::CanUseChromePersist()
236 : {
237 0 : return mCanUseChromePersist;
238 : }
239 :
240 : nsresult
241 0 : StorageChild::GetDBValue(const nsAString& aKey, nsAString& aValue,
242 : bool* aSecure)
243 : {
244 : nsresult rv;
245 0 : nsString value;
246 0 : SendGetDBValue(nsString(aKey), &value, aSecure, &rv);
247 0 : aValue = value;
248 0 : return rv;
249 : }
250 :
251 : nsresult
252 0 : StorageChild::SetDBValue(const nsAString& aKey,
253 : const nsAString& aValue,
254 : bool aSecure)
255 : {
256 : nsresult rv;
257 0 : SendSetDBValue(nsString(aKey), nsString(aValue), aSecure, &rv);
258 0 : return rv;
259 : }
260 :
261 : nsresult
262 0 : StorageChild::SetSecure(const nsAString& aKey, bool aSecure)
263 : {
264 : nsresult rv;
265 0 : SendSetSecure(nsString(aKey), aSecure, &rv);
266 0 : return rv;
267 : }
268 :
269 : nsresult
270 0 : StorageChild::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat)
271 : {
272 0 : StorageChild* other = static_cast<StorageChild*>(aThat);
273 0 : ContentChild* child = ContentChild::GetSingleton();
274 0 : StorageClone clone(nsnull, other, aCallerSecure);
275 0 : AddIPDLReference();
276 0 : child->SendPStorageConstructor(this, clone);
277 : SendInit(mUseDB, mCanUseChromePersist, mSessionOnly, mDomain, mScopeDBKey,
278 0 : mQuotaDomainDBKey, mQuotaETLDplus1DomainDBKey, mStorageType);
279 0 : return NS_OK;
280 : }
281 :
282 : }
283 4392 : }
|