bug 602814 - fix parsing of connection http response header r=mcmanus
authorSimonJ <simon-mozilla@abominable.org.uk>
Thu, 18 Apr 2013 09:00:00 -0400
changeset 129198 4078a8fd22ced31329ab773d34276fd3e455e63c
parent 129197 76af6021d5d14a89ad9ddf21809c7d3353c1556e
child 129199 22ed2b874b4aae6e8d4a5fa77b4016429d44d039
push id24562
push userryanvm@gmail.com
push dateFri, 19 Apr 2013 01:24:04 +0000
treeherdermozilla-central@f8d27fe5d7c0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs602814
milestone23.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 602814 - fix parsing of connection http response header r=mcmanus
netwerk/protocol/http/nsHttpConnection.cpp
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -723,39 +723,44 @@ nsHttpConnection::OnHeadersAvailable(nsA
         *reset = true;
         return NS_OK;
     }
 
     // we won't change our keep-alive policy unless the server has explicitly
     // told us to do so.
 
     // inspect the connection headers for keep-alive info provided the
-    // transaction completed successfully.
-    const char *val = responseHead->PeekHeader(nsHttp::Connection);
-    if (!val)
-        val = responseHead->PeekHeader(nsHttp::Proxy_Connection);
+    // transaction completed successfully. In the case of a non-sensical close
+    // and keep-alive favor the close out of conservatism.
+
+    bool explicitKeepAlive = false;
+    bool explicitClose = responseHead->HasHeaderValue(nsHttp::Connection, "close") ||
+        responseHead->HasHeaderValue(nsHttp::Proxy_Connection, "close");
+    if (!explicitClose)
+        explicitKeepAlive = responseHead->HasHeaderValue(nsHttp::Connection, "keep-alive") ||
+            responseHead->HasHeaderValue(nsHttp::Proxy_Connection, "keep-alive");
 
     // reset to default (the server may have changed since we last checked)
     mSupportsPipelining = false;
 
     if ((responseHead->Version() < NS_HTTP_VERSION_1_1) ||
         (requestHead->Version() < NS_HTTP_VERSION_1_1)) {
         // HTTP/1.0 connections are by default NOT persistent
-        if (val && !PL_strcasecmp(val, "keep-alive"))
+        if (explicitKeepAlive)
             mKeepAlive = true;
         else
             mKeepAlive = false;
         
         // We need at least version 1.1 to use pipelines
         gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
             mConnInfo, nsHttpConnectionMgr::RedVersionTooLow, this, 0);
     }
     else {
         // HTTP/1.1 connections are by default persistent
-        if (val && !PL_strcasecmp(val, "close")) {
+        if (explicitClose) {
             mKeepAlive = false;
 
             // persistent connections are required for pipelining to work - if
             // this close was not pre-announced then generate the negative
             // BadExplicitClose feedback
             if (mRemainingConnectionUses > 1)
                 gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
                     mConnInfo, nsHttpConnectionMgr::BadExplicitClose, this, 0);
@@ -803,17 +808,17 @@ nsHttpConnection::OnHeadersAvailable(nsA
     // header specifying the maximum number of times the connection can be
     // reused as well as the maximum amount of time the connection can be idle
     // before the server will close it.  we ignore the max reuse count, because
     // a "keep-alive" connection is by definition capable of being reused, and
     // we only care about being able to reuse it once.  if a timeout is not 
     // specified then we use our advertized timeout value.
     bool foundKeepAliveMax = false;
     if (mKeepAlive) {
-        val = responseHead->PeekHeader(nsHttp::Keep_Alive);
+        const char *val = responseHead->PeekHeader(nsHttp::Keep_Alive);
 
         if (!mUsingSpdyVersion) {
             const char *cp = PL_strcasestr(val, "timeout=");
             if (cp)
                 mIdleTimeout = PR_SecondsToInterval((uint32_t) atoi(cp + 8));
             else
                 mIdleTimeout = gHttpHandler->IdleTimeout();