Bug 1231565 - (Part 3) Make alt-data responses report the correct content length r=michal
authorValentin Gosu <valentin.gosu@gmail.com>
Tue, 27 Sep 2016 10:26:00 +0200
changeset 315429 d3a0e25cebb306ee52992d15cffbc47248309f91
parent 315428 f6c8123885905804ac06f6dc01d0f7f969f0ceb8
child 315430 cde7a9badcab194e25adf5fc48a991f6fa41fb87
push id30750
push usercbook@mozilla.com
push dateWed, 28 Sep 2016 13:57:20 +0000
treeherdermozilla-central@b1d60f2f68c7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1231565
milestone52.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 1231565 - (Part 3) Make alt-data responses report the correct content length r=michal MozReview-Commit-ID: DvQP7NB4SqW
netwerk/cache2/CacheEntry.cpp
netwerk/cache2/CacheFile.cpp
netwerk/cache2/CacheFile.h
netwerk/cache2/OldWrappers.cpp
netwerk/cache2/OldWrappers.h
netwerk/cache2/nsICacheEntry.idl
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/test/unit/test_alt-data_simple.js
--- a/netwerk/cache2/CacheEntry.cpp
+++ b/netwerk/cache2/CacheEntry.cpp
@@ -1501,16 +1501,27 @@ NS_IMETHODIMP CacheEntry::GetDataSize(in
     LOG(("  write in progress (stream active)"));
     return NS_ERROR_IN_PROGRESS;
   }
 
   LOG(("  size=%lld", *aDataSize));
   return NS_OK;
 }
 
+
+NS_IMETHODIMP CacheEntry::GetAltDataSize(int64_t *aDataSize)
+{
+  LOG(("CacheEntry::GetAltDataSize [this=%p]", this));
+  if (NS_FAILED(mFileStatus)) {
+    return mFileStatus;
+  }
+  return mFile->GetAltDataSize(aDataSize);
+}
+
+
 NS_IMETHODIMP CacheEntry::MarkValid()
 {
   // NOT IMPLEMENTED ACTUALLY
   return NS_OK;
 }
 
 NS_IMETHODIMP CacheEntry::MaybeMarkValid()
 {
--- a/netwerk/cache2/CacheFile.cpp
+++ b/netwerk/cache2/CacheFile.cpp
@@ -2095,16 +2095,32 @@ CacheFile::DataSize(int64_t* aSize)
     *aSize = mDataSize;
   } else {
     *aSize = mAltDataOffset;
   }
 
   return true;
 }
 
+nsresult
+CacheFile::GetAltDataSize(int64_t *aSize)
+{
+  CacheFileAutoLock lock(this);
+  if (mOutput) {
+    return NS_ERROR_IN_PROGRESS;
+  }
+
+  if (mAltDataOffset == -1) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  *aSize = mDataSize - mAltDataOffset;
+  return NS_OK;
+}
+
 bool
 CacheFile::IsDoomed()
 {
   CacheFileAutoLock lock(this);
 
   if (!mHandle)
     return false;
 
--- a/netwerk/cache2/CacheFile.h
+++ b/netwerk/cache2/CacheFile.h
@@ -86,16 +86,18 @@ public:
   NS_IMETHOD OpenAlternativeOutputStream(CacheOutputCloseListener *aCloseListener,
                                          const char *aAltDataType, nsIOutputStream **_retval);
   NS_IMETHOD SetMemoryOnly();
   NS_IMETHOD Doom(CacheFileListener *aCallback);
 
   void Kill() { mKill = true; }
   nsresult   ThrowMemoryCachedData();
 
+  nsresult GetAltDataSize(int64_t *aSize);
+
   // metadata forwarders
   nsresult GetElement(const char *aKey, char **_retval);
   nsresult SetElement(const char *aKey, const char *aValue);
   nsresult VisitMetaData(nsICacheEntryMetaDataVisitor *aVisitor);
   nsresult ElementsSize(uint32_t *_retval);
   nsresult SetExpirationTime(uint32_t aExpirationTime);
   nsresult GetExpirationTime(uint32_t *_retval);
   nsresult SetFrecency(uint32_t aFrecency);
--- a/netwerk/cache2/OldWrappers.cpp
+++ b/netwerk/cache2/OldWrappers.cpp
@@ -394,16 +394,21 @@ NS_IMETHODIMP _OldCacheEntryWrapper::Get
   nsresult rv = GetDataSize(&size);
   if (NS_FAILED(rv))
     return rv;
 
   *aSize = size;
   return NS_OK;
 }
 
+NS_IMETHODIMP _OldCacheEntryWrapper::GetAltDataSize(int64_t *aSize)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 NS_IMETHODIMP _OldCacheEntryWrapper::GetPersistent(bool *aPersistToDisk)
 {
   if (!mOldDesc) {
     return NS_ERROR_NULL_POINTER;
   }
 
   nsresult rv;
 
--- a/netwerk/cache2/OldWrappers.h
+++ b/netwerk/cache2/OldWrappers.h
@@ -134,16 +134,17 @@ public:
   NS_IMETHOD AsyncDoom(nsICacheEntryDoomCallback* listener) override;
   NS_IMETHOD GetPersistent(bool *aPersistToDisk) override;
   NS_IMETHOD GetIsForcedValid(bool *aIsForcedValid) override;
   NS_IMETHOD ForceValidFor(uint32_t aSecondsToTheFuture) override;
   NS_IMETHOD SetValid() override { return NS_OK; }
   NS_IMETHOD MetaDataReady() override { return NS_OK; }
   NS_IMETHOD Recreate(bool, nsICacheEntry**) override;
   NS_IMETHOD GetDataSize(int64_t *size) override;
+  NS_IMETHOD GetAltDataSize(int64_t *size) override;
   NS_IMETHOD OpenInputStream(int64_t offset, nsIInputStream * *_retval) override;
   NS_IMETHOD OpenOutputStream(int64_t offset, nsIOutputStream * *_retval) override;
   NS_IMETHOD MaybeMarkValid() override;
   NS_IMETHOD HasWriteAccess(bool aWriteOnly, bool *aWriteAccess) override;
   NS_IMETHOD VisitMetaData(nsICacheEntryMetaDataVisitor*) override;
 
   explicit _OldCacheEntryWrapper(nsICacheEntryDescriptor* desc);
   explicit _OldCacheEntryWrapper(nsICacheEntryInfo* info);
--- a/netwerk/cache2/nsICacheEntry.idl
+++ b/netwerk/cache2/nsICacheEntry.idl
@@ -192,16 +192,25 @@ interface nsICacheEntry : nsISupports
   /**
    * Returns the length of data this entry holds.
    * @throws
    *    NS_ERROR_IN_PROGRESS when the write is still in progress.
    */
   readonly attribute long long dataSize;
 
   /**
+  * Returns the length of data this entry holds.
+  * @throws
+  *    - NS_ERROR_IN_PROGRESS when a write is still in progress (either real
+                              content or alt data).
+  *    - NS_ERROR_NOT_AVAILABLE if alt data does not exist.
+  */
+  readonly attribute long long altDataSize;
+
+  /**
    * Opens and returns an output stream that a consumer may use to save an
    * alternate representation of the data.
    * @throws
    *    - NS_ERROR_NOT_AVAILABLE if the real data hasn't been written.
    *    - NS_ERROR_IN_PROGRESS when the writing regular content or alt-data to
    *      the cache entry is still in progress.
    *
    * If there is alt-data already saved, it will be overwritten.
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -4500,19 +4500,23 @@ nsHttpChannel::OpenCacheInputStream(nsIC
     // If an alternate representation was requested, try to open the alt
     // input stream.
     if (!mPreferredCachedAltDataType.IsEmpty()) {
         rv = cacheEntry->OpenAlternativeInputStream(mPreferredCachedAltDataType,
                                                     getter_AddRefs(stream));
         if (NS_SUCCEEDED(rv)) {
             // We have succeeded.
             mAvailableCachedAltDataType = mPreferredCachedAltDataType;
-            // The alternative data may have a different length than the original
-            // content, so we clear the Content-Length header
+            // Clear the header.
             mCachedResponseHead->SetContentLength(-1);
+            // Set the correct data size on the channel.
+            int64_t altDataSize;
+            if (NS_SUCCEEDED(cacheEntry->GetAltDataSize(&altDataSize))) {
+                mCachedResponseHead->SetContentLength(altDataSize);
+            }
         }
     }
 
     if (!stream) {
         rv = cacheEntry->OpenInputStream(0, getter_AddRefs(stream));
     }
 
     if (NS_FAILED(rv)) {
--- a/netwerk/test/unit/test_alt-data_simple.js
+++ b/netwerk/test/unit/test_alt-data_simple.js
@@ -56,17 +56,17 @@ function run_test()
   httpServer.registerPathHandler("/content", contentHandler);
   httpServer.start(-1);
 
   var chan = make_channel(URL);
 
   var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
   cc.preferAlternativeDataType(altContentType);
 
-  chan.asyncOpen2(new ChannelListener(readServerContent, null, CL_ALLOW_UNKNOWN_CL));
+  chan.asyncOpen2(new ChannelListener(readServerContent, null));
   do_test_pending();
 }
 
 function readServerContent(request, buffer)
 {
   var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
 
   do_check_eq(buffer, responseContent);