Bug 1172884 P1 Properly decode body when intercepted response redirects. r=mayhemer a=kwierso
☠☠ backed out by 437700eb4d87 ☠ ☠
authorBen Kelly <ben@wanderview.com>
Thu, 11 Jun 2015 17:52:01 -0700
changeset 279295 6231a72d0557b2e835150945188bea306f996da8
parent 279168 bf40676095aac00fd78c37a9e8958ca4810fbc02
child 279296 573451ac095c5c3b182daa17ad63f6dcd346166f
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer, kwierso
bugs1172884
milestone41.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 1172884 P1 Properly decode body when intercepted response redirects. r=mayhemer a=kwierso
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/InterceptedChannel.cpp
netwerk/protocol/http/nsHttpChannel.cpp
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -39,16 +39,19 @@
 #endif
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
+extern bool
+WillRedirect(const nsHttpResponseHead * response);
+
 namespace {
 
 const uint32_t kMaxFileDescriptorsPerMessage = 250;
 
 #ifdef OS_POSIX
 // Keep this in sync with other platforms.
 static_assert(FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE == 250,
               "MAX_DESCRIPTORS_PER_MESSAGE mismatch!");
@@ -2181,18 +2184,21 @@ HttpChannelChild::ResetInterception()
   NS_ENSURE_SUCCESS_VOID(rv);
 }
 
 void
 HttpChannelChild::OverrideWithSynthesizedResponse(nsAutoPtr<nsHttpResponseHead>& aResponseHead,
                                                   nsIInputStream* aSynthesizedInput,
                                                   nsIStreamListener* aStreamListener)
 {
-  // Intercepted responses should already be decoded.
-  SetApplyConversion(false);
+  // Intercepted responses should already be decoded.  If its a redirect,
+  // however, we want to respect the encoding of the final result instead.
+  if (!WillRedirect(aResponseHead)) {
+    SetApplyConversion(false);
+  }
 
   mResponseHead = aResponseHead;
   mSynthesizedResponse = true;
 
   uint16_t status = mResponseHead->Status();
   if (status != 200 && status != 404) {
     // Continue with the original cross-process request
     nsresult rv = ContinueAsyncOpen();
--- a/netwerk/protocol/http/InterceptedChannel.cpp
+++ b/netwerk/protocol/http/InterceptedChannel.cpp
@@ -13,16 +13,19 @@
 #include "nsHttpChannel.h"
 #include "HttpChannelChild.h"
 #include "nsHttpResponseHead.h"
 #include "mozilla/dom/ChannelInfo.h"
 
 namespace mozilla {
 namespace net {
 
+extern bool
+WillRedirect(const nsHttpResponseHead * response);
+
 extern nsresult
 DoAddCacheEntryHeaders(nsHttpChannel *self,
                        nsICacheEntry *entry,
                        nsHttpRequestHead *requestHead,
                        nsHttpResponseHead *responseHead,
                        nsISupports *securityInfo);
 
 NS_IMPL_ISUPPORTS(InterceptedChannelBase, nsIInterceptedChannel)
@@ -179,16 +182,23 @@ NS_IMETHODIMP
 InterceptedChannelChrome::FinishSynthesizedResponse()
 {
   if (!mChannel) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   EnsureSynthesizedResponse();
 
+  // If the synthesized response is a redirect, then we want to respect
+  // the encoding of whatever is loaded as a result.
+  if (WillRedirect(mSynthesizedResponseHead.ref())) {
+    nsresult rv = mChannel->SetApplyConversion(mOldApplyConversion);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   mChannel->MarkIntercepted();
 
   // First we ensure the appropriate metadata is set on the synthesized cache entry
   // (i.e. the flattened response head)
 
   nsCOMPtr<nsISupports> securityInfo;
   nsresult rv = mChannel->GetSecurityInfo(getter_AddRefs(securityInfo));
   NS_ENSURE_SUCCESS(rv, rv);
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -152,27 +152,27 @@ Hash(const char *buf, nsACString &hash)
 
 bool IsRedirectStatus(uint32_t status)
 {
     // 305 disabled as a security measure (see bug 187996).
     return status == 300 || status == 301 || status == 302 || status == 303 ||
            status == 307 || status == 308;
 }
 
+} // unnamed namespace
+
 // We only treat 3xx responses as redirects if they have a Location header and
 // the status code is in a whitelist.
 bool
 WillRedirect(const nsHttpResponseHead * response)
 {
     return IsRedirectStatus(response->Status()) &&
            response->PeekHeader(nsHttp::Location);
 }
 
-} // unnamed namespace
-
 nsresult
 StoreAuthorizationMetaData(nsICacheEntry *entry, nsHttpRequestHead *requestHead);
 
 class AutoRedirectVetoNotifier
 {
 public:
     explicit AutoRedirectVetoNotifier(nsHttpChannel* channel) : mChannel(channel)
     {