Merge backout.
[mozilla-central.git] / dom / src / storage / nsDOMStorage.h
blob46ab313b8c973604b71bb87bc63880637275aa40
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
13 * License.
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.
22 * Contributor(s):
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___
44 #include "nscore.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"
53 #include "nsTArray.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"
63 #ifdef MOZ_STORAGE
64 #include "nsDOMStorageDBWrapper.h"
65 #endif
67 #define IS_PERMISSION_ALLOWED(perm) \
68 ((perm) != nsIPermissionManager::UNKNOWN_ACTION && \
69 (perm) != nsIPermissionManager::DENY_ACTION)
71 class nsDOMStorage;
72 class nsIDOMStorage;
73 class nsDOMStorageItem;
75 class nsDOMStorageEntry : public nsVoidPtrHashKey
77 public:
78 nsDOMStorageEntry(KeyTypePointer aStr);
79 nsDOMStorageEntry(const nsDOMStorageEntry& aToCopy);
80 ~nsDOMStorageEntry();
82 // weak reference so that it can be deleted when no longer used
83 nsDOMStorage* mStorage;
86 class nsSessionStorageEntry : public nsStringHashKey
88 public:
89 nsSessionStorageEntry(KeyTypePointer aStr);
90 nsSessionStorageEntry(const nsSessionStorageEntry& aToCopy);
91 ~nsSessionStorageEntry();
93 nsRefPtr<nsDOMStorageItem> mItem;
96 class nsDOMStorageManager : public nsIDOMStorageManager
97 , public nsIObserver
99 public:
100 // nsISupports
101 NS_DECL_ISUPPORTS
103 // nsIDOMStorageManager
104 NS_DECL_NSIDOMSTORAGEMANAGER
106 // nsIObserver
107 NS_DECL_NSIOBSERVER
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;
124 protected:
126 nsTHashtable<nsDOMStorageEntry> mStorages;
127 PRBool mInPrivateBrowsing;
130 class nsDOMStorage : public nsIDOMStorageObsolete,
131 public nsPIDOMStorage
133 public:
134 nsDOMStorage();
135 nsDOMStorage(nsDOMStorage& aThat);
136 virtual ~nsDOMStorage();
138 // nsISupports
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);
147 nsresult Clear();
149 // nsPIDOMStorage
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
166 // storage.
167 // This call relies on mSessionOnly, and should only be used
168 // after a CacheStoragePermissions() call. See the comments
169 // for mSessionOnly below.
170 PRBool UseDB() {
171 return mUseDB;
174 PRBool SessionOnly() {
175 return mSessionOnly;
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.
184 static PRBool
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
189 // apps quota.
190 static PRBool
191 URICanUseChromePersist(nsIURI* aURI);
193 // Check whether storage may be used. Updates mSessionOnly based on
194 // the result of CanUseStorage.
195 PRBool
196 CacheStoragePermissions();
198 // retrieve the value and secure state corresponding to a key out of storage.
199 nsresult
200 GetDBValue(const nsAString& aKey,
201 nsAString& aValue,
202 PRBool* aSecure);
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
207 nsresult
208 SetDBValue(const nsAString& aKey,
209 const nsAString& aValue,
210 PRBool aSecure);
212 // set the value corresponding to a key as secure.
213 nsresult
214 SetSecure(const nsAString& aKey, PRBool aSecure);
216 // clear all values from the store
217 void ClearAll();
219 nsresult
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));
229 protected:
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
242 PRPackedBool mUseDB;
244 // domain this store is associated with
245 nsCString mDomain;
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;
281 public:
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;
294 #ifdef MOZ_STORAGE
295 static nsDOMStorageDBWrapper* gStorageDB;
296 #endif
299 class nsDOMStorage2 : public nsIDOMStorage,
300 public nsPIDOMStorage
302 public:
303 // nsISupports
304 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
305 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMStorage2, nsIDOMStorage)
307 nsDOMStorage2(nsDOMStorage2& aThat);
308 nsDOMStorage2();
310 NS_DECL_NSIDOMSTORAGE
312 // nsPIDOMStorage
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);
331 private:
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
337 // is bound to
338 nsString mDocumentURI;
339 nsRefPtr<nsDOMStorage> mStorage;
342 class nsDOMStorageList : public nsIDOMStorageList
344 public:
345 nsDOMStorageList()
347 mStorages.Init();
350 virtual ~nsDOMStorageList() {}
352 // nsISupports
353 NS_DECL_ISUPPORTS
355 // nsIDOMStorageList
356 NS_DECL_NSIDOMSTORAGELIST
358 nsIDOMStorageObsolete* GetNamedItem(const nsAString& aDomain, nsresult* aResult);
361 * Check whether aCurrentDomain has access to aRequestedDomain
363 static PRBool
364 CanAccessDomain(const nsACString& aRequestedDomain,
365 const nsACString& aCurrentDomain);
367 protected:
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
373 * any domain.
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,
383 nsresult* aResult);
386 * Convert the domain into an array of its component parts.
388 static PRBool
389 ConvertDomainToArray(const nsACString& aDomain,
390 nsTArray<nsCString>* aArray);
392 nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorageObsolete> mStorages;
395 class nsDOMStorageItem : public nsIDOMStorageItem,
396 public nsIDOMToString
398 public:
399 nsDOMStorageItem(nsDOMStorage* aStorage,
400 const nsAString& aKey,
401 const nsAString& aValue,
402 PRBool aSecure);
403 virtual ~nsDOMStorageItem();
405 // nsISupports
406 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
407 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMStorageItem, nsIDOMStorageItem)
409 // nsIDOMStorageObsolete
410 NS_DECL_NSIDOMSTORAGEITEM
412 // nsIDOMToString
413 NS_DECL_NSIDOMTOSTRING
415 PRBool IsSecure()
417 return mSecure;
420 void SetSecureInternal(PRBool aSecure)
422 mSecure = aSecure;
425 const nsAString& GetValueInternal()
427 return mValue;
430 const void SetValueInternal(const nsAString& aValue)
432 mValue = aValue;
435 void ClearValue()
437 mValue.Truncate();
440 protected:
442 // true if this value is for secure sites only
443 PRBool mSecure;
445 // key for the item
446 nsString mKey;
448 // value of the item
449 nsString mValue;
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
459 public:
460 nsDOMStorageEvent()
461 : nsDOMEvent(nsnull, nsnull)
465 virtual ~nsDOMStorageEvent()
469 nsresult Init();
471 NS_DECL_ISUPPORTS_INHERITED
472 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMStorageEvent, nsDOMEvent)
474 NS_DECL_NSIDOMSTORAGEEVENT
475 NS_FORWARD_NSIDOMEVENT(nsDOMEvent::)
477 protected:
478 nsString mKey;
479 nsString mOldValue;
480 nsString mNewValue;
481 nsString mUrl;
482 nsCOMPtr<nsIDOMStorage> mStorageArea;
485 class nsDOMStorageEventObsolete : public nsDOMEvent,
486 public nsIDOMStorageEventObsolete
488 public:
489 nsDOMStorageEventObsolete()
490 : nsDOMEvent(nsnull, nsnull)
494 virtual ~nsDOMStorageEventObsolete()
498 NS_DECL_ISUPPORTS
499 NS_DECL_NSIDOMSTORAGEEVENTOBSOLETE
500 NS_FORWARD_NSIDOMEVENT(nsDOMEvent::)
502 protected:
503 nsString mDomain;
506 nsresult
507 NS_NewDOMStorage(nsISupports* aOuter, REFNSIID aIID, void** aResult);
509 nsresult
510 NS_NewDOMStorage2(nsISupports* aOuter, REFNSIID aIID, void** aResult);
512 nsresult
513 NS_NewDOMStorageList(nsIDOMStorageList** aResult);
515 PRUint32
516 GetOfflinePermission(const nsACString &aDomain);
518 PRBool
519 IsOfflineAllowed(const nsACString &aDomain);
521 #endif /* nsDOMStorage_h___ */