bug 760608 alternatve 1 preconnect problem with SSL r=honzab
authorPatrick McManus <mcmanus@ducksong.com>
Wed, 06 Jun 2012 15:47:45 -0400
changeset 98724 3b1f2455579acc95bcc9883f13084878f5b80f63
parent 98723 b9c7e2a573c95a2553882c576527924c11fbe6b4
child 98725 d15b364be513ab84dd144cc49d21d1e8d85b94c9
push id1729
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 20:02:43 +0000
treeherdermozilla-aurora@f4e75e148951 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershonzab
bugs760608
milestone16.0a1
bug 760608 alternatve 1 preconnect problem with SSL r=honzab
netwerk/protocol/http/NullHttpTransaction.cpp
netwerk/protocol/http/nsHttpConnectionMgr.cpp
--- a/netwerk/protocol/http/NullHttpTransaction.cpp
+++ b/netwerk/protocol/http/NullHttpTransaction.cpp
@@ -14,17 +14,17 @@ namespace net {
 
 NS_IMPL_THREADSAFE_ISUPPORTS0(NullHttpTransaction);
 
 NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci,
                                          nsIInterfaceRequestor *callbacks,
                                          nsIEventTarget *target,
                                          PRUint8 caps)
   : mStatus(NS_OK)
-  , mCaps(caps)
+  , mCaps(caps | NS_HTTP_ALLOW_KEEPALIVE)
   , mCallbacks(callbacks)
   , mEventTarget(target)
   , mConnectionInfo(ci)
   , mRequestHead(nsnull)
   , mIsDone(false)
 {
 }
 
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -1582,46 +1582,58 @@ nsHttpConnectionMgr::DispatchAbstractTra
     NS_ABORT_IF_FALSE(!conn->UsingSpdy(),
                       "Spdy Must Not Use DispatchAbstractTransaction");
     LOG(("nsHttpConnectionMgr::DispatchAbstractTransaction "
          "[ci=%s trans=%x caps=%x conn=%x]\n",
          ent->mConnInfo->HashKey().get(), aTrans, caps, conn));
 
     /* Use pipeline datastructure even if connection does not currently qualify
        to pipeline this transaction because a different pipeline-eligible
-       transaction might be placed on the active connection */
-
-    nsRefPtr<nsHttpPipeline> pipeline;
-    nsresult rv = BuildPipeline(ent, aTrans, getter_AddRefs(pipeline));
-    if (!NS_SUCCEEDED(rv))
-        return rv;
+       transaction might be placed on the active connection. Make an exception
+       for CLASS_SOLO as that connection will never pipeline until it goes
+       quiescent */
+
+    nsRefPtr<nsAHttpTransaction> transaction;
+    nsresult rv;
+    if (conn->Classification() != nsAHttpTransaction::CLASS_SOLO) {
+        LOG(("   using pipeline datastructure.\n"));
+        nsRefPtr<nsHttpPipeline> pipeline;
+        rv = BuildPipeline(ent, aTrans, getter_AddRefs(pipeline));
+        if (!NS_SUCCEEDED(rv))
+            return rv;
+        transaction = pipeline;
+    }
+    else {
+        LOG(("   not using pipeline datastructure due to class solo.\n"));
+        transaction = aTrans;
+    }
 
     nsRefPtr<nsConnectionHandle> handle = new nsConnectionHandle(conn);
 
     // give the transaction the indirect reference to the connection.
-    pipeline->SetConnection(handle);
-
-    rv = conn->Activate(pipeline, caps, priority);
+    transaction->SetConnection(handle);
+
+    rv = conn->Activate(transaction, caps, priority);
     if (NS_FAILED(rv)) {
         LOG(("  conn->Activate failed [rv=%x]\n", rv));
         ent->mActiveConns.RemoveElement(conn);
         if (conn == ent->mYellowConnection)
             ent->OnYellowComplete();
         mNumActiveConns--;
         ConditionallyStopReadTimeoutTick();
 
         // sever back references to connection, and do so without triggering
         // a call to ReclaimConnection ;-)
-        pipeline->SetConnection(nsnull);
+        transaction->SetConnection(nsnull);
         NS_RELEASE(handle->mConn);
         // destroy the connection
         NS_RELEASE(conn);
     }
 
-    // As pipeline goes out of scope it will drop the last refernece to the
+    // As transaction goes out of scope it will drop the last refernece to the
     // pipeline if activation failed, in which case this will destroy
     // the pipeline, which will cause each the transactions owned by the 
     // pipeline to be restarted.
 
     return rv;
 }
 
 nsresult
@@ -2638,18 +2650,20 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
         // After about 1 second allow for the possibility of restarting a
         // transaction due to server close. Keep at sub 1 second as that is the
         // minimum granularity we can expect a server to be timing out with.
         conn->SetIsReusedAfter(950);
 
         // if we are using ssl and no other transactions are waiting right now,
         // then form a null transaction to drive the SSL handshake to
         // completion. Afterwards the connection will be 100% ready for the next
-        // transaction to use it.
-        if (mEnt->mConnInfo->UsingSSL() && !mEnt->mPendingQ.Length()) {
+        // transaction to use it. Make an exception for SSL over HTTP proxy as the
+        // NullHttpTransaction does not know how to drive CONNECT.
+        if (mEnt->mConnInfo->UsingSSL() && !mEnt->mPendingQ.Length() &&
+            !mEnt->mConnInfo->UsingHttpProxy()) {
             LOG(("nsHalfOpenSocket::OnOutputStreamReady null transaction will "
                  "be used to finish SSL handshake on conn %p\n", conn.get()));
             nsRefPtr<NullHttpTransaction>  trans =
                 new NullHttpTransaction(mEnt->mConnInfo,
                                         callbacks, callbackTarget,
                                         mCaps & ~NS_HTTP_ALLOW_PIPELINING);
 
             gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);