bug 366559 - patch 6, support different content encodings for http vs https r=bagder
authorPatrick McManus <mcmanus@ducksong.com>
Sat, 19 Sep 2015 18:51:32 -0400
changeset 263813 5e0a3850571f
parent 263812 f504caa27f0a
child 263814 4d45c4323570
push id29418
push userkwierso@gmail.com
push date2015-09-22 23:42 +0000
treeherdermozilla-central@05a7ee49d40a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbagder
bugs366559
milestone44.0a1
bug 366559 - patch 6, support different content encodings for http vs https r=bagder
modules/libpref/init/all.js
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1317,16 +1317,17 @@ pref("network.http.enablePerElementRefer
 
 // Maximum number of consecutive redirects before aborting.
 pref("network.http.redirection-limit", 20);
 
 // Enable http compression: comment this out in case of problems with 1.1
 // NOTE: support for "compress" has been disabled per bug 196406.
 // NOTE: separate values with comma+space (", "): see bug 576033
 pref("network.http.accept-encoding", "gzip, deflate");
+pref("network.http.accept-encoding.secure", "gzip, deflate");
 
 pref("network.http.pipelining"      , false);
 pref("network.http.pipelining.ssl"  , false); // disable pipelining over SSL
 pref("network.http.pipelining.abtest", false);
 pref("network.http.proxy.pipelining", false);
 
 // Max number of requests in the pipeline
 pref("network.http.pipelining.maxrequests" , 32);
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -135,19 +135,19 @@ HttpBaseChannel::Init(nsIURI *aURI,
   mDocumentURI = nullptr;
   mCaps = aCaps;
   mProxyResolveFlags = aProxyResolveFlags;
   mProxyURI = aProxyURI;
 
   // Construct connection info object
   nsAutoCString host;
   int32_t port = -1;
-  bool usingSSL = false;
-
-  nsresult rv = mURI->SchemeIs("https", &usingSSL);
+  bool isHTTPS = false;
+
+  nsresult rv = mURI->SchemeIs("https", &isHTTPS);
   if (NS_FAILED(rv)) return rv;
 
   rv = mURI->GetAsciiHost(host);
   if (NS_FAILED(rv)) return rv;
 
   // Reject the URL if it doesn't specify a host
   if (host.IsEmpty())
     return NS_ERROR_MALFORMED_URI;
@@ -167,17 +167,17 @@ HttpBaseChannel::Init(nsIURI *aURI,
   // Set request headers
   nsAutoCString hostLine;
   rv = nsHttpHandler::GenerateHostPort(host, port, hostLine);
   if (NS_FAILED(rv)) return rv;
 
   rv = mRequestHead.SetHeader(nsHttp::Host, hostLine);
   if (NS_FAILED(rv)) return rv;
 
-  rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead.Headers());
+  rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead.Headers(), isHTTPS);
   if (NS_FAILED(rv)) return rv;
 
   nsAutoCString type;
   if (aProxyInfo && NS_SUCCEEDED(aProxyInfo->GetType(type)) &&
       !type.EqualsLiteral("unknown"))
     mProxyInfo = aProxyInfo;
 
   return rv;
@@ -803,17 +803,19 @@ HttpBaseChannel::DoApplyContentConversio
     if (++count > 16) {
       // That's ridiculous. We only understand 2 different ones :)
       // but for compatibility with old code, we will just carry on without
       // removing the encodings
       LOG(("Too many Content-Encodings. Ignoring remainder.\n"));
       break;
     }
 
-    if (gHttpHandler->IsAcceptableEncoding(val)) {
+    bool isHTTPS = false;
+    mURI->SchemeIs("https", &isHTTPS);
+    if (gHttpHandler->IsAcceptableEncoding(val, isHTTPS)) {
       nsCOMPtr<nsIStreamConverterService> serv;
       rv = gHttpHandler->GetStreamConverterService(getter_AddRefs(serv));
 
       // we won't fail to load the page just because we couldn't load the
       // stream converter service.. carry on..
       if (NS_FAILED(rv)) {
         if (val)
           LOG(("Unknown content encoding '%s', ignoring\n", val));
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -413,17 +413,17 @@ nsHttpHandler::InitConnectionMgr()
                         mMaxPersistentConnectionsPerProxy,
                         mMaxRequestDelay,
                         mMaxPipelinedRequests,
                         mMaxOptimisticPipelinedRequests);
     return rv;
 }
 
 nsresult
-nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request)
+nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request, bool isSecure)
 {
     nsresult rv;
 
     // Add the "User-Agent" header
     rv = request->SetHeader(nsHttp::User_Agent, UserAgent(),
                             false, nsHttpHeaderArray::eVarietyDefault);
     if (NS_FAILED(rv)) return rv;
 
@@ -437,18 +437,23 @@ nsHttpHandler::AddStandardRequestHeaders
     if (!mAcceptLanguages.IsEmpty()) {
         // Add the "Accept-Language" header
         rv = request->SetHeader(nsHttp::Accept_Language, mAcceptLanguages,
                                 false, nsHttpHeaderArray::eVarietyDefault);
         if (NS_FAILED(rv)) return rv;
     }
 
     // Add the "Accept-Encoding" header
-    rv = request->SetHeader(nsHttp::Accept_Encoding, mAcceptEncodings,
-                            false, nsHttpHeaderArray::eVarietyDefault);
+    if (isSecure) {
+        rv = request->SetHeader(nsHttp::Accept_Encoding, mHttpsAcceptEncodings,
+                                false, nsHttpHeaderArray::eVarietyDefault);
+    } else {
+        rv = request->SetHeader(nsHttp::Accept_Encoding, mHttpAcceptEncodings,
+                                false, nsHttpHeaderArray::eVarietyDefault);
+    }
     if (NS_FAILED(rv)) return rv;
 
     // Add the "Do-Not-Track" header
     if (mDoNotTrackEnabled) {
       rv = request->SetHeader(nsHttp::DoNotTrack, NS_LITERAL_CSTRING("1"),
                               false, nsHttpHeaderArray::eVarietyDefault);
       if (NS_FAILED(rv)) return rv;
     }
@@ -478,34 +483,37 @@ nsHttpHandler::AddConnectionHeader(nsHtt
     if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
         connectionType = &keepAlive;
     }
 
     return request->SetHeader(nsHttp::Connection, *connectionType);
 }
 
 bool
-nsHttpHandler::IsAcceptableEncoding(const char *enc)
+nsHttpHandler::IsAcceptableEncoding(const char *enc, bool isSecure)
 {
     if (!enc)
         return false;
 
     // HTTP 1.1 allows servers to send x-gzip and x-compress instead
     // of gzip and compress, for example.  So, we'll always strip off
     // an "x-" prefix before matching the encoding to one we claim
     // to accept.
     if (!PL_strncasecmp(enc, "x-", 2))
         enc += 2;
 
     // gzip and deflate are inherently acceptable in modern HTTP - always
     // process them if a stream converter can also be found.
     if (!PL_strcasecmp(enc, "gzip") || !PL_strcasecmp(enc, "deflate"))
         return true;
 
-    return nsHttp::FindToken(mAcceptEncodings.get(), enc, HTTP_LWS ",") != nullptr;
+    if (isSecure) {
+        return nsHttp::FindToken(mHttpsAcceptEncodings.get(), enc, HTTP_LWS ",") != nullptr;
+    }
+    return nsHttp::FindToken(mHttpAcceptEncodings.get(), enc, HTTP_LWS ",") != nullptr;
 }
 
 nsresult
 nsHttpHandler::GetStreamConverterService(nsIStreamConverterService **result)
 {
     if (!mStreamConvSvc) {
         nsresult rv;
         nsCOMPtr<nsIStreamConverterService> service =
@@ -1151,18 +1159,28 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
         if (NS_SUCCEEDED(rv))
             SetAccept(accept);
     }
 
     if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) {
         nsXPIDLCString acceptEncodings;
         rv = prefs->GetCharPref(HTTP_PREF("accept-encoding"),
                                   getter_Copies(acceptEncodings));
-        if (NS_SUCCEEDED(rv))
-            SetAcceptEncodings(acceptEncodings);
+        if (NS_SUCCEEDED(rv)) {
+            SetAcceptEncodings(acceptEncodings, false);
+        }
+    }
+
+    if (PREF_CHANGED(HTTP_PREF("accept-encoding.secure"))) {
+        nsXPIDLCString acceptEncodings;
+        rv = prefs->GetCharPref(HTTP_PREF("accept-encoding.secure"),
+                                  getter_Copies(acceptEncodings));
+        if (NS_SUCCEEDED(rv)) {
+            SetAcceptEncodings(acceptEncodings, true);
+        }
     }
 
     if (PREF_CHANGED(HTTP_PREF("default-socket-type"))) {
         nsXPIDLCString sval;
         rv = prefs->GetCharPref(HTTP_PREF("default-socket-type"),
                                 getter_Copies(sval));
         if (NS_SUCCEEDED(rv)) {
             if (sval.IsEmpty())
@@ -1749,19 +1767,28 @@ nsHttpHandler::SetAcceptLanguages(const 
 nsresult
 nsHttpHandler::SetAccept(const char *aAccept)
 {
     mAccept = aAccept;
     return NS_OK;
 }
 
 nsresult
-nsHttpHandler::SetAcceptEncodings(const char *aAcceptEncodings)
+nsHttpHandler::SetAcceptEncodings(const char *aAcceptEncodings, bool isSecure)
 {
-    mAcceptEncodings = aAcceptEncodings;
+    if (isSecure) {
+        mHttpsAcceptEncodings = aAcceptEncodings;
+    } else {
+        // use legacy list if a secure override is not specified
+        mHttpAcceptEncodings = aAcceptEncodings;
+        if (mHttpsAcceptEncodings.IsEmpty()) {
+            mHttpsAcceptEncodings = aAcceptEncodings;
+        }
+    }
+      
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpHandler::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS(nsHttpHandler,
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -60,20 +60,20 @@ public:
     NS_DECL_NSIPROXIEDPROTOCOLHANDLER
     NS_DECL_NSIHTTPPROTOCOLHANDLER
     NS_DECL_NSIOBSERVER
     NS_DECL_NSISPECULATIVECONNECT
 
     nsHttpHandler();
 
     nsresult Init();
-    nsresult AddStandardRequestHeaders(nsHttpHeaderArray *);
+    nsresult AddStandardRequestHeaders(nsHttpHeaderArray *, bool isSecure);
     nsresult AddConnectionHeader(nsHttpHeaderArray *,
                                  uint32_t capabilities);
-    bool     IsAcceptableEncoding(const char *encoding);
+    bool     IsAcceptableEncoding(const char *encoding, bool isSecure);
 
     const nsAFlatCString &UserAgent();
 
     nsHttpVersion  HttpVersion()             { return mHttpVersion; }
     nsHttpVersion  ProxyHttpVersion()        { return mProxyHttpVersion; }
     uint8_t        ReferrerLevel()           { return mReferrerLevel; }
     bool           SpoofReferrerSource()     { return mSpoofReferrerSource; }
     uint8_t        ReferrerTrimmingPolicy()  { return mReferrerTrimmingPolicy; }
@@ -349,17 +349,17 @@ private:
     // Useragent/prefs helper methods
     //
     void     BuildUserAgent();
     void     InitUserAgentComponents();
     void     PrefsChanged(nsIPrefBranch *prefs, const char *pref);
 
     nsresult SetAccept(const char *);
     nsresult SetAcceptLanguages(const char *);
-    nsresult SetAcceptEncodings(const char *);
+    nsresult SetAcceptEncodings(const char *, bool mIsSecure);
 
     nsresult InitConnectionMgr();
 
     void     NotifyObservers(nsIHttpChannel *chan, const char *event);
 
     static void TimerCallback(nsITimer * aTimer, void * aClosure);
 private:
 
@@ -426,17 +426,18 @@ private:
 
     uint8_t  mQoSBits;
 
     bool mPipeliningOverSSL;
     bool mEnforceAssocReq;
 
     nsCString mAccept;
     nsCString mAcceptLanguages;
-    nsCString mAcceptEncodings;
+    nsCString mHttpAcceptEncodings;
+    nsCString mHttpsAcceptEncodings;
 
     nsXPIDLCString mDefaultSocketType;
 
     // cache support
     uint32_t                  mLastUniqueID;
     uint32_t                  mSessionStartTime;
 
     // useragent components