uriloader/prefetch/nsOfflineCacheUpdate.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef nsOfflineCacheUpdate_h__
     7 #define nsOfflineCacheUpdate_h__
     9 #include "nsIOfflineCacheUpdate.h"
    11 #include "nsAutoPtr.h"
    12 #include "nsCOMArray.h"
    13 #include "nsCOMPtr.h"
    14 #include "nsICacheService.h"
    15 #include "nsIChannelEventSink.h"
    16 #include "nsIDOMDocument.h"
    17 #include "nsIDOMNode.h"
    18 #include "nsIInterfaceRequestor.h"
    19 #include "nsIMutableArray.h"
    20 #include "nsIObserver.h"
    21 #include "nsIObserverService.h"
    22 #include "nsIApplicationCache.h"
    23 #include "nsIRequestObserver.h"
    24 #include "nsIRunnable.h"
    25 #include "nsIStreamListener.h"
    26 #include "nsIURI.h"
    27 #include "nsIWebProgressListener.h"
    28 #include "nsClassHashtable.h"
    29 #include "nsString.h"
    30 #include "nsTArray.h"
    31 #include "nsWeakReference.h"
    32 #include "nsICryptoHash.h"
    33 #include "mozilla/Attributes.h"
    34 #include "mozilla/WeakPtr.h"
    35 #include "nsTHashtable.h"
    36 #include "nsHashKeys.h"
    38 class nsOfflineCacheUpdate;
    40 class nsICacheEntryDescriptor;
    41 class nsIUTF8StringEnumerator;
    42 class nsILoadContext;
    44 class nsOfflineCacheUpdateItem : public nsIStreamListener
    45                                , public nsIRunnable
    46                                , public nsIInterfaceRequestor
    47                                , public nsIChannelEventSink
    48 {
    49 public:
    50     NS_DECL_ISUPPORTS
    51     NS_DECL_NSIREQUESTOBSERVER
    52     NS_DECL_NSISTREAMLISTENER
    53     NS_DECL_NSIRUNNABLE
    54     NS_DECL_NSIINTERFACEREQUESTOR
    55     NS_DECL_NSICHANNELEVENTSINK
    57     nsOfflineCacheUpdateItem(nsIURI *aURI,
    58                              nsIURI *aReferrerURI,
    59                              nsIApplicationCache *aApplicationCache,
    60                              nsIApplicationCache *aPreviousApplicationCache,
    61                              uint32_t aType);
    62     virtual ~nsOfflineCacheUpdateItem();
    64     nsCOMPtr<nsIURI>           mURI;
    65     nsCOMPtr<nsIURI>           mReferrerURI;
    66     nsCOMPtr<nsIApplicationCache> mApplicationCache;
    67     nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache;
    68     nsCString                  mCacheKey;
    69     uint32_t                   mItemType;
    71     nsresult OpenChannel(nsOfflineCacheUpdate *aUpdate);
    72     nsresult Cancel();
    73     nsresult GetRequestSucceeded(bool * succeeded);
    75     bool IsInProgress();
    76     bool IsScheduled();
    77     bool IsCompleted();
    79     nsresult GetStatus(uint16_t *aStatus);
    81 private:
    82     enum LoadStatus MOZ_ENUM_TYPE(uint16_t) {
    83       UNINITIALIZED = 0U,
    84       REQUESTED = 1U,
    85       RECEIVING = 2U,
    86       LOADED = 3U
    87     };
    89     nsRefPtr<nsOfflineCacheUpdate> mUpdate;
    90     nsCOMPtr<nsIChannel>           mChannel;
    91     uint16_t                       mState;
    93 protected:
    94     int64_t                        mBytesRead;
    95 };
    98 class nsOfflineManifestItem : public nsOfflineCacheUpdateItem
    99 {
   100 public:
   101     NS_DECL_NSISTREAMLISTENER
   102     NS_DECL_NSIREQUESTOBSERVER
   104     nsOfflineManifestItem(nsIURI *aURI,
   105                           nsIURI *aReferrerURI,
   106                           nsIApplicationCache *aApplicationCache,
   107                           nsIApplicationCache *aPreviousApplicationCache);
   108     virtual ~nsOfflineManifestItem();
   110     nsCOMArray<nsIURI> &GetExplicitURIs() { return mExplicitURIs; }
   111     nsCOMArray<nsIURI> &GetFallbackURIs() { return mFallbackURIs; }
   113     nsTArray<nsCString> &GetOpportunisticNamespaces()
   114         { return mOpportunisticNamespaces; }
   115     nsIArray *GetNamespaces()
   116         { return mNamespaces.get(); }
   118     bool ParseSucceeded()
   119         { return (mParserState != PARSE_INIT && mParserState != PARSE_ERROR); }
   120     bool NeedsUpdate() { return mParserState != PARSE_INIT && mNeedsUpdate; }
   122     void GetManifestHash(nsCString &aManifestHash)
   123         { aManifestHash = mManifestHashValue; }
   125 private:
   126     static NS_METHOD ReadManifest(nsIInputStream *aInputStream,
   127                                   void *aClosure,
   128                                   const char *aFromSegment,
   129                                   uint32_t aOffset,
   130                                   uint32_t aCount,
   131                                   uint32_t *aBytesConsumed);
   133     nsresult AddNamespace(uint32_t namespaceType,
   134                           const nsCString &namespaceSpec,
   135                           const nsCString &data);
   137     nsresult HandleManifestLine(const nsCString::const_iterator &aBegin,
   138                                 const nsCString::const_iterator &aEnd);
   140     /**
   141      * Saves "offline-manifest-hash" meta data from the old offline cache
   142      * token to mOldManifestHashValue member to be compared on
   143      * successfull load.
   144      */
   145     nsresult GetOldManifestContentHash(nsIRequest *aRequest);
   146     /**
   147      * This method setups the mNeedsUpdate to false when hash value
   148      * of the just downloaded manifest file is the same as stored in cache's 
   149      * "offline-manifest-hash" meta data. Otherwise stores the new value
   150      * to this meta data.
   151      */
   152     nsresult CheckNewManifestContentHash(nsIRequest *aRequest);
   154     void ReadStrictFileOriginPolicyPref();
   156     enum {
   157         PARSE_INIT,
   158         PARSE_CACHE_ENTRIES,
   159         PARSE_FALLBACK_ENTRIES,
   160         PARSE_BYPASS_ENTRIES,
   161         PARSE_UNKNOWN_SECTION,
   162         PARSE_ERROR
   163     } mParserState;
   165     nsCString mReadBuf;
   167     nsCOMArray<nsIURI> mExplicitURIs;
   168     nsCOMArray<nsIURI> mFallbackURIs;
   170     // All opportunistic caching namespaces.  Used to decide whether
   171     // to include previously-opportunistically-cached entries.
   172     nsTArray<nsCString> mOpportunisticNamespaces;
   174     // Array of nsIApplicationCacheNamespace objects specified by the
   175     // manifest.
   176     nsCOMPtr<nsIMutableArray> mNamespaces;
   178     bool mNeedsUpdate;
   179     bool mStrictFileOriginPolicy;
   181     // manifest hash data
   182     nsCOMPtr<nsICryptoHash> mManifestHash;
   183     bool mManifestHashInitialized;
   184     nsCString mManifestHashValue;
   185     nsCString mOldManifestHashValue;
   186 };
   188 class nsOfflineCacheUpdateOwner
   189   : public mozilla::SupportsWeakPtr<nsOfflineCacheUpdateOwner>
   190 {
   191 public:
   192     MOZ_DECLARE_REFCOUNTED_TYPENAME(nsOfflineCacheUpdateOwner)
   193     virtual ~nsOfflineCacheUpdateOwner() {}
   194     virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate) = 0;
   195 };
   197 class nsOfflineCacheUpdate MOZ_FINAL : public nsIOfflineCacheUpdate
   198                                      , public nsIOfflineCacheUpdateObserver
   199                                      , public nsIRunnable
   200                                      , public nsOfflineCacheUpdateOwner
   201 {
   202 public:
   203     MOZ_DECLARE_REFCOUNTED_TYPENAME(nsOfflineCacheUpdate)
   204     NS_DECL_ISUPPORTS
   205     NS_DECL_NSIOFFLINECACHEUPDATE
   206     NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
   207     NS_DECL_NSIRUNNABLE
   209     nsOfflineCacheUpdate();
   210     ~nsOfflineCacheUpdate();
   212     static nsresult GetCacheKey(nsIURI *aURI, nsACString &aKey);
   214     nsresult Init();
   216     nsresult Begin();
   218     void LoadCompleted(nsOfflineCacheUpdateItem *aItem);
   219     void ManifestCheckCompleted(nsresult aStatus,
   220                                 const nsCString &aManifestHash);
   221     void StickDocument(nsIURI *aDocumentURI);
   223     void SetOwner(nsOfflineCacheUpdateOwner *aOwner);
   225     bool IsForGroupID(const nsCSubstring &groupID);
   227     virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);
   229 protected:
   230     friend class nsOfflineCacheUpdateItem;
   231     void OnByteProgress(uint64_t byteIncrement);
   233 private:
   234     nsresult InitInternal(nsIURI *aManifestURI);
   235     nsresult HandleManifest(bool *aDoUpdate);
   236     nsresult AddURI(nsIURI *aURI, uint32_t aItemType);
   238     nsresult ProcessNextURI();
   240     // Adds items from the previous cache witha type matching aType.
   241     // If namespaceFilter is non-null, only items matching the
   242     // specified namespaces will be added.
   243     nsresult AddExistingItems(uint32_t aType,
   244                               nsTArray<nsCString>* namespaceFilter = nullptr);
   245     nsresult ScheduleImplicit();
   246     void AssociateDocuments(nsIApplicationCache* cache);
   247     bool CheckUpdateAvailability();
   248     void NotifyUpdateAvailability(bool updateAvailable);
   250     void GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers);
   251     void NotifyState(uint32_t state);
   252     nsresult Finish();
   253     nsresult FinishNoNotify();
   255     void AsyncFinishWithError();
   257     // Find one non-pinned cache group and evict it.
   258     nsresult EvictOneNonPinned();
   260     enum {
   261         STATE_UNINITIALIZED,
   262         STATE_INITIALIZED,
   263         STATE_CHECKING,
   264         STATE_DOWNLOADING,
   265         STATE_CANCELLED,
   266         STATE_FINISHED
   267     } mState;
   269     mozilla::WeakPtr<nsOfflineCacheUpdateOwner> mOwner;
   271     bool mAddedItems;
   272     bool mPartialUpdate;
   273     bool mOnlyCheckUpdate;
   274     bool mSucceeded;
   275     bool mObsolete;
   277     nsCString mUpdateDomain;
   278     nsCString mGroupID;
   279     nsCOMPtr<nsIURI> mManifestURI;
   280     nsCOMPtr<nsIURI> mDocumentURI;
   281     nsCOMPtr<nsIFile> mCustomProfileDir;
   283     uint32_t mAppID;
   284     bool mInBrowser;
   286     nsCOMPtr<nsIObserver> mUpdateAvailableObserver;
   288     nsCOMPtr<nsIApplicationCache> mApplicationCache;
   289     nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache;
   291     nsCOMPtr<nsIObserverService> mObserverService;
   293     nsRefPtr<nsOfflineManifestItem> mManifestItem;
   295     /* Items being updated */
   296     uint32_t mItemsInProgress;
   297     nsTArray<nsRefPtr<nsOfflineCacheUpdateItem> > mItems;
   299     /* Clients watching this update for changes */
   300     nsCOMArray<nsIWeakReference> mWeakObservers;
   301     nsCOMArray<nsIOfflineCacheUpdateObserver> mObservers;
   303     /* Documents that requested this update */
   304     nsCOMArray<nsIURI> mDocumentURIs;
   306     /* Reschedule count.  When an update is rescheduled due to
   307      * mismatched manifests, the reschedule count will be increased. */
   308     uint32_t mRescheduleCount;
   310     /* Whena an entry for a pinned app is retried, retries count is
   311      * increaded. */
   312     uint32_t mPinnedEntryRetriesCount;
   314     nsRefPtr<nsOfflineCacheUpdate> mImplicitUpdate;
   316     bool                           mPinned;
   318     uint64_t                       mByteProgress;
   319 };
   321 class nsOfflineCacheUpdateService MOZ_FINAL : public nsIOfflineCacheUpdateService
   322                                             , public nsIObserver
   323                                             , public nsOfflineCacheUpdateOwner
   324                                             , public nsSupportsWeakReference
   325 {
   326 public:
   327     NS_DECL_ISUPPORTS
   328     NS_DECL_NSIOFFLINECACHEUPDATESERVICE
   329     NS_DECL_NSIOBSERVER
   331     nsOfflineCacheUpdateService();
   332     ~nsOfflineCacheUpdateService();
   334     nsresult Init();
   336     nsresult ScheduleUpdate(nsOfflineCacheUpdate *aUpdate);
   337     nsresult FindUpdate(nsIURI *aManifestURI,
   338                         uint32_t aAppID,
   339                         bool aInBrowser,
   340                         nsOfflineCacheUpdate **aUpdate);
   342     nsresult Schedule(nsIURI *aManifestURI,
   343                       nsIURI *aDocumentURI,
   344                       nsIDOMDocument *aDocument,
   345                       nsIDOMWindow* aWindow,
   346                       nsIFile* aCustomProfileDir,
   347                       uint32_t aAppID,
   348                       bool aInBrowser,
   349                       nsIOfflineCacheUpdate **aUpdate);
   351     virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);
   353     /**
   354      * Returns the singleton nsOfflineCacheUpdateService without an addref, or
   355      * nullptr if the service couldn't be created.
   356      */
   357     static nsOfflineCacheUpdateService *EnsureService();
   359     /** Addrefs and returns the singleton nsOfflineCacheUpdateService. */
   360     static nsOfflineCacheUpdateService *GetInstance();
   362     static nsresult OfflineAppPinnedForURI(nsIURI *aDocumentURI,
   363                                            nsIPrefBranch *aPrefBranch,
   364                                            bool *aPinned);
   366     static nsTHashtable<nsCStringHashKey>* AllowedDomains();
   368 private:
   369     nsresult ProcessNextUpdate();
   371     nsTArray<nsRefPtr<nsOfflineCacheUpdate> > mUpdates;
   372     static nsTHashtable<nsCStringHashKey>* mAllowedDomains;
   374     bool mDisabled;
   375     bool mUpdateRunning;
   376     bool mLowFreeSpace;
   377 };
   379 #endif

mercurial