Bug 1395202 - Part 2: Expose CacheEntryId to nsICacheInfoChannel. r=michal, f=junior
authorHo-Pang Hsu <hopang.hsu@gmail.com>
Thu, 12 Oct 2017 02:25:00 -0400
changeset 386160 ed4c6ec74ab5ff38f7f6a35892ed98f9b1b9938a
parent 386159 3a984f1984783282623cca5c7fa90ec7f339b53c
child 386161 4896e4d4e3f52ba3ebb39448f0c5ef17ae8fd9ab
push id32676
push userarchaeopteryx@coole-files.de
push dateFri, 13 Oct 2017 21:38:18 +0000
treeherdermozilla-central@a31334a65a1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1395202
milestone58.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 1395202 - Part 2: Expose CacheEntryId to nsICacheInfoChannel. r=michal, f=junior
netwerk/base/nsICacheInfoChannel.idl
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttpChannel.cpp
--- a/netwerk/base/nsICacheInfoChannel.idl
+++ b/netwerk/base/nsICacheInfoChannel.idl
@@ -34,16 +34,28 @@ interface nsICacheInfoChannel : nsISuppo
   /**
    * 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();
 
   /**
+   * The unique ID of the corresponding nsICacheEntry from which the response is
+   * retrieved. By comparing the returned value, we can judge whether the data
+   * of two distinct nsICacheInfoChannels is from the same nsICacheEntry. This
+   * scenario could be useful when verifying whether the alternative data from
+   * one nsICacheInfochannel matches the main data from another one.
+   *
+   * Note: NS_ERROR_NOT_AVAILABLE is thrown when a nsICacheInfoChannel has no
+   * valid corresponding nsICacheEntry.
+   */
+  uint64_t getCacheEntryId();
+
+  /**
    * 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 nsICacheInfoChannel
    * could be set on another instance of nsICacheInfoChannel provided the
    * underlying implementations are compatible and provided the new 
    * channel instance was created with the same URI.  The implementation of
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -160,16 +160,17 @@ InterceptStreamListener::Cleanup()
 //-----------------------------------------------------------------------------
 
 HttpChannelChild::HttpChannelChild()
   : HttpAsyncAborter<HttpChannelChild>(this)
   , NeckoTargetHolder(nullptr)
   , mSynthesizedStreamLength(0)
   , mIsFromCache(false)
   , mCacheEntryAvailable(false)
+  , mCacheEntryId(0)
   , mAltDataCacheEntryAvailable(false)
   , mCacheFetchCount(0)
   , mCacheExpirationTime(nsICacheEntry::NO_EXPIRATION_TIME)
   , mSendResumeAt(false)
   , mDeletingChannelSent(false)
   , mIPCOpen(false)
   , mKeptAlive(false)
   , mUnknownDecoderInvolved(false)
@@ -408,60 +409,64 @@ class StartRequestEvent : public NeckoTa
  public:
   StartRequestEvent(HttpChannelChild* aChild,
                     const nsresult& aChannelStatus,
                     const nsHttpResponseHead& aResponseHead,
                     const bool& aUseResponseHead,
                     const nsHttpHeaderArray& aRequestHeaders,
                     const bool& aIsFromCache,
                     const bool& aCacheEntryAvailable,
+                    const uint64_t& aCacheEntryId,
                     const int32_t& aCacheFetchCount,
                     const uint32_t& aCacheExpirationTime,
                     const nsCString& aCachedCharset,
                     const nsCString& aSecurityInfoSerialization,
                     const NetAddr& aSelfAddr,
                     const NetAddr& aPeerAddr,
                     const uint32_t& aCacheKey,
                     const nsCString& altDataType,
                     const int64_t& altDataLen)
   : NeckoTargetChannelEvent<HttpChannelChild>(aChild)
   , mChannelStatus(aChannelStatus)
   , mResponseHead(aResponseHead)
   , mRequestHeaders(aRequestHeaders)
   , mUseResponseHead(aUseResponseHead)
   , mIsFromCache(aIsFromCache)
   , mCacheEntryAvailable(aCacheEntryAvailable)
+  , mCacheEntryId(aCacheEntryId)
   , mCacheFetchCount(aCacheFetchCount)
   , mCacheExpirationTime(aCacheExpirationTime)
   , mCachedCharset(aCachedCharset)
   , mSecurityInfoSerialization(aSecurityInfoSerialization)
   , mSelfAddr(aSelfAddr)
   , mPeerAddr(aPeerAddr)
   , mCacheKey(aCacheKey)
   , mAltDataType(altDataType)
   , mAltDataLen(altDataLen)
   {}
 
   void Run()
   {
     LOG(("StartRequestEvent [this=%p]\n", mChild));
     mChild->OnStartRequest(mChannelStatus, mResponseHead, mUseResponseHead,
                            mRequestHeaders, mIsFromCache, mCacheEntryAvailable,
-                           mCacheFetchCount, mCacheExpirationTime, mCachedCharset,
+                           mCacheEntryId, mCacheFetchCount,
+                           mCacheExpirationTime, mCachedCharset,
                            mSecurityInfoSerialization, mSelfAddr, mPeerAddr,
                            mCacheKey, mAltDataType, mAltDataLen);
   }
 
  private:
   nsresult mChannelStatus;
   nsHttpResponseHead mResponseHead;
   nsHttpHeaderArray mRequestHeaders;
   bool mUseResponseHead;
   bool mIsFromCache;
   bool mCacheEntryAvailable;
+  uint64_t mCacheEntryId;
   int32_t mCacheFetchCount;
   uint32_t mCacheExpirationTime;
   nsCString mCachedCharset;
   nsCString mSecurityInfoSerialization;
   NetAddr mSelfAddr;
   NetAddr mPeerAddr;
   uint32_t mCacheKey;
   nsCString mAltDataType;
@@ -470,16 +475,17 @@ class StartRequestEvent : public NeckoTa
 
 mozilla::ipc::IPCResult
 HttpChannelChild::RecvOnStartRequest(const nsresult& channelStatus,
                                      const nsHttpResponseHead& responseHead,
                                      const bool& useResponseHead,
                                      const nsHttpHeaderArray& requestHeaders,
                                      const bool& isFromCache,
                                      const bool& cacheEntryAvailable,
+                                     const uint64_t& cacheEntryId,
                                      const int32_t& cacheFetchCount,
                                      const uint32_t& cacheExpirationTime,
                                      const nsCString& cachedCharset,
                                      const nsCString& securityInfoSerialization,
                                      const NetAddr& selfAddr,
                                      const NetAddr& peerAddr,
                                      const int16_t& redirectCount,
                                      const uint32_t& cacheKey,
@@ -495,17 +501,17 @@ HttpChannelChild::RecvOnStartRequest(con
     "mDivertingToParent should be unset before OnStartRequest!");
 
 
   mRedirectCount = redirectCount;
 
   mEventQ->RunOrEnqueue(new StartRequestEvent(this, channelStatus, responseHead,
                                               useResponseHead, requestHeaders,
                                               isFromCache, cacheEntryAvailable,
-                                              cacheFetchCount,
+                                              cacheEntryId, cacheFetchCount,
                                               cacheExpirationTime, cachedCharset,
                                               securityInfoSerialization,
                                               selfAddr, peerAddr, cacheKey,
                                               altDataType, altDataLen));
 
   {
     // Child's mEventQ is to control the execution order of the IPC messages
     // from both main thread IPDL and PBackground IPDL.
@@ -530,16 +536,17 @@ HttpChannelChild::RecvOnStartRequest(con
 
 void
 HttpChannelChild::OnStartRequest(const nsresult& channelStatus,
                                  const nsHttpResponseHead& responseHead,
                                  const bool& useResponseHead,
                                  const nsHttpHeaderArray& requestHeaders,
                                  const bool& isFromCache,
                                  const bool& cacheEntryAvailable,
+                                 const uint64_t& cacheEntryId,
                                  const int32_t& cacheFetchCount,
                                  const uint32_t& cacheExpirationTime,
                                  const nsCString& cachedCharset,
                                  const nsCString& securityInfoSerialization,
                                  const NetAddr& selfAddr,
                                  const NetAddr& peerAddr,
                                  const uint32_t& cacheKey,
                                  const nsCString& altDataType,
@@ -563,16 +570,17 @@ HttpChannelChild::OnStartRequest(const n
 
   if (!securityInfoSerialization.IsEmpty()) {
     NS_DeserializeObject(securityInfoSerialization,
                          getter_AddRefs(mSecurityInfo));
   }
 
   mIsFromCache = isFromCache;
   mCacheEntryAvailable = cacheEntryAvailable;
+  mCacheEntryId = cacheEntryId;
   mCacheFetchCount = cacheFetchCount;
   mCacheExpirationTime = cacheExpirationTime;
   mCachedCharset = cachedCharset;
   mSelfAddr = selfAddr;
   mPeerAddr = peerAddr;
 
   mAvailableCachedAltDataType = altDataType;
   mAltDataLength = altDataLen;
@@ -2842,16 +2850,30 @@ HttpChannelChild::IsFromCache(bool *valu
   if (!mIsPending)
     return NS_ERROR_NOT_AVAILABLE;
 
   *value = mIsFromCache;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+HttpChannelChild::GetCacheEntryId(uint64_t *aCacheEntryId)
+{
+  bool fromCache = false;
+  if (NS_FAILED(IsFromCache(&fromCache)) ||
+      !fromCache ||
+      !mCacheEntryAvailable) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  *aCacheEntryId = mCacheEntryId;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 HttpChannelChild::GetCacheKey(nsISupports **cacheKey)
 {
   NS_IF_ADDREF(*cacheKey = mCacheKey);
   return NS_OK;
 }
 NS_IMETHODIMP
 HttpChannelChild::SetCacheKey(nsISupports *cacheKey)
 {
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -126,16 +126,17 @@ public:
 
 protected:
   mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& channelStatus,
                                              const nsHttpResponseHead& responseHead,
                                              const bool& useResponseHead,
                                              const nsHttpHeaderArray& requestHeaders,
                                              const bool& isFromCache,
                                              const bool& cacheEntryAvailable,
+                                             const uint64_t& cacheEntryId,
                                              const int32_t& cacheFetchCount,
                                              const uint32_t& cacheExpirationTime,
                                              const nsCString& cachedCharset,
                                              const nsCString& securityInfoSerialization,
                                              const NetAddr& selfAddr,
                                              const NetAddr& peerAddr,
                                              const int16_t& redirectCount,
                                              const uint32_t& cacheKey,
@@ -284,16 +285,17 @@ private:
 
   RequestHeaderTuples mClientSetRequestHeaders;
   RefPtr<nsInputStreamPump> mSynthesizedResponsePump;
   nsCOMPtr<nsIInputStream> mSynthesizedInput;
   int64_t mSynthesizedStreamLength;
 
   bool mIsFromCache;
   bool mCacheEntryAvailable;
+  uint64_t mCacheEntryId;
   bool mAltDataCacheEntryAvailable;
   int32_t      mCacheFetchCount;
   uint32_t     mCacheExpirationTime;
   nsCString    mCachedCharset;
 
   nsCString mProtocolVersion;
 
   // If ResumeAt is called before AsyncOpen, we need to send extra data upstream
@@ -380,16 +382,17 @@ private:
   void AssociateApplicationCache(const nsCString &groupID,
                                  const nsCString &clientID);
   void OnStartRequest(const nsresult& channelStatus,
                       const nsHttpResponseHead& responseHead,
                       const bool& useResponseHead,
                       const nsHttpHeaderArray& requestHeaders,
                       const bool& isFromCache,
                       const bool& cacheEntryAvailable,
+                      const uint64_t& cacheEntryId,
                       const int32_t& cacheFetchCount,
                       const uint32_t& cacheExpirationTime,
                       const nsCString& cachedCharset,
                       const nsCString& securityInfoSerialization,
                       const NetAddr& selfAddr,
                       const NetAddr& peerAddr,
                       const uint32_t& cacheKey,
                       const nsCString& altDataType,
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1438,24 +1438,26 @@ HttpChannelParent::OnStartRequest(nsIReq
     DebugOnly<nsresult> rv =
       static_cast<ContentParent*>(pcp)->AboutToLoadHttpFtpWyciwygDocumentForChild(chan);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
   }
 
   nsHttpResponseHead *responseHead = chan->GetResponseHead();
   nsHttpRequestHead  *requestHead = chan->GetRequestHead();
   bool isFromCache = false;
+  uint64_t cacheEntryId = 0;
   int32_t fetchCount = 0;
   uint32_t expirationTime = nsICacheEntry::NO_EXPIRATION_TIME;
   nsCString cachedCharset;
 
   RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(chan);
 
   if (httpChannelImpl) {
     httpChannelImpl->IsFromCache(&isFromCache);
+    httpChannelImpl->GetCacheEntryId(&cacheEntryId);
     httpChannelImpl->GetCacheTokenFetchCount(&fetchCount);
     httpChannelImpl->GetCacheTokenExpirationTime(&expirationTime);
     httpChannelImpl->GetCacheTokenCachedCharset(cachedCharset);
   }
 
   bool loadedFromApplicationCache = false;
 
   if (httpChannelImpl) {
@@ -1523,16 +1525,17 @@ HttpChannelParent::OnStartRequest(nsIReq
   nsresult rv = NS_OK;
   if (mIPCClosed ||
       !SendOnStartRequest(channelStatus,
                           responseHead ? *responseHead : nsHttpResponseHead(),
                           !!responseHead,
                           requestHead->Headers(),
                           isFromCache,
                           mCacheEntry ? true : false,
+                          cacheEntryId,
                           fetchCount, expirationTime,
                           cachedCharset, secInfoSerialization,
                           chan->GetSelfAddr(), chan->GetPeerAddr(),
                           redirectCount,
                           cacheKeyValue,
                           altDataType,
                           altDataLen))
   {
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -94,16 +94,17 @@ parent:
 
 child:
   async OnStartRequest(nsresult            channelStatus,
                        nsHttpResponseHead  responseHead,
                        bool                useResponseHead,
                        nsHttpHeaderArray   requestHeaders,
                        bool                isFromCache,
                        bool                cacheEntryAvailable,
+                       uint64_t            cacheEntryId,
                        int32_t             cacheFetchCount,
                        uint32_t            cacheExpirationTime,
                        nsCString           cachedCharset,
                        nsCString           securityInfoSerialization,
                        NetAddr             selfAddr,
                        NetAddr             peerAddr,
                        int16_t             redirectCount,
                        uint32_t            cacheKey,
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -7847,16 +7847,28 @@ nsHttpChannel::IsFromCache(bool *value)
     // If we are racing network and cache (or skipping the cache)
     // we just return the first response source.
     *value = mFirstResponseSource == RESPONSE_FROM_CACHE;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsHttpChannel::GetCacheEntryId(uint64_t *aCacheEntryId)
+{
+  bool fromCache = false;
+  if (NS_FAILED(IsFromCache(&fromCache)) || !fromCache || !mCacheEntry ||
+      NS_FAILED(mCacheEntry->GetCacheEntryId(aCacheEntryId))) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsHttpChannel::GetCacheTokenFetchCount(int32_t *_retval)
 {
     NS_ENSURE_ARG_POINTER(_retval);
     nsCOMPtr<nsICacheEntry> cacheEntry = mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
     if (!cacheEntry) {
         return NS_ERROR_NOT_AVAILABLE;
     }