Bug 1156493 - e10s: move .cacheKey to nsICacheInfoChannel so child channels can get/set it, r=jduell
authorMichal Novotny <michal.novotny@gmail.com>
Sun, 10 May 2015 02:26:39 +0200
changeset 243188 371cbdcc9562ebef9938430a2ada358280a9273a
parent 243175 77d92f6d76797fbbb80819a13ff4dbd6147aa328
child 243189 eb58a88c452916195554b6338c82a3178eb85d87
push id28724
push userphilringnalda@gmail.com
push dateSun, 10 May 2015 16:10:27 +0000
treeherdermozilla-central@30a4ba533b1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell
bugs1156493
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 1156493 - e10s: move .cacheKey to nsICacheInfoChannel so child channels can get/set it, r=jduell
docshell/base/nsDocShell.cpp
embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
netwerk/base/nsICacheInfoChannel.idl
netwerk/base/nsICachingChannel.idl
netwerk/ipc/NeckoChannelParams.ipdlh
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/protocol/viewsource/nsViewSourceChannel.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -10720,17 +10720,17 @@ nsDocShell::DoURILoad(nsIURI* aURI,
                                   aReferrerURI);
   }
 
   //
   // If this is a HTTP channel, then set up the HTTP specific information
   // (ie. POST data, referrer, ...)
   //
   if (httpChannel) {
-    nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(httpChannel));
+    nsCOMPtr<nsICacheInfoChannel> cacheChannel(do_QueryInterface(httpChannel));
     /* Get the cache Key from SH */
     nsCOMPtr<nsISupports> cacheKey;
     if (mLSHE) {
       mLSHE->GetCacheKey(getter_AddRefs(cacheKey));
     } else if (mOSHE) {  // for reload cases
       mOSHE->GetCacheKey(getter_AddRefs(cacheKey));
     }
 
@@ -11270,17 +11270,17 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsICh
       (aLoadType == LOAD_RELOAD_BYPASS_CACHE ||
        aLoadType == LOAD_RELOAD_BYPASS_PROXY ||
        aLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE ||
        aLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT)) {
     NS_ASSERTION(!updateSHistory,
                  "We shouldn't be updating session history for forced"
                  " reloads!");
 
-    nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(aChannel));
+    nsCOMPtr<nsICacheInfoChannel> cacheChannel(do_QueryInterface(aChannel));
     nsCOMPtr<nsISupports> cacheKey;
     // Get the Cache Key and store it in SH.
     if (cacheChannel) {
       cacheChannel->GetCacheKey(getter_AddRefs(cacheKey));
     }
     // If we already have a loading history entry, store the new cache key
     // in it.  Otherwise, since we're doing a reload and won't be updating
     // our history entry, store the cache key in our current history entry.
@@ -11824,17 +11824,17 @@ nsDocShell::AddToSessionHistory(nsIURI* 
   // Get the post data & referrer
   nsCOMPtr<nsIInputStream> inputStream;
   nsCOMPtr<nsIURI> referrerURI;
   uint32_t referrerPolicy = mozilla::net::RP_Default;
   nsCOMPtr<nsISupports> cacheKey;
   nsCOMPtr<nsISupports> owner = aOwner;
   bool expired = false;
   bool discardLayoutState = false;
-  nsCOMPtr<nsICachingChannel> cacheChannel;
+  nsCOMPtr<nsICacheInfoChannel> cacheChannel;
   if (aChannel) {
     cacheChannel = do_QueryInterface(aChannel);
 
     /* If there is a caching channel, get the Cache Key and store it
      * in SH.
      */
     if (cacheChannel) {
       cacheChannel->GetCacheKey(getter_AddRefs(cacheKey));
--- a/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -14,17 +14,17 @@
 #include "nsComponentManagerUtils.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIStorageStream.h"
 #include "nsISeekableStream.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIEncodedChannel.h"
 #include "nsIUploadChannel.h"
-#include "nsICachingChannel.h"
+#include "nsICacheInfoChannel.h"
 #include "nsIFileChannel.h"
 #include "nsEscape.h"
 #include "nsUnicharUtils.h"
 #include "nsIStringEnumerator.h"
 #include "nsCRT.h"
 #include "nsSupportsArray.h"
 #include "nsContentCID.h"
 #include "nsStreamUtils.h"
@@ -1269,17 +1269,17 @@ nsresult nsWebBrowserPersist::SaveURIInt
                 nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
                 NS_ASSERTION(uploadChannel, "http must support nsIUploadChannel");
                 // Attach the postdata to the http channel
                 uploadChannel->SetUploadStream(aPostData, EmptyCString(), -1);
             }
         }
 
         // Cache key
-        nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(httpChannel));
+        nsCOMPtr<nsICacheInfoChannel> cacheChannel(do_QueryInterface(httpChannel));
         if (cacheChannel && cacheKey)
         {
             cacheChannel->SetCacheKey(cacheKey);
         }
 
         // Headers
         if (aExtraHeaders)
         {
--- a/netwerk/base/nsICacheInfoChannel.idl
+++ b/netwerk/base/nsICacheInfoChannel.idl
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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 "nsISupports.idl"
 
-[scriptable, uuid (299d69b4-ee86-4541-802d-7642671ebf97)]
+[scriptable, uuid (c5f583f0-ae53-4e39-8af9-2c2d0d7af093)]
 interface nsICacheInfoChannel : nsISupports
 {
   /**
    * Get expiration time from cache token. This attribute is equivalent to
    * nsICachingChannel.cacheToken.expirationTime.
    */
   readonly attribute uint32_t cacheTokenExpirationTime;
 
@@ -21,9 +21,28 @@ interface nsICacheInfoChannel : nsISuppo
   attribute ACString cacheTokenCachedCharset;
 
   /**
    * TRUE if this channel's data is being loaded from the cache.  This value
    * is undefined before the channel fires its OnStartRequest notification
    * and after the channel fires its OnStopRequest notification.
    */
   boolean isFromCache();
+
+  /**
+   * Set/get the cache key... uniquely identifies the data in the cache
+   * for this channel.  Holding a reference to this key does NOT prevent
+   * the cached data from being removed.
+   *
+   * A cache key retrieved from a particular instance of nsICachingChannel
+   * could be set on another instance of nsICachingChannel provided the
+   * underlying implementations are compatible and provided the new 
+   * channel instance was created with the same URI.  The implementation of
+   * nsICachingChannel would be expected to use the cache entry identified
+   * by the cache token.  Depending on the value of nsIRequest::loadFlags,
+   * the cache entry may be validated, overwritten, or simply read.
+   *
+   * The cache key may be NULL indicating that the URI of the channel is
+   * sufficient to locate the same cache entry.  Setting a NULL cache key
+   * is likewise valid.
+   */
+  attribute nsISupports cacheKey;
 };
--- a/netwerk/base/nsICachingChannel.idl
+++ b/netwerk/base/nsICachingChannel.idl
@@ -12,17 +12,17 @@ interface nsIFile;
  * to affect its behavior with respect to how it uses the cache service.
  *
  * This interface provides:
  *   1) Support for "stream as file" semantics (for JAR and plugins).
  *   2) Support for "pinning" cached data in the cache (for printing and save-as).
  *   3) Support for uniquely identifying cached data in cases when the URL
  *      is insufficient (e.g., HTTP form submission).
  */
-[scriptable, uuid(3d46b469-7405-416e-ba42-84899963b403)]
+[scriptable, uuid(436b939d-e391-48e5-ba64-ab0e496e3400)]
 interface nsICachingChannel : nsICacheInfoChannel
 {
     /**
      * Set/get the cache token... uniquely identifies the data in the cache.
      * Holding a reference to this token prevents the cached data from being
      * removed.
      * 
      * A cache token retrieved from a particular instance of nsICachingChannel
@@ -41,35 +41,16 @@ interface nsICachingChannel : nsICacheIn
      * is any.
      *
      * @throws
      *      NS_ERROR_NOT_AVAILABLE when there is not offline cache token
      */
     attribute nsISupports offlineCacheToken;
 
     /**
-     * Set/get the cache key... uniquely identifies the data in the cache
-     * for this channel.  Holding a reference to this key does NOT prevent
-     * the cached data from being removed.
-     * 
-     * A cache key retrieved from a particular instance of nsICachingChannel
-     * could be set on another instance of nsICachingChannel provided the
-     * underlying implementations are compatible and provided the new 
-     * channel instance was created with the same URI.  The implementation of
-     * nsICachingChannel would be expected to use the cache entry identified
-     * by the cache token.  Depending on the value of nsIRequest::loadFlags,
-     * the cache entry may be validated, overwritten, or simply read.
-     *
-     * The cache key may be NULL indicating that the URI of the channel is
-     * sufficient to locate the same cache entry.  Setting a NULL cache key
-     * is likewise valid.
-     */
-    attribute nsISupports cacheKey;
-
-    /**
      * Instructs the channel to only store the metadata of the entry, and not
      * the content. When reading an existing entry, this automatically sets
      * LOAD_ONLY_IF_MODIFIED flag.
      * Must be called before asyncOpen().
      */
     attribute boolean cacheOnlyMetadata;
 
     /**************************************************************************
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -25,16 +25,28 @@ namespace net {
 //-----------------------------------------------------------------------------
 
 union OptionalHttpResponseHead
 {
   void_t;
   nsHttpResponseHead;
 };
 
+struct HttpChannelCacheKey
+{
+  uint32_t postId;
+  nsCString key;
+};
+
+union OptionalHttpChannelCacheKey
+{
+  void_t;
+  HttpChannelCacheKey;
+};
+
 struct HttpChannelOpenArgs
 {
   URIParams                   uri;
   // - TODO: bug 571161: unclear if any HTTP channel clients ever
   // set originalURI != uri (about:credits?); also not clear if
   // chrome channel would ever need to know.  Get rid of next arg?
   OptionalURIParams           original;
   OptionalURIParams           doc;
@@ -62,16 +74,17 @@ struct HttpChannelOpenArgs
   bool                        allowAltSvc;
   OptionalFileDescriptorSet   fds;
   PrincipalInfo               requestingPrincipalInfo;
   PrincipalInfo               triggeringPrincipalInfo;
   uint32_t                    securityFlags;
   uint32_t                    contentPolicyType;
   uint32_t                    innerWindowID;
   OptionalHttpResponseHead    synthesizedResponseHead;
+  OptionalHttpChannelCacheKey cacheKey;
 };
 
 struct HttpChannelConnectArgs
 {
   uint32_t channelId;
 };
 
 union HttpChannelCreationArgs
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -318,67 +318,72 @@ class StartRequestEvent : public Channel
                     const bool& useResponseHead,
                     const nsHttpHeaderArray& requestHeaders,
                     const bool& isFromCache,
                     const bool& cacheEntryAvailable,
                     const uint32_t& cacheExpirationTime,
                     const nsCString& cachedCharset,
                     const nsCString& securityInfoSerialization,
                     const NetAddr& selfAddr,
-                    const NetAddr& peerAddr)
+                    const NetAddr& peerAddr,
+                    const HttpChannelCacheKey& cacheKey)
   : mChild(child)
   , mChannelStatus(channelStatus)
   , mResponseHead(responseHead)
   , mRequestHeaders(requestHeaders)
   , mUseResponseHead(useResponseHead)
   , mIsFromCache(isFromCache)
   , mCacheEntryAvailable(cacheEntryAvailable)
   , mCacheExpirationTime(cacheExpirationTime)
   , mCachedCharset(cachedCharset)
   , mSecurityInfoSerialization(securityInfoSerialization)
   , mSelfAddr(selfAddr)
   , mPeerAddr(peerAddr)
+  , mCacheKey(cacheKey)
   {}
 
   void Run()
   {
     LOG(("StartRequestEvent [this=%p]\n", mChild));
     mChild->OnStartRequest(mChannelStatus, mResponseHead, mUseResponseHead,
                            mRequestHeaders, mIsFromCache, mCacheEntryAvailable,
                            mCacheExpirationTime, mCachedCharset,
-                           mSecurityInfoSerialization, mSelfAddr, mPeerAddr);
+                           mSecurityInfoSerialization, mSelfAddr, mPeerAddr,
+                           mCacheKey);
   }
  private:
   HttpChannelChild* mChild;
   nsresult mChannelStatus;
   nsHttpResponseHead mResponseHead;
   nsHttpHeaderArray mRequestHeaders;
   bool mUseResponseHead;
   bool mIsFromCache;
   bool mCacheEntryAvailable;
   uint32_t mCacheExpirationTime;
   nsCString mCachedCharset;
   nsCString mSecurityInfoSerialization;
   NetAddr mSelfAddr;
   NetAddr mPeerAddr;
+  HttpChannelCacheKey mCacheKey;
 };
 
 bool
 HttpChannelChild::RecvOnStartRequest(const nsresult& channelStatus,
                                      const nsHttpResponseHead& responseHead,
                                      const bool& useResponseHead,
                                      const nsHttpHeaderArray& requestHeaders,
                                      const bool& isFromCache,
                                      const bool& cacheEntryAvailable,
                                      const uint32_t& cacheExpirationTime,
                                      const nsCString& cachedCharset,
                                      const nsCString& securityInfoSerialization,
                                      const NetAddr& selfAddr,
                                      const NetAddr& peerAddr,
-                                     const int16_t& redirectCount)
+                                     const int16_t& redirectCount,
+                                     const HttpChannelCacheKey& cacheKey)
 {
   LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this));
   // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
   // stage, as they are set in the listener's OnStartRequest.
   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
     "mFlushedForDiversion should be unset before OnStartRequest!");
   MOZ_RELEASE_ASSERT(!mDivertingToParent,
     "mDivertingToParent should be unset before OnStartRequest!");
@@ -387,38 +392,39 @@ HttpChannelChild::RecvOnStartRequest(con
   mRedirectCount = redirectCount;
 
   if (mEventQ->ShouldEnqueue()) {
     mEventQ->Enqueue(new StartRequestEvent(this, channelStatus, responseHead,
                                            useResponseHead, requestHeaders,
                                            isFromCache, cacheEntryAvailable,
                                            cacheExpirationTime, cachedCharset,
                                            securityInfoSerialization, selfAddr,
-                                           peerAddr));
+                                           peerAddr, cacheKey));
   } else {
     OnStartRequest(channelStatus, responseHead, useResponseHead, requestHeaders,
                    isFromCache, cacheEntryAvailable, cacheExpirationTime,
                    cachedCharset, securityInfoSerialization, selfAddr,
-                   peerAddr);
+                   peerAddr, cacheKey);
   }
   return true;
 }
 
 void
 HttpChannelChild::OnStartRequest(const nsresult& channelStatus,
                                  const nsHttpResponseHead& responseHead,
                                  const bool& useResponseHead,
                                  const nsHttpHeaderArray& requestHeaders,
                                  const bool& isFromCache,
                                  const bool& cacheEntryAvailable,
                                  const uint32_t& cacheExpirationTime,
                                  const nsCString& cachedCharset,
                                  const nsCString& securityInfoSerialization,
                                  const NetAddr& selfAddr,
-                                 const NetAddr& peerAddr)
+                                 const NetAddr& peerAddr,
+                                 const HttpChannelCacheKey& cacheKey)
 {
   LOG(("HttpChannelChild::OnStartRequest [this=%p]\n", this));
 
   // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
   // stage, as they are set in the listener's OnStartRequest.
   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
     "mFlushedForDiversion should be unset before OnStartRequest!");
   MOZ_RELEASE_ASSERT(!mDivertingToParent,
@@ -436,16 +442,20 @@ HttpChannelChild::OnStartRequest(const n
                          getter_AddRefs(mSecurityInfo));
   }
 
   mIsFromCache = isFromCache;
   mCacheEntryAvailable = cacheEntryAvailable;
   mCacheExpirationTime = cacheExpirationTime;
   mCachedCharset = cachedCharset;
 
+  nsRefPtr<nsHttpChannelCacheKey> tmpKey = new nsHttpChannelCacheKey();
+  tmpKey->SetData(cacheKey.postId(), cacheKey.key());
+  CallQueryInterface(tmpKey.get(), getter_AddRefs(mCacheKey));
+
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
   // replace our request headers with what actually got sent in the parent
   mRequestHead.Headers() = requestHeaders;
 
   // Note: this is where we would notify "http-on-examine-response" observers.
   // We have deliberately disabled this for child processes (see bug 806753)
   //
@@ -1642,16 +1652,30 @@ HttpChannelChild::ContinueAsyncOpen()
   openArgs.resumeAt() = mSendResumeAt;
   openArgs.startPos() = mStartPos;
   openArgs.entityID() = mEntityID;
   openArgs.chooseApplicationCache() = mChooseApplicationCache;
   openArgs.appCacheClientID() = appCacheClientId;
   openArgs.allowSpdy() = mAllowSpdy;
   openArgs.allowAltSvc() = mAllowAltSvc;
 
+  if (mCacheKey) {
+    uint32_t postId;
+    nsAutoCString key;
+    nsresult rv = static_cast<nsHttpChannelCacheKey *>(
+      static_cast<nsISupportsPRUint32 *>(mCacheKey.get()))->GetData(&postId,
+                                                                    key);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    openArgs.cacheKey() = HttpChannelCacheKey(postId, key);
+  } else {
+    openArgs.cacheKey() = mozilla::void_t();
+  }
+
   propagateLoadInfo(mLoadInfo, openArgs);
 
   // The socket transport in the chrome process now holds a logical ref to us
   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
   AddIPDLReference();
 
   PBrowserOrId browser = static_cast<ContentChild*>(gNeckoChild->Manager())
                          ->GetBrowserOrId(tabChild);
@@ -1784,16 +1808,31 @@ HttpChannelChild::IsFromCache(bool *valu
 {
   if (!mIsPending)
     return NS_ERROR_NOT_AVAILABLE;
 
   *value = mIsFromCache;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+HttpChannelChild::GetCacheKey(nsISupports **cacheKey)
+{
+  NS_IF_ADDREF(*cacheKey = mCacheKey);
+  return NS_OK;
+}
+NS_IMETHODIMP
+HttpChannelChild::SetCacheKey(nsISupports *cacheKey)
+{
+  ENSURE_CALLED_BEFORE_ASYNC_OPEN();
+
+  mCacheKey = cacheKey;
+  return NS_OK;
+}
+
 //-----------------------------------------------------------------------------
 // HttpChannelChild::nsIResumableChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpChannelChild::ResumeAt(uint64_t startPos, const nsACString& entityID)
 {
   LOG(("HttpChannelChild::ResumeAt [this=%p]\n", this));
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -112,17 +112,18 @@ protected:
                           const nsHttpHeaderArray& requestHeaders,
                           const bool& isFromCache,
                           const bool& cacheEntryAvailable,
                           const uint32_t& cacheExpirationTime,
                           const nsCString& cachedCharset,
                           const nsCString& securityInfoSerialization,
                           const NetAddr& selfAddr,
                           const NetAddr& peerAddr,
-                          const int16_t& redirectCount) override;
+                          const int16_t& redirectCount,
+                          const HttpChannelCacheKey& cacheKey) override;
   bool RecvOnTransportAndData(const nsresult& channelStatus,
                               const nsresult& status,
                               const uint64_t& progress,
                               const uint64_t& progressMax,
                               const nsCString& data,
                               const uint64_t& offset,
                               const uint32_t& count) override;
   bool RecvOnStopRequest(const nsresult& statusCode, const ResourceTimingStruct& timing) override;
@@ -171,16 +172,17 @@ private:
   nsRefPtr<InterceptStreamListener> mInterceptListener;
   nsRefPtr<nsInputStreamPump> mSynthesizedResponsePump;
   int64_t mSynthesizedStreamLength;
 
   bool mIsFromCache;
   bool mCacheEntryAvailable;
   uint32_t     mCacheExpirationTime;
   nsCString    mCachedCharset;
+  nsCOMPtr<nsISupports> mCacheKey;
 
   // If ResumeAt is called before AsyncOpen, we need to send extra data upstream
   bool mSendResumeAt;
 
   bool mIPCOpen;
   bool mKeptAlive;            // IPC kept open, but only for security info
   nsRefPtr<ChannelEventQueue> mEventQ;
 
@@ -203,17 +205,18 @@ private:
                       const bool& useResponseHead,
                       const nsHttpHeaderArray& requestHeaders,
                       const bool& isFromCache,
                       const bool& cacheEntryAvailable,
                       const uint32_t& cacheExpirationTime,
                       const nsCString& cachedCharset,
                       const nsCString& securityInfoSerialization,
                       const NetAddr& selfAddr,
-                      const NetAddr& peerAddr);
+                      const NetAddr& peerAddr,
+                      const HttpChannelCacheKey& cacheKey);
   void OnTransportAndData(const nsresult& channelStatus,
                           const nsresult& status,
                           const uint64_t progress,
                           const uint64_t& progressMax,
                           const nsCString& data,
                           const uint64_t& offset,
                           const uint32_t& count);
   void OnStopRequest(const nsresult& channelStatus, const ResourceTimingStruct& timing);
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -108,17 +108,17 @@ HttpChannelParent::Init(const HttpChanne
                        a.requestMethod(), a.uploadStream(),
                        a.uploadStreamHasHeaders(), a.priority(), a.classOfService(),
                        a.redirectionLimit(), a.allowPipelining(), a.allowSTS(),
                        a.thirdPartyFlags(), a.resumeAt(), a.startPos(),
                        a.entityID(), a.chooseApplicationCache(),
                        a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.fds(),
                        a.requestingPrincipalInfo(), a.triggeringPrincipalInfo(),
                        a.securityFlags(), a.contentPolicyType(), a.innerWindowID(),
-                       a.synthesizedResponseHead());
+                       a.synthesizedResponseHead(), a.cacheKey());
   }
   case HttpChannelCreationArgs::THttpChannelConnectArgs:
   {
     const HttpChannelConnectArgs& cArgs = aArgs.get_HttpChannelConnectArgs();
     return ConnectChannel(cArgs.channelId());
   }
   default:
     NS_NOTREACHED("unknown open type");
@@ -262,17 +262,18 @@ HttpChannelParent::DoAsyncOpen(  const U
                                  const bool&                allowSpdy,
                                  const bool&                allowAltSvc,
                                  const OptionalFileDescriptorSet& aFds,
                                  const ipc::PrincipalInfo&  aRequestingPrincipalInfo,
                                  const ipc::PrincipalInfo&  aTriggeringPrincipalInfo,
                                  const uint32_t&            aSecurityFlags,
                                  const uint32_t&            aContentPolicyType,
                                  const uint32_t&            aInnerWindowID,
-                                 const OptionalHttpResponseHead& aSynthesizedResponseHead)
+                                 const OptionalHttpResponseHead& aSynthesizedResponseHead,
+                                 const OptionalHttpChannelCacheKey& aCacheKey)
 {
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   if (!uri) {
     // URIParams does MOZ_ASSERT if null, but we need to protect opt builds from
     // null deref here.
     return false;
   }
   nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI);
@@ -384,16 +385,25 @@ HttpChannelParent::DoAsyncOpen(  const U
     mChannel->InternalSetUploadStream(stream);
     mChannel->SetUploadStreamHasHeaders(uploadStreamHasHeaders);
   }
 
   if (aSynthesizedResponseHead.type() == OptionalHttpResponseHead::TnsHttpResponseHead) {
     mSynthesizedResponseHead = new nsHttpResponseHead(aSynthesizedResponseHead.get_nsHttpResponseHead());
   }
 
+  if (aCacheKey.type() == OptionalHttpChannelCacheKey::THttpChannelCacheKey) {
+    nsRefPtr<nsHttpChannelCacheKey> cacheKey = new nsHttpChannelCacheKey();
+    cacheKey->SetData(aCacheKey.get_HttpChannelCacheKey().postId(),
+                      aCacheKey.get_HttpChannelCacheKey().key());
+    nsCOMPtr<nsISupports> cacheKeySupp;
+    CallQueryInterface(cacheKey.get(), getter_AddRefs(cacheKeySupp));
+    mChannel->SetCacheKey(cacheKeySupp);
+  }
+
   if (priority != nsISupportsPriority::PRIORITY_NORMAL) {
     mChannel->SetPriority(priority);
   }
   if (classOfService) {
     mChannel->SetClassFlags(classOfService);
   }
   mChannel->SetRedirectionLimit(redirectionLimit);
   mChannel->SetAllowPipelining(allowPipelining);
@@ -799,26 +809,42 @@ HttpChannelParent::OnStartRequest(nsIReq
     mAssociatedContentSecurity = do_QueryInterface(secInfoSupp);
     nsCOMPtr<nsISerializable> secInfoSer = do_QueryInterface(secInfoSupp);
     if (secInfoSer)
       NS_SerializeToString(secInfoSer, secInfoSerialization);
   }
 
   uint16_t redirectCount = 0;
   mChannel->GetRedirectCount(&redirectCount);
+
+  nsCOMPtr<nsISupports> cacheKeySupp;
+  mChannel->GetCacheKey(getter_AddRefs(cacheKeySupp));
+  uint32_t postId = 0;
+  nsAutoCString key;
+  if (cacheKeySupp) {
+    nsresult rv = static_cast<nsHttpChannelCacheKey *>(
+      static_cast<nsISupportsPRUint32 *>(cacheKeySupp.get()))->GetData(&postId,
+                                                                       key);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+  }
+  HttpChannelCacheKey cacheKey = HttpChannelCacheKey(postId, key);
+
   if (mIPCClosed ||
       !SendOnStartRequest(channelStatus,
                           responseHead ? *responseHead : nsHttpResponseHead(),
                           !!responseHead,
                           requestHead->Headers(),
                           isFromCache,
                           mCacheEntry ? true : false,
                           expirationTime, cachedCharset, secInfoSerialization,
                           mChannel->GetSelfAddr(), mChannel->GetPeerAddr(),
-                          redirectCount))
+                          redirectCount,
+                          cacheKey))
   {
     return NS_ERROR_UNEXPECTED;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -116,17 +116,18 @@ protected:
                    const bool&                allowSpdy,
                    const bool&                allowAltSvc,
                    const OptionalFileDescriptorSet& aFds,
                    const ipc::PrincipalInfo&  aRequestingPrincipalInfo,
                    const ipc::PrincipalInfo&  aTriggeringPrincipalInfo,
                    const uint32_t&            aSecurityFlags,
                    const uint32_t&            aContentPolicyType,
                    const uint32_t&            aInnerWindowID,
-                   const OptionalHttpResponseHead& aSynthesizedResponseHead);
+                   const OptionalHttpResponseHead& aSynthesizedResponseHead,
+                   const OptionalHttpChannelCacheKey& aCacheKey);
 
   virtual bool RecvSetPriority(const uint16_t& priority) override;
   virtual bool RecvSetClassOfService(const uint32_t& cos) override;
   virtual bool RecvSetCacheTokenCachedCharset(const nsCString& charset) override;
   virtual bool RecvSuspend() override;
   virtual bool RecvResume() override;
   virtual bool RecvCancel(const nsresult& status) override;
   virtual bool RecvRedirect2Verify(const nsresult& result,
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -3,25 +3,23 @@
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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 protocol PNecko;
 include InputStreamParams;
 include URIParams;
+include NeckoChannelParams;
 
 include protocol PBlob; //FIXME: bug #792908
 
 include "mozilla/net/NeckoMessageUtils.h";
 
-using RequestHeaderTuples from "mozilla/net/PHttpChannelParams.h";
 using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
-using class nsHttpResponseHead from "nsHttpResponseHead.h";
-using struct nsHttpAtom from "nsHttp.h";
 using mozilla::net::NetAddr from "mozilla/net/DNS.h";
 using struct mozilla::net::ResourceTimingStruct from "mozilla/net/TimingStruct.h";
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 protocol PHttpChannel
@@ -88,17 +86,18 @@ child:
                  nsHttpHeaderArray   requestHeaders,
                  bool                isFromCache,
                  bool                cacheEntryAvailable,
                  uint32_t            cacheExpirationTime,
                  nsCString           cachedCharset,
                  nsCString           securityInfoSerialization,
                  NetAddr             selfAddr,
                  NetAddr             peerAddr,
-                 int16_t             redirectCount);
+                 int16_t             redirectCount,
+                 HttpChannelCacheKey cacheKey);
 
   // Combines a single OnDataAvailable and its associated OnProgress &
   // OnStatus calls into one IPDL message
   OnTransportAndData(nsresult  channelStatus,
                      nsresult  transportStatus,
                      uint64_t  progress,
                      uint64_t  progressMax,
                      nsCString data,
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -6032,45 +6032,16 @@ nsHttpChannel::GetOfflineCacheToken(nsIS
 }
 
 NS_IMETHODIMP
 nsHttpChannel::SetOfflineCacheToken(nsISupports *token)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-class nsHttpChannelCacheKey final : public nsISupportsPRUint32,
-                                    public nsISupportsCString
-{
-    NS_DECL_ISUPPORTS
-
-    NS_DECL_NSISUPPORTSPRIMITIVE
-    NS_FORWARD_NSISUPPORTSPRUINT32(mSupportsPRUint32->)
-
-    // Both interfaces declares toString method with the same signature.
-    // Thus we have to delegate only to nsISupportsPRUint32 implementation.
-    NS_IMETHOD GetData(nsACString & aData) override
-    {
-        return mSupportsCString->GetData(aData);
-    }
-    NS_IMETHOD SetData(const nsACString & aData) override
-    {
-        return mSupportsCString->SetData(aData);
-    }
-
-public:
-    nsresult SetData(uint32_t aPostID, const nsACString& aKey);
-
-protected:
-    ~nsHttpChannelCacheKey() {}
-
-    nsCOMPtr<nsISupportsPRUint32> mSupportsPRUint32;
-    nsCOMPtr<nsISupportsCString> mSupportsCString;
-};
-
 NS_IMPL_ADDREF(nsHttpChannelCacheKey)
 NS_IMPL_RELEASE(nsHttpChannelCacheKey)
 NS_INTERFACE_TABLE_HEAD(nsHttpChannelCacheKey)
 NS_INTERFACE_TABLE_BEGIN
 NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(nsHttpChannelCacheKey,
                                    nsISupports, nsISupportsPRUint32)
 NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(nsHttpChannelCacheKey,
                                    nsISupportsPrimitive, nsISupportsPRUint32)
@@ -6106,16 +6077,29 @@ nsresult nsHttpChannelCacheKey::SetData(
     if (NS_FAILED(rv)) return rv;
 
     mSupportsPRUint32->SetData(aPostID);
     if (NS_FAILED(rv)) return rv;
 
     return NS_OK;
 }
 
+nsresult nsHttpChannelCacheKey::GetData(uint32_t *aPostID,
+                                        nsACString& aKey)
+{
+    nsresult rv;
+
+    rv = mSupportsPRUint32->GetData(aPostID);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    return mSupportsCString->GetData(aKey);
+}
+
 NS_IMETHODIMP
 nsHttpChannel::GetCacheKey(nsISupports **key)
 {
     // mayhemer: TODO - do we need this API?
 
     nsresult rv;
     NS_ENSURE_ARG_POINTER(key);
 
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -36,16 +36,50 @@ class Http2PushedStream;
 class HttpChannelSecurityWarningReporter
 {
 public:
   virtual nsresult ReportSecurityMessage(const nsAString& aMessageTag,
                                          const nsAString& aMessageCategory) = 0;
 };
 
 //-----------------------------------------------------------------------------
+// nsHttpChannelCacheKey
+//-----------------------------------------------------------------------------
+
+class nsHttpChannelCacheKey final : public nsISupportsPRUint32,
+                                    public nsISupportsCString
+{
+    NS_DECL_ISUPPORTS
+
+    NS_DECL_NSISUPPORTSPRIMITIVE
+    NS_FORWARD_NSISUPPORTSPRUINT32(mSupportsPRUint32->)
+
+    // Both interfaces declares toString method with the same signature.
+    // Thus we have to delegate only to nsISupportsPRUint32 implementation.
+    NS_IMETHOD GetData(nsACString & aData) override
+    {
+        return mSupportsCString->GetData(aData);
+    }
+    NS_IMETHOD SetData(const nsACString & aData) override
+    {
+        return mSupportsCString->SetData(aData);
+    }
+
+public:
+    nsresult SetData(uint32_t aPostID, const nsACString& aKey);
+    nsresult GetData(uint32_t *aPostID, nsACString& aKey);
+
+protected:
+    ~nsHttpChannelCacheKey() {}
+
+    nsCOMPtr<nsISupportsPRUint32> mSupportsPRUint32;
+    nsCOMPtr<nsISupportsCString> mSupportsCString;
+};
+
+//-----------------------------------------------------------------------------
 // nsHttpChannel
 //-----------------------------------------------------------------------------
 
 // Use to support QI nsIChannel to nsHttpChannel
 #define NS_HTTPCHANNEL_IID                         \
 {                                                  \
   0x301bf95b,                                      \
   0x7bb3,                                          \
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -20,16 +20,17 @@ NS_IMPL_RELEASE(nsViewSourceChannel)
 */
 NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel)
     NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel)
     NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
     NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal)
     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel)
+    NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICacheInfoChannel, mCacheInfoChannel)
     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIApplicationCacheChannel, mApplicationCacheChannel)
     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel)
     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel)
     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
 NS_INTERFACE_MAP_END
 
 nsresult
@@ -75,16 +76,17 @@ nsViewSourceChannel::Init(nsIURI* uri)
     NS_ENSURE_SUCCESS(rv, rv);
 
     mIsSrcdocChannel = false;
 
     mChannel->SetOriginalURI(mOriginalURI);
     mHttpChannel = do_QueryInterface(mChannel);
     mHttpChannelInternal = do_QueryInterface(mChannel);
     mCachingChannel = do_QueryInterface(mChannel);
+    mCacheInfoChannel = do_QueryInterface(mChannel);
     mApplicationCacheChannel = do_QueryInterface(mChannel);
     mUploadChannel = do_QueryInterface(mChannel);
     
     return NS_OK;
 }
 
 nsresult
 nsViewSourceChannel::InitSrcdoc(nsIURI* aURI, const nsAString &aSrcdoc)
@@ -112,16 +114,17 @@ nsViewSourceChannel::InitSrcdoc(nsIURI* 
     NS_ENSURE_SUCCESS(rv, rv);
     mOriginalURI = aURI;
     mIsSrcdocChannel = true;
 
     mChannel->SetOriginalURI(mOriginalURI);
     mHttpChannel = do_QueryInterface(mChannel);
     mHttpChannelInternal = do_QueryInterface(mChannel);
     mCachingChannel = do_QueryInterface(mChannel);
+    mCacheInfoChannel = do_QueryInterface(mChannel);
     mApplicationCacheChannel = do_QueryInterface(mChannel);
     mUploadChannel = do_QueryInterface(mChannel);
     return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIRequest methods:
 
@@ -539,16 +542,17 @@ nsViewSourceChannel::GetIsSrcdocChannel(
 NS_IMETHODIMP
 nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
 {
     NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
     // The channel may have gotten redirected... Time to update our info
     mChannel = do_QueryInterface(aRequest);
     mHttpChannel = do_QueryInterface(aRequest);
     mCachingChannel = do_QueryInterface(aRequest);
+    mCacheInfoChannel = do_QueryInterface(mChannel);
     mUploadChannel = do_QueryInterface(aRequest);
     
     return mListener->OnStartRequest(static_cast<nsIViewSourceChannel*>
                                                 (this),
                                      aContext);
 }
 
 
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.h
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.h
@@ -30,17 +30,17 @@ class nsViewSourceChannel final : public
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIREQUEST
     NS_DECL_NSICHANNEL
     NS_DECL_NSIVIEWSOURCECHANNEL
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSIHTTPCHANNEL
-    NS_FORWARD_SAFE_NSICACHEINFOCHANNEL(mCachingChannel)
+    NS_FORWARD_SAFE_NSICACHEINFOCHANNEL(mCacheInfoChannel)
     NS_FORWARD_SAFE_NSICACHINGCHANNEL(mCachingChannel)
     NS_FORWARD_SAFE_NSIAPPLICATIONCACHECHANNEL(mApplicationCacheChannel)
     NS_FORWARD_SAFE_NSIAPPLICATIONCACHECONTAINER(mApplicationCacheChannel)
     NS_FORWARD_SAFE_NSIUPLOADCHANNEL(mUploadChannel)
     NS_FORWARD_SAFE_NSIHTTPCHANNELINTERNAL(mHttpChannelInternal)
 
     // nsViewSourceChannel methods:
     nsViewSourceChannel()
@@ -53,16 +53,17 @@ public:
 
 protected:
     ~nsViewSourceChannel() {}
 
     nsCOMPtr<nsIChannel>        mChannel;
     nsCOMPtr<nsIHttpChannel>    mHttpChannel;
     nsCOMPtr<nsIHttpChannelInternal>    mHttpChannelInternal;
     nsCOMPtr<nsICachingChannel> mCachingChannel;
+    nsCOMPtr<nsICacheInfoChannel> mCacheInfoChannel;
     nsCOMPtr<nsIApplicationCacheChannel> mApplicationCacheChannel;
     nsCOMPtr<nsIUploadChannel>  mUploadChannel;
     nsCOMPtr<nsIStreamListener> mListener;
     nsCOMPtr<nsIURI>            mOriginalURI;
     nsCString                   mContentType;
     bool                        mIsDocument; // keeps track of the LOAD_DOCUMENT_URI flag
     bool                        mOpened;
     bool                        mIsSrcdocChannel;