Bug 1159378 - Part 2: When storing the service worker downloaded after a failed network compare into the cache, store its security info in the cache as well; r=nsm
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 04 May 2015 10:18:01 -0400
changeset 274265 c532540057ddc282cb886502df2f31940acfc857
parent 274264 47947bd5ebed09603734c6177c0eda96016352a5
child 274266 482c23ebcf041df32b15c8e04e7d71b8b9377d9f
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnsm
bugs1159378
milestone40.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 1159378 - Part 2: When storing the service worker downloaded after a failed network compare into the cache, store its security info in the cache as well; r=nsm
dom/workers/ServiceWorkerScriptCache.cpp
--- a/dom/workers/ServiceWorkerScriptCache.cpp
+++ b/dom/workers/ServiceWorkerScriptCache.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ServiceWorkerScriptCache.h"
 #include "mozilla/dom/CacheBinding.h"
 #include "mozilla/dom/cache/CacheStorage.h"
 #include "mozilla/dom/cache/Cache.h"
 #include "nsIThreadRetargetableRequest.h"
+#include "nsSerializationHelper.h"
 
 #include "nsIPrincipal.h"
 #include "Workers.h"
 
 using mozilla::dom::cache::Cache;
 using mozilla::dom::cache::CacheStorage;
 
 BEGIN_WORKERS_NAMESPACE
@@ -55,21 +56,23 @@ CreateCacheStorage(nsIPrincipal* aPrinci
                                           sandboxGlobalObject,
                                           aPrincipal, aRv);
 }
 
 class CompareManager;
 
 // This class downloads a URL from the network and then it calls
 // NetworkFinished() in the CompareManager.
-class CompareNetwork final : public nsIStreamLoaderObserver
+class CompareNetwork final : public nsIStreamLoaderObserver,
+                             public nsIRequestObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLOADEROBSERVER
+  NS_DECL_NSIREQUESTOBSERVER
 
   explicit CompareNetwork(CompareManager* aManager)
     : mManager(aManager)
   {
     MOZ_ASSERT(aManager);
     AssertIsOnMainThread();
   }
 
@@ -113,17 +116,17 @@ public:
 
     // Don't let serviceworker intercept.
     nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(mChannel);
     if (internalChannel) {
       internalChannel->ForceNoIntercept();
     }
 
     nsCOMPtr<nsIStreamLoader> loader;
-    rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
+    rv = NS_NewStreamLoader(getter_AddRefs(loader), this, this);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     rv = mChannel->AsyncOpen(loader, nullptr);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
@@ -153,17 +156,18 @@ private:
     AssertIsOnMainThread();
   }
 
   nsRefPtr<CompareManager> mManager;
   nsCOMPtr<nsIChannel> mChannel;
   nsString mBuffer;
 };
 
-NS_IMPL_ISUPPORTS(CompareNetwork, nsIStreamLoaderObserver)
+NS_IMPL_ISUPPORTS(CompareNetwork, nsIStreamLoaderObserver,
+                  nsIRequestObserver)
 
 // This class gets a cached Response from the CacheStorage and then it calls
 // CacheFinished() in the CompareManager.
 class CompareCache final : public PromiseNativeHandler
                          , public nsIStreamLoaderObserver
 {
 public:
   NS_DECL_ISUPPORTS
@@ -427,16 +431,22 @@ public:
   CacheStorage*
   CacheStorage_()
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(mCacheStorage);
     return mCacheStorage;
   }
 
+  void
+  SetSecurityInfo(nsISerializable* aSecurityInfo)
+  {
+    NS_SerializeToString(aSecurityInfo, mSecurityInfo);
+  }
+
 private:
   ~CompareManager()
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(!mCC);
     MOZ_ASSERT(!mCN);
   }
 
@@ -520,16 +530,18 @@ private:
       Fail(result.StealNSResult());
       return;
     }
 
     nsRefPtr<InternalResponse> ir =
       new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
     ir->SetBody(body);
 
+    ir->SetSecurityInfo(mSecurityInfo);
+
     nsRefPtr<Response> response = new Response(aCache->GetGlobalObject(), ir);
 
     RequestOrUSVString request;
     request.SetAsUSVString().Rebind(URL().Data(), URL().Length());
 
     // For now we have to wait until the Put Promise is fulfilled before we can
     // continue since Cache does not yet support starting a read that is being
     // written to.
@@ -550,27 +562,61 @@ private:
 
   nsRefPtr<CompareNetwork> mCN;
   nsRefPtr<CompareCache> mCC;
 
   nsString mURL;
   // Only used if the network script has changed and needs to be cached.
   nsString mNewCacheName;
 
+  nsCString mSecurityInfo;
+
   enum {
     WaitingForOpen,
     WaitingForPut
   } mState;
 
   bool mNetworkFinished;
   bool mCacheFinished;
   bool mInCache;
 };
 
 NS_IMETHODIMP
+CompareNetwork::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
+{
+  AssertIsOnMainThread();
+
+#ifdef DEBUG
+  nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
+  MOZ_ASSERT(channel == mChannel);
+#endif
+
+  nsCOMPtr<nsISupports> infoObj;
+  mChannel->GetSecurityInfo(getter_AddRefs(infoObj));
+  if (infoObj) {
+    nsCOMPtr<nsISerializable> serializable = do_QueryInterface(infoObj);
+    if (serializable) {
+      mManager->SetSecurityInfo(serializable);
+    } else {
+      NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!");
+    }
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+CompareNetwork::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
+                              nsresult aStatusCode)
+{
+  // Nothing to do here!
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
                                  nsresult aStatus, uint32_t aLen,
                                  const uint8_t* aString)
 {
   AssertIsOnMainThread();
 
   // If no channel, Abort() has been called.
   if (!mChannel) {