Bug 1285476 - Let appcache double-cache resources that are cross origin, r=michal
authorHonza Bambas <honzab.moz@firemni.cz>
Wed, 27 Jul 2016 13:08:00 +0200
changeset 308915 6e56fc8ee8682e46efca65bf9647e8c3e764827a
parent 308914 a29eab248d2088da675fc438801b8d8cc1985a6b
child 308916 cf78eed5c0e2ba7844981bf15264cf8dd35ebcec
push id30552
push userkwierso@gmail.com
push dateWed, 10 Aug 2016 23:15:29 +0000
treeherdermozilla-central@65520f4cf4cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1285476
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1285476 - Let appcache double-cache resources that are cross origin, r=michal
netwerk/cache2/AppCacheStorage.cpp
uriloader/prefetch/nsOfflineCacheUpdate.cpp
uriloader/prefetch/nsOfflineCacheUpdate.h
--- a/netwerk/cache2/AppCacheStorage.cpp
+++ b/netwerk/cache2/AppCacheStorage.cpp
@@ -66,16 +66,24 @@ NS_IMETHODIMP AppCacheStorage::AsyncOpen
   nsCOMPtr<nsIURI> noRefURI;
   rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString cacheKey;
   rv = noRefURI->GetAsciiSpec(cacheKey);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // This is the only way how to recognize appcache data by the anonymous
+  // flag.  There is no way to switch to e.g. a different session, because
+  // there is just a single session for an appcache version (identified
+  // by the client id).
+  if (LoadInfo()->IsAnonymous()) {
+    cacheKey = NS_LITERAL_CSTRING("anon&") + cacheKey;
+  }
+
   nsAutoCString scheme;
   rv = noRefURI->GetScheme(scheme);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<_OldCacheLoad> appCacheLoad =
     new _OldCacheLoad(scheme, cacheKey, aCallback, appCache,
                       LoadInfo(), WriteToDisk(), aFlags);
   rv = appCacheLoad->Start();
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -319,23 +319,25 @@ NS_IMPL_ISUPPORTS(nsOfflineCacheUpdateIt
 // nsOfflineCacheUpdateItem <public>
 //-----------------------------------------------------------------------------
 
 nsOfflineCacheUpdateItem::nsOfflineCacheUpdateItem(nsIURI *aURI,
                                                    nsIURI *aReferrerURI,
                                                    nsIPrincipal* aLoadingPrincipal,
                                                    nsIApplicationCache *aApplicationCache,
                                                    nsIApplicationCache *aPreviousApplicationCache,
-                                                   uint32_t type)
+                                                   uint32_t type,
+                                                   uint32_t loadFlags)
     : mURI(aURI)
     , mReferrerURI(aReferrerURI)
     , mLoadingPrincipal(aLoadingPrincipal)
     , mApplicationCache(aApplicationCache)
     , mPreviousApplicationCache(aPreviousApplicationCache)
     , mItemType(type)
+    , mLoadFlags(loadFlags)
     , mChannel(nullptr)
     , mState(LoadStatus::UNINITIALIZED)
     , mBytesRead(0)
 {
 }
 
 nsOfflineCacheUpdateItem::~nsOfflineCacheUpdateItem()
 {
@@ -366,16 +368,18 @@ nsOfflineCacheUpdateItem::OpenChannel(ns
 
     if (mApplicationCache == mPreviousApplicationCache) {
         // Same app cache to read from and to write to is used during
         // an only-update-check procedure.  Here we protect the existing
         // cache from being modified.
         flags |= nsIRequest::INHIBIT_CACHING;
     }
 
+    flags |= mLoadFlags;
+
     rv = NS_NewChannel(getter_AddRefs(mChannel),
                        mURI,
                        mLoadingPrincipal,
                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                        nsIContentPolicy::TYPE_OTHER,
                        nullptr,  // aLoadGroup
                        this,     // aCallbacks
                        flags);
@@ -679,17 +683,17 @@ nsOfflineCacheUpdateItem::GetStatus(uint
 
 nsOfflineManifestItem::nsOfflineManifestItem(nsIURI *aURI,
                                              nsIURI *aReferrerURI,
                                              nsIPrincipal* aLoadingPrincipal,
                                              nsIApplicationCache *aApplicationCache,
                                              nsIApplicationCache *aPreviousApplicationCache)
     : nsOfflineCacheUpdateItem(aURI, aReferrerURI, aLoadingPrincipal,
                                aApplicationCache, aPreviousApplicationCache,
-                               nsIApplicationCache::ITEM_MANIFEST)
+                               nsIApplicationCache::ITEM_MANIFEST, 0)
     , mParserState(PARSE_INIT)
     , mNeedsUpdate(true)
     , mStrictFileOriginPolicy(false)
     , mManifestHashInitialized(false)
 {
     ReadStrictFileOriginPolicyPref();
 }
 
@@ -893,16 +897,22 @@ nsOfflineManifestItem::HandleManifestLin
         uri->GetScheme(scheme);
 
         // Manifest URIs must have the same scheme as the manifest.
         bool match;
         if (NS_FAILED(mURI->SchemeIs(scheme.get(), &match)) || !match)
             break;
 
         mExplicitURIs.AppendObject(uri);
+
+        if (!NS_SecurityCompareURIs(mURI, uri,
+                                    mStrictFileOriginPolicy)) {
+          mAnonymousURIs.AppendObject(uri);
+        }
+
         break;
     }
 
     case PARSE_FALLBACK_ENTRIES: {
         int32_t separator = line.FindChar(' ');
         if (separator == kNotFound) {
             separator = line.FindChar('\t');
             if (separator == kNotFound)
@@ -1424,16 +1434,23 @@ nsOfflineCacheUpdate::HandleManifest(boo
 
     // Add items requested by the manifest.
     const nsCOMArray<nsIURI> &manifestURIs = mManifestItem->GetExplicitURIs();
     for (int32_t i = 0; i < manifestURIs.Count(); i++) {
         rv = AddURI(manifestURIs[i], nsIApplicationCache::ITEM_EXPLICIT);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
+    const nsCOMArray<nsIURI> &anonURIs = mManifestItem->GetAnonymousURIs();
+    for (int32_t i = 0; i < anonURIs.Count(); i++) {
+      rv = AddURI(anonURIs[i], nsIApplicationCache::ITEM_EXPLICIT,
+                  nsIRequest::LOAD_ANONYMOUS);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+
     const nsCOMArray<nsIURI> &fallbackURIs = mManifestItem->GetFallbackURIs();
     for (int32_t i = 0; i < fallbackURIs.Count(); i++) {
         rv = AddURI(fallbackURIs[i], nsIApplicationCache::ITEM_FALLBACK);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // The document that requested the manifest is implicitly included
     // as part of that manifest update.
@@ -2260,17 +2277,17 @@ nsOfflineCacheUpdate::GetIsUpgrade(bool 
     NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
 
     *aIsUpgrade = (mPreviousApplicationCache != nullptr);
 
     return NS_OK;
 }
 
 nsresult
-nsOfflineCacheUpdate::AddURI(nsIURI *aURI, uint32_t aType)
+nsOfflineCacheUpdate::AddURI(nsIURI *aURI, uint32_t aType, uint32_t aLoadFlags)
 {
     NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
 
     if (mState >= STATE_DOWNLOADING)
         return NS_ERROR_NOT_AVAILABLE;
 
     // Resource URIs must have the same scheme as the manifest.
     nsAutoCString scheme;
@@ -2278,30 +2295,32 @@ nsOfflineCacheUpdate::AddURI(nsIURI *aUR
 
     bool match;
     if (NS_FAILED(mManifestURI->SchemeIs(scheme.get(), &match)) || !match)
         return NS_ERROR_FAILURE;
 
     // Don't fetch the same URI twice.
     for (uint32_t i = 0; i < mItems.Length(); i++) {
         bool equals;
-        if (NS_SUCCEEDED(mItems[i]->mURI->Equals(aURI, &equals)) && equals) {
+        if (NS_SUCCEEDED(mItems[i]->mURI->Equals(aURI, &equals)) && equals &&
+            mItems[i]->mLoadFlags == aLoadFlags) {
             // retain both types.
             mItems[i]->mItemType |= aType;
             return NS_OK;
         }
     }
 
     RefPtr<nsOfflineCacheUpdateItem> item =
         new nsOfflineCacheUpdateItem(aURI,
                                      mDocumentURI,
                                      mLoadingPrincipal,
                                      mApplicationCache,
                                      mPreviousApplicationCache,
-                                     aType);
+                                     aType,
+                                     aLoadFlags);
     if (!item) return NS_ERROR_OUT_OF_MEMORY;
 
     mItems.AppendElement(item);
     mAddedItems = true;
 
     return NS_OK;
 }
 
--- a/uriloader/prefetch/nsOfflineCacheUpdate.h
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.h
@@ -49,25 +49,27 @@ public:
     NS_DECL_NSIINTERFACEREQUESTOR
     NS_DECL_NSICHANNELEVENTSINK
 
     nsOfflineCacheUpdateItem(nsIURI *aURI,
                              nsIURI *aReferrerURI,
                              nsIPrincipal* aLoadingPrincipal,
                              nsIApplicationCache *aApplicationCache,
                              nsIApplicationCache *aPreviousApplicationCache,
-                             uint32_t aType);
+                             uint32_t aType,
+                             uint32_t aLoadFlags);
 
     nsCOMPtr<nsIURI>              mURI;
     nsCOMPtr<nsIURI>              mReferrerURI;
     nsCOMPtr<nsIPrincipal>        mLoadingPrincipal;
     nsCOMPtr<nsIApplicationCache> mApplicationCache;
     nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache;
     nsCString                     mCacheKey;
     uint32_t                      mItemType;
+    uint32_t                      mLoadFlags;
 
     nsresult OpenChannel(nsOfflineCacheUpdate *aUpdate);
     nsresult Cancel();
     nsresult GetRequestSucceeded(bool * succeeded);
 
     bool IsInProgress();
     bool IsScheduled();
     bool IsCompleted();
@@ -102,16 +104,17 @@ public:
     nsOfflineManifestItem(nsIURI *aURI,
                           nsIURI *aReferrerURI,
                           nsIPrincipal* aLoadingPrincipal,
                           nsIApplicationCache *aApplicationCache,
                           nsIApplicationCache *aPreviousApplicationCache);
     virtual ~nsOfflineManifestItem();
 
     nsCOMArray<nsIURI> &GetExplicitURIs() { return mExplicitURIs; }
+    nsCOMArray<nsIURI> &GetAnonymousURIs() { return mAnonymousURIs; }
     nsCOMArray<nsIURI> &GetFallbackURIs() { return mFallbackURIs; }
 
     nsTArray<nsCString> &GetOpportunisticNamespaces()
         { return mOpportunisticNamespaces; }
     nsIArray *GetNamespaces()
         { return mNamespaces.get(); }
 
     bool ParseSucceeded()
@@ -159,16 +162,17 @@ private:
         PARSE_BYPASS_ENTRIES,
         PARSE_UNKNOWN_SECTION,
         PARSE_ERROR
     } mParserState;
 
     nsCString mReadBuf;
 
     nsCOMArray<nsIURI> mExplicitURIs;
+    nsCOMArray<nsIURI> mAnonymousURIs;
     nsCOMArray<nsIURI> mFallbackURIs;
 
     // All opportunistic caching namespaces.  Used to decide whether
     // to include previously-opportunistically-cached entries.
     nsTArray<nsCString> mOpportunisticNamespaces;
 
     // Array of nsIApplicationCacheNamespace objects specified by the
     // manifest.
@@ -228,17 +232,17 @@ protected:
     ~nsOfflineCacheUpdate();
 
     friend class nsOfflineCacheUpdateItem;
     void OnByteProgress(uint64_t byteIncrement);
 
 private:
     nsresult InitInternal(nsIURI *aManifestURI, nsIPrincipal* aPrincipal);
     nsresult HandleManifest(bool *aDoUpdate);
-    nsresult AddURI(nsIURI *aURI, uint32_t aItemType);
+    nsresult AddURI(nsIURI *aURI, uint32_t aItemType, uint32_t aLoadFlags = 0);
 
     nsresult ProcessNextURI();
 
     // Adds items from the previous cache witha type matching aType.
     // If namespaceFilter is non-null, only items matching the
     // specified namespaces will be added.
     nsresult AddExistingItems(uint32_t aType,
                               nsTArray<nsCString>* namespaceFilter = nullptr);