1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Mozilla Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2006
20 * the Initial Developer. All Rights Reserved.
23 * Neil Deakin <enndeakin@sympatico.ca>
24 * Johnny Stenback <jst@mozilla.com>
25 * Ehsan Akhgari <ehsan.akhgari@gmail.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #ifndef nsDOMStorage_h___
42 #define nsDOMStorage_h___
45 #include "nsAutoPtr.h"
46 #include "nsIDOMStorageObsolete.h"
47 #include "nsIDOMStorage.h"
48 #include "nsIDOMStorageList.h"
49 #include "nsIDOMStorageItem.h"
50 #include "nsIPermissionManager.h"
51 #include "nsInterfaceHashtable.h"
52 #include "nsVoidArray.h"
54 #include "nsPIDOMStorage.h"
55 #include "nsIDOMToString.h"
56 #include "nsDOMEvent.h"
57 #include "nsIDOMStorageEvent.h"
58 #include "nsIDOMStorageEventObsolete.h"
59 #include "nsIDOMStorageManager.h"
60 #include "nsCycleCollectionParticipant.h"
61 #include "nsIObserver.h"
64 #include "nsDOMStorageDBWrapper.h"
67 #define IS_PERMISSION_ALLOWED(perm) \
68 ((perm) != nsIPermissionManager::UNKNOWN_ACTION && \
69 (perm) != nsIPermissionManager::DENY_ACTION)
73 class nsDOMStorageItem
;
75 class nsDOMStorageEntry
: public nsVoidPtrHashKey
78 nsDOMStorageEntry(KeyTypePointer aStr
);
79 nsDOMStorageEntry(const nsDOMStorageEntry
& aToCopy
);
82 // weak reference so that it can be deleted when no longer used
83 nsDOMStorage
* mStorage
;
86 class nsSessionStorageEntry
: public nsStringHashKey
89 nsSessionStorageEntry(KeyTypePointer aStr
);
90 nsSessionStorageEntry(const nsSessionStorageEntry
& aToCopy
);
91 ~nsSessionStorageEntry();
93 nsRefPtr
<nsDOMStorageItem
> mItem
;
96 class nsDOMStorageManager
: public nsIDOMStorageManager
103 // nsIDOMStorageManager
104 NS_DECL_NSIDOMSTORAGEMANAGER
109 nsDOMStorageManager();
111 void AddToStoragesHash(nsDOMStorage
* aStorage
);
112 void RemoveFromStoragesHash(nsDOMStorage
* aStorage
);
114 nsresult
ClearAllStorages();
116 PRBool
InPrivateBrowsingMode() { return mInPrivateBrowsing
; }
118 static nsresult
Initialize();
119 static nsDOMStorageManager
* GetInstance();
120 static void Shutdown();
122 static nsDOMStorageManager
* gStorageManager
;
126 nsTHashtable
<nsDOMStorageEntry
> mStorages
;
127 PRBool mInPrivateBrowsing
;
130 class nsDOMStorage
: public nsIDOMStorageObsolete
,
131 public nsPIDOMStorage
135 nsDOMStorage(nsDOMStorage
& aThat
);
136 virtual ~nsDOMStorage();
139 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
140 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMStorage
, nsIDOMStorageObsolete
)
142 // nsIDOMStorageObsolete
143 NS_DECL_NSIDOMSTORAGEOBSOLETE
145 // Helpers for implementing nsIDOMStorage
146 nsresult
GetItem(const nsAString
& key
, nsAString
& aData
);
150 virtual nsresult
InitAsSessionStorage(nsIPrincipal
*aPrincipal
, const nsSubstring
&aDocumentURI
);
151 virtual nsresult
InitAsLocalStorage(nsIPrincipal
*aPrincipal
, const nsSubstring
&aDocumentURI
);
152 virtual nsresult
InitAsGlobalStorage(const nsACString
&aDomainDemanded
);
153 virtual already_AddRefed
<nsIDOMStorage
> Clone();
154 virtual already_AddRefed
<nsIDOMStorage
> Fork(const nsSubstring
&aDocumentURI
);
155 virtual PRBool
IsForkOf(nsIDOMStorage
* aThat
);
156 virtual nsTArray
<nsString
> *GetKeys();
157 virtual nsIPrincipal
* Principal();
158 virtual PRBool
CanAccess(nsIPrincipal
*aPrincipal
);
159 virtual nsDOMStorageType
StorageType();
160 virtual void BroadcastChangeNotification(const nsSubstring
&aKey
,
161 const nsSubstring
&aOldValue
,
162 const nsSubstring
&aNewValue
);
164 // If true, the contents of the storage should be stored in the
165 // database, otherwise this storage should act like a session
167 // This call relies on mSessionOnly, and should only be used
168 // after a CacheStoragePermissions() call. See the comments
169 // for mSessionOnly below.
174 PRBool
SessionOnly() {
178 // Some privileged internal pages can use a persistent storage even in
179 // session-only or private-browsing modes.
180 bool CanUseChromePersist();
182 // Check whether storage may be used by the caller, and whether it
183 // is session only. Returns true if storage may be used.
185 CanUseStorage(PRPackedBool
* aSessionOnly
);
187 // Check whether this URI can use chrome persist storage. This kind of
188 // storage can bypass cookies limits, private browsing and uses the offline
191 URICanUseChromePersist(nsIURI
* aURI
);
193 // Check whether storage may be used. Updates mSessionOnly based on
194 // the result of CanUseStorage.
196 CacheStoragePermissions();
198 // retrieve the value and secure state corresponding to a key out of storage.
200 GetDBValue(const nsAString
& aKey
,
204 // set the value corresponding to a key in the storage. If
205 // aSecure is false, then attempts to modify a secure value
206 // throw NS_ERROR_DOM_INVALID_ACCESS_ERR
208 SetDBValue(const nsAString
& aKey
,
209 const nsAString
& aValue
,
212 // set the value corresponding to a key as secure.
214 SetSecure(const nsAString
& aKey
, PRBool aSecure
);
216 // clear all values from the store
220 CloneFrom(nsDOMStorage
* aThat
);
222 nsIDOMStorageItem
* GetNamedItem(const nsAString
& aKey
, nsresult
* aResult
);
224 static nsDOMStorage
* FromSupports(nsISupports
* aSupports
)
226 return static_cast<nsDOMStorage
*>(static_cast<nsIDOMStorageObsolete
*>(aSupports
));
231 friend class nsDOMStorageManager
;
232 friend class nsDOMStorage2
;
234 static nsresult
InitDB();
236 // cache the keys from the database for faster lookup
237 nsresult
CacheKeysFromDB();
239 PRBool
CanAccessSystem(nsIPrincipal
*aPrincipal
);
241 // true if the storage database should be used for values
244 // domain this store is associated with
247 // document URI of the document this storage is bound to
248 nsString mDocumentURI
;
250 // true if the preferences indicates that this storage should be
251 // session only. This member is updated by
252 // CacheStoragePermissions(), using the current principal.
253 // CacheStoragePermissions() must be called at each entry point to
254 // make sure this stays up to date.
255 PRPackedBool mSessionOnly
;
257 // true if this storage was initialized as a localStorage object. localStorage
258 // objects are scoped to scheme/host/port in the database, while globalStorage
259 // objects are scoped just to host. this flag also tells the manager to map
260 // this storage also in mLocalStorages hash table.
261 nsDOMStorageType mStorageType
;
263 // true if items from the database are cached
264 PRPackedBool mItemsCached
;
266 // the key->value item pairs
267 nsTHashtable
<nsSessionStorageEntry
> mItems
;
269 // keys are used for database queries.
270 // see comments of the getters bellow.
271 nsCString mScopeDBKey
;
272 nsCString mQuotaETLDplus1DomainDBKey
;
273 nsCString mQuotaDomainDBKey
;
275 friend class nsIDOMStorage2
;
276 nsPIDOMStorage
* mSecurityChecker
;
277 nsPIDOMStorage
* mEventBroadcaster
;
279 bool mCanUseChromePersist
;
282 // e.g. "moc.rab.oof.:" or "moc.rab.oof.:http:80" depending
283 // on association with a domain (globalStorage) or
284 // an origin (localStorage).
285 nsCString
& GetScopeDBKey() {return mScopeDBKey
;}
287 // e.g. "moc.rab.%" - reversed eTLD+1 subpart of the domain or
288 // reversed offline application allowed domain.
289 nsCString
& GetQuotaDomainDBKey(PRBool aOfflineAllowed
)
291 return aOfflineAllowed
? mQuotaDomainDBKey
: mQuotaETLDplus1DomainDBKey
;
295 static nsDOMStorageDBWrapper
* gStorageDB
;
299 class nsDOMStorage2
: public nsIDOMStorage
,
300 public nsPIDOMStorage
304 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
305 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMStorage2
, nsIDOMStorage
)
307 nsDOMStorage2(nsDOMStorage2
& aThat
);
310 NS_DECL_NSIDOMSTORAGE
313 virtual nsresult
InitAsSessionStorage(nsIPrincipal
*aPrincipal
, const nsSubstring
&aDocumentURI
);
314 virtual nsresult
InitAsLocalStorage(nsIPrincipal
*aPrincipal
, const nsSubstring
&aDocumentURI
);
315 virtual nsresult
InitAsGlobalStorage(const nsACString
&aDomainDemanded
);
316 virtual already_AddRefed
<nsIDOMStorage
> Clone();
317 virtual already_AddRefed
<nsIDOMStorage
> Fork(const nsSubstring
&aDocumentURI
);
318 virtual PRBool
IsForkOf(nsIDOMStorage
* aThat
);
319 virtual nsTArray
<nsString
> *GetKeys();
320 virtual nsIPrincipal
* Principal();
321 virtual PRBool
CanAccess(nsIPrincipal
*aPrincipal
);
322 virtual nsDOMStorageType
StorageType();
323 virtual void BroadcastChangeNotification(const nsSubstring
&aKey
,
324 const nsSubstring
&aOldValue
,
325 const nsSubstring
&aNewValue
);
327 nsresult
InitAsSessionStorageFork(nsIPrincipal
*aPrincipal
,
328 const nsSubstring
&aDocumentURI
,
329 nsIDOMStorageObsolete
* aStorage
);
332 // storages bound to an origin hold the principal to
333 // make security checks against it
334 nsCOMPtr
<nsIPrincipal
> mPrincipal
;
336 // Needed for the storage event, this is address of the document this storage
338 nsString mDocumentURI
;
339 nsRefPtr
<nsDOMStorage
> mStorage
;
342 class nsDOMStorageList
: public nsIDOMStorageList
350 virtual ~nsDOMStorageList() {}
356 NS_DECL_NSIDOMSTORAGELIST
358 nsIDOMStorageObsolete
* GetNamedItem(const nsAString
& aDomain
, nsresult
* aResult
);
361 * Check whether aCurrentDomain has access to aRequestedDomain
364 CanAccessDomain(const nsACString
& aRequestedDomain
,
365 const nsACString
& aCurrentDomain
);
370 * Return the global nsIDOMStorageObsolete for a particular domain.
371 * aNoCurrentDomainCheck may be true to skip the domain comparison;
372 * this is used for chrome code so that it may retrieve data from
375 * @param aRequestedDomain domain to return
376 * @param aCurrentDomain domain of current caller
377 * @param aNoCurrentDomainCheck true to skip domain comparison
379 nsIDOMStorageObsolete
*
380 GetStorageForDomain(const nsACString
& aRequestedDomain
,
381 const nsACString
& aCurrentDomain
,
382 PRBool aNoCurrentDomainCheck
,
386 * Convert the domain into an array of its component parts.
389 ConvertDomainToArray(const nsACString
& aDomain
,
390 nsTArray
<nsCString
>* aArray
);
392 nsInterfaceHashtable
<nsCStringHashKey
, nsIDOMStorageObsolete
> mStorages
;
395 class nsDOMStorageItem
: public nsIDOMStorageItem
,
396 public nsIDOMToString
399 nsDOMStorageItem(nsDOMStorage
* aStorage
,
400 const nsAString
& aKey
,
401 const nsAString
& aValue
,
403 virtual ~nsDOMStorageItem();
406 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
407 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMStorageItem
, nsIDOMStorageItem
)
409 // nsIDOMStorageObsolete
410 NS_DECL_NSIDOMSTORAGEITEM
413 NS_DECL_NSIDOMTOSTRING
420 void SetSecureInternal(PRBool aSecure
)
425 const nsAString
& GetValueInternal()
430 const void SetValueInternal(const nsAString
& aValue
)
442 // true if this value is for secure sites only
451 // If this item came from the db, mStorage points to the storage
452 // object where this item came from.
453 nsRefPtr
<nsDOMStorage
> mStorage
;
456 class nsDOMStorageEvent
: public nsDOMEvent
,
457 public nsIDOMStorageEvent
461 : nsDOMEvent(nsnull
, nsnull
)
465 virtual ~nsDOMStorageEvent()
471 NS_DECL_ISUPPORTS_INHERITED
472 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMStorageEvent
, nsDOMEvent
)
474 NS_DECL_NSIDOMSTORAGEEVENT
475 NS_FORWARD_NSIDOMEVENT(nsDOMEvent::)
482 nsCOMPtr
<nsIDOMStorage
> mStorageArea
;
485 class nsDOMStorageEventObsolete
: public nsDOMEvent
,
486 public nsIDOMStorageEventObsolete
489 nsDOMStorageEventObsolete()
490 : nsDOMEvent(nsnull
, nsnull
)
494 virtual ~nsDOMStorageEventObsolete()
499 NS_DECL_NSIDOMSTORAGEEVENTOBSOLETE
500 NS_FORWARD_NSIDOMEVENT(nsDOMEvent::)
507 NS_NewDOMStorage(nsISupports
* aOuter
, REFNSIID aIID
, void** aResult
);
510 NS_NewDOMStorage2(nsISupports
* aOuter
, REFNSIID aIID
, void** aResult
);
513 NS_NewDOMStorageList(nsIDOMStorageList
** aResult
);
516 GetOfflinePermission(const nsACString
&aDomain
);
519 IsOfflineAllowed(const nsACString
&aDomain
);
521 #endif /* nsDOMStorage_h___ */