Back to index

lightning-sunbird  0.9+nobinonly
nsCookieService.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2003
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Daniel Witte (dwitte@stanford.edu)
00024  *   Michiel van Leeuwen (mvl@exedo.nl)
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #ifndef nsCookieService_h__
00041 #define nsCookieService_h__
00042 
00043 #include "nsICookieService.h"
00044 #include "nsICookieManager.h"
00045 #include "nsICookieManager2.h"
00046 #include "nsIObserver.h"
00047 #include "nsWeakReference.h"
00048 
00049 #include "nsCookie.h"
00050 #include "nsString.h"
00051 #include "nsTHashtable.h"
00052 
00053 #include "nsInt64.h"
00054 
00055 struct nsCookieAttributes;
00056 struct nsListIter;
00057 struct nsEnumerationData;
00058 class nsIPrefBranch;
00059 class nsICookieConsent;
00060 class nsICookiePermission;
00061 class nsIPrefBranch;
00062 class nsIObserverService;
00063 class nsIURI;
00064 class nsIChannel;
00065 class nsITimer;
00066 class nsIFile;
00067 
00068 // hash entry class
00069 class nsCookieEntry : public PLDHashEntryHdr
00070 {
00071   public:
00072     // Hash methods
00073     typedef const char* KeyType;
00074     typedef const char* KeyTypePointer;
00075 
00076     // do nothing with aHost - we require mHead to be set before we're live!
00077     nsCookieEntry(KeyTypePointer aHost)
00078      : mHead(nsnull)
00079     {
00080     }
00081 
00082     nsCookieEntry(const nsCookieEntry& toCopy)
00083     {
00084       // if we end up here, things will break. nsTHashtable shouldn't
00085       // allow this, since we set ALLOW_MEMMOVE to true.
00086       NS_NOTREACHED("nsCookieEntry copy constructor is forbidden!");
00087     }
00088 
00089     ~nsCookieEntry()
00090     {
00091       // walk the linked list, and de-link everything by releasing & nulling.
00092       // this allows the parent host entry to be deleted by the hashtable.
00093       // note: we know mHead cannot be null here - we always set mHead to a
00094       // valid nsCookie (if it were null, the hashtable wouldn't be able to find
00095       // this entry, because the key string is provided by mHead).
00096       nsCookie *current = mHead, *next;
00097       do {
00098         next = current->Next();
00099         NS_RELEASE(current);
00100       } while ((current = next));
00101     }
00102 
00103     KeyType GetKey() const
00104     {
00105       return HostPtr();
00106     }
00107 
00108     KeyTypePointer GetKeyPointer() const
00109     {
00110       return HostPtr();
00111     }
00112 
00113     PRBool KeyEquals(KeyTypePointer aKey) const
00114     {
00115       return !strcmp(HostPtr(), aKey);
00116     }
00117 
00118     static KeyTypePointer KeyToPointer(KeyType aKey)
00119     {
00120       return aKey;
00121     }
00122 
00123     static PLDHashNumber HashKey(KeyTypePointer aKey)
00124     {
00125       // PL_DHashStringKey doesn't use the table parameter, so we can safely
00126       // pass nsnull
00127       return PL_DHashStringKey(nsnull, aKey);
00128     }
00129 
00130     enum { ALLOW_MEMMOVE = PR_TRUE };
00131 
00132     // get methods
00133     inline const nsDependentCString Host() const { return mHead->Host(); }
00134 
00135     // linked list management helper
00136     inline nsCookie*& Head() { return mHead; }
00137 
00138     inline KeyTypePointer HostPtr() const
00139     {
00140       return mHead->Host().get();
00141     }
00142 
00143   private:
00144     nsCookie *mHead;
00145 };
00146 
00147 /******************************************************************************
00148  * nsCookieService:
00149  * class declaration
00150  ******************************************************************************/
00151 
00152 class nsCookieService : public nsICookieService
00153                       , public nsICookieManager2
00154                       , public nsIObserver
00155                       , public nsSupportsWeakReference
00156 {
00157   public:
00158     // nsISupports
00159     NS_DECL_ISUPPORTS
00160     NS_DECL_NSIOBSERVER
00161     NS_DECL_NSICOOKIESERVICE
00162     NS_DECL_NSICOOKIEMANAGER
00163     NS_DECL_NSICOOKIEMANAGER2
00164 
00165     nsCookieService();
00166     virtual ~nsCookieService();
00167     static nsCookieService*       GetSingleton();
00168     nsresult                      Init();
00169 
00170   protected:
00171     void                          PrefChanged(nsIPrefBranch *aPrefBranch);
00172     nsresult                      Read();
00173     nsresult                      Write();
00174     nsresult                      GetCookieInternal(nsIURI *aHostURI, nsIURI *aFirstURI, nsIChannel *aChannel, PRBool aHttpBound, char **aCookie);
00175     nsresult                      SetCookieStringInternal(nsIURI *aHostURI, nsIURI *aFirstURI, nsIPrompt *aPrompt, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, PRBool aFromHttp);
00176     PRBool                        SetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, nsDependentCString &aCookieHeader, nsInt64 aServerTime, PRBool aFromHttp, nsCookieStatus aStatus, nsCookiePolicy aPolicy);
00177     void                          AddInternal(nsCookie *aCookie, nsInt64 aCurrentTime, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp);
00178     void                          RemoveCookieFromList(nsListIter &aIter);
00179     PRBool                        AddCookieToList(nsCookie *aCookie);
00180     static PRBool                 GetTokenValue(nsASingleFragmentCString::const_char_iterator &aIter, nsASingleFragmentCString::const_char_iterator &aEndIter, nsDependentCSubstring &aTokenString, nsDependentCSubstring &aTokenValue, PRBool &aEqualsFound);
00181     static PRBool                 ParseAttributes(nsDependentCString &aCookieHeader, nsCookieAttributes &aCookie);
00182     static PRBool                 IsIPAddress(const nsAFlatCString &aHost);
00183     static PRBool                 IsInDomain(const nsACString &aDomain, const nsACString &aHost, PRBool aIsDomain = PR_TRUE);
00184     static PRBool                 IsForeign(nsIURI *aHostURI, nsIURI *aFirstURI);
00185     nsCookieStatus                CheckPrefs(nsIURI *aHostURI, nsIURI *aFirstURI, nsIChannel *aChannel, const char *aCookieHeader, nsCookiePolicy &aPolicy);
00186     static PRBool                 CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI);
00187     static PRBool                 CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI);
00188     static PRBool                 GetExpiry(nsCookieAttributes &aCookie, nsInt64 aServerTime, nsInt64 aCurrentTime, nsCookieStatus aStatus);
00189     void                          RemoveAllFromMemory();
00190     void                          RemoveExpiredCookies(nsInt64 aCurrentTime);
00191     PRBool                        FindCookie(const nsAFlatCString &aHost, const nsAFlatCString &aName, const nsAFlatCString &aPath, nsListIter &aIter);
00192     void                          FindOldestCookie(nsEnumerationData &aData);
00193     PRUint32                      CountCookiesFromHost(nsCookie *aCookie, nsEnumerationData &aData);
00194     void                          NotifyRejected(nsIURI *aHostURI);
00195     void                          NotifyChanged(nsICookie2 *aCookie, const PRUnichar *aData);
00196 
00197     // Use LazyWrite to save the cookies file on a timer. It will write
00198     // the file only once if repeatedly hammered quickly.
00199     void                          LazyWrite();
00200     static void                   DoLazyWrite(nsITimer *aTimer, void *aClosure);
00201 
00202   protected:
00203     // cached members
00204     nsCOMPtr<nsIFile>             mCookieFile;
00205     nsCOMPtr<nsIObserverService>  mObserverService;
00206     nsCOMPtr<nsICookieConsent>    mP3PService;
00207     nsCOMPtr<nsICookiePermission> mPermissionService;
00208 
00209     // impl members
00210     nsCOMPtr<nsITimer>            mWriteTimer;
00211     nsTHashtable<nsCookieEntry>   mHostTable;
00212     PRUint32                      mCookieCount;
00213     PRPackedBool                  mCookieChanged;
00214     PRPackedBool                  mCookieIconVisible;
00215 
00216     // cached prefs
00217     PRUint8                       mCookiesPermissions;   // BEHAVIOR_{ACCEPT, REJECTFOREIGN, REJECT, P3P}
00218     PRUint16                      mMaxNumberOfCookies;
00219     PRUint16                      mMaxCookiesPerHost;
00220 
00221     // private static member, used to cache a ptr to nsCookieService,
00222     // so we can make nsCookieService a singleton xpcom object.
00223     static nsCookieService        *gCookieService;
00224 
00225     // this callback needs access to member functions
00226     friend PLDHashOperator PR_CALLBACK removeExpiredCallback(nsCookieEntry *aEntry, void *aArg);
00227 };
00228 
00229 #endif // nsCookieService_h__