Backed out changeset f65247c7647a (bug 729133)
authorGeoff Lankow <geoff@darktrojan.net>
Sun, 26 Feb 2012 13:50:34 +1300
changeset 87735 11fe119b6075589db5aa9afbee76c8673c1c7af6
parent 87734 a8a1e874238a6dfdbf306b92187cb8dfcc766c21
child 87736 d0679906670729207d07e450a9804a528020fcb2
push id22143
push userphilringnalda@gmail.com
push dateSun, 26 Feb 2012 23:12:35 +0000
treeherdermozilla-central@b98fc24ac54b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs729133
milestone13.0a1
backs outf65247c7647a530499b9c8331c2284ed556227cf
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
Backed out changeset f65247c7647a (bug 729133)
netwerk/protocol/http/Makefile.in
netwerk/protocol/http/NullHttpTransaction.cpp
netwerk/protocol/http/NullHttpTransaction.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnectionInfo.cpp
netwerk/protocol/http/nsHttpConnectionInfo.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
netwerk/protocol/http/nsHttpHandler.h
--- a/netwerk/protocol/http/Makefile.in
+++ b/netwerk/protocol/http/Makefile.in
@@ -107,17 +107,16 @@ CPPSRCS = \
   nsHttpPipeline.cpp \
   nsHttpActivityDistributor.cpp \
   nsHttpChannelAuthProvider.cpp \
   HttpChannelParent.cpp \
   HttpChannelChild.cpp \
   HttpChannelParentListener.cpp \
   SpdySession.cpp \
   SpdyStream.cpp \
-  NullHttpTransaction.cpp \
   $(NULL)
 
 LOCAL_INCLUDES = \
   -I$(srcdir)/../../base/src \
   -I$(topsrcdir)/xpcom/ds \
   -I$(topsrcdir)/content/base/src \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
deleted file mode 100644
--- a/netwerk/protocol/http/NullHttpTransaction.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Patrick McManus <mcmanus@ducksong.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsHttp.h"
-#include "NullHttpTransaction.h"
-#include "nsProxyRelease.h"
-#include "nsHttpHandler.h"
-
-namespace mozilla {
-namespace net {
-
-NS_IMPL_THREADSAFE_ISUPPORTS0(NullHttpTransaction);
-
-NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci,
-                                         nsIInterfaceRequestor *callbacks,
-                                         nsIEventTarget *target,
-                                         PRUint8 caps)
-  : mStatus(NS_OK)
-  , mCaps(caps)
-  , mCallbacks(callbacks)
-  , mEventTarget(target)
-  , mConnectionInfo(ci)
-  , mRequestHead(nsnull)
-{
-}
-
-NullHttpTransaction::~NullHttpTransaction()
-{
-  if (mCallbacks) {
-    nsIInterfaceRequestor *cbs = nsnull;
-    mCallbacks.swap(cbs);
-    NS_ProxyRelease(mEventTarget, cbs);
-  }
-  delete mRequestHead;
-}
-
-void
-NullHttpTransaction::SetConnection(nsAHttpConnection *conn)
-{
-  mConnection = conn;
-}
-
-nsAHttpConnection *
-NullHttpTransaction::Connection()
-{
-  return mConnection.get();
-}
-
-void
-NullHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **outCB,
-                                           nsIEventTarget **outTarget)
-{
-  nsCOMPtr<nsIInterfaceRequestor> copyCB(mCallbacks);
-  *outCB = copyCB;
-  copyCB.forget();
-
-  if (outTarget) {
-    nsCOMPtr<nsIEventTarget> copyET(mEventTarget);
-    *outTarget = copyET;
-    copyET.forget();
-  }
-}
-
-void
-NullHttpTransaction::OnTransportStatus(nsITransport* transport,
-                                       nsresult status, PRUint64 progress)
-{
-}
-
-bool
-NullHttpTransaction::IsDone()
-{
-  return true;
-}
-
-nsresult
-NullHttpTransaction::Status()
-{
-  return mStatus;
-}
-
-PRUint32
-NullHttpTransaction::Available()
-{
-  return 0;
-}
-
-nsresult
-NullHttpTransaction::ReadSegments(nsAHttpSegmentReader *reader,
-                                  PRUint32 count, PRUint32 *countRead)
-{
-  *countRead = 0;
-  return NS_BASE_STREAM_CLOSED;
-}
-
-nsresult
-NullHttpTransaction::WriteSegments(nsAHttpSegmentWriter *writer,
-                                   PRUint32 count, PRUint32 *countWritten)
-{
-  *countWritten = 0;
-  return NS_BASE_STREAM_CLOSED;
-}
-
-PRUint32
-NullHttpTransaction::Http1xTransactionCount()
-{
-  return 0;
-}
-
-nsHttpRequestHead *
-NullHttpTransaction::RequestHead()
-{
-  // We suport a requesthead at all so that a CONNECT tunnel transaction
-  // can obtain a Host header from it, but we lazy-popualate that header.
-
-  if (!mRequestHead) {
-    mRequestHead = new nsHttpRequestHead();
-
-    nsCAutoString hostHeader;
-    nsCString host(mConnectionInfo->GetHost());
-    nsresult rv = nsHttpHandler::GenerateHostPort(host,
-                                                  mConnectionInfo->Port(),
-                                                  hostHeader);
-    if (NS_SUCCEEDED(rv))
-       mRequestHead->SetHeader(nsHttp::Host, hostHeader);
-
-    // CONNECT tunnels may also want Proxy-Authorization but that is a lot
-    // harder to determine, so for now we will let those connections fail in
-    // the NullHttpTransaction and let them be retried from the pending queue
-    // with a bound transcation
-  }
-  
-  return mRequestHead;
-}
-
-nsresult
-NullHttpTransaction::TakeSubTransactions(
-  nsTArray<nsRefPtr<nsAHttpTransaction> > &outTransactions)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-void
-NullHttpTransaction::SetSSLConnectFailed()
-{
-}
-
-void
-NullHttpTransaction::Close(nsresult reason)
-{
-  mStatus = reason;
-  mConnection = nsnull;
-}
-
-} // namespace mozilla::net
-} // namespace mozilla
-
deleted file mode 100644
--- a/netwerk/protocol/http/NullHttpTransaction.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Patrick McManus <mcmanus@ducksong.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef mozilla_net_NullHttpTransaction_h
-#define mozilla_net_NullHttpTransaction_h
-
-#include "nsAHttpTransaction.h"
-#include "nsAHttpConnection.h"
-#include "nsIInterfaceRequestor.h"
-#include "nsIEventTarget.h"
-#include "nsHttpConnectionInfo.h"
-#include "nsHttpRequestHead.h"
-
-// This is the minimal nsAHttpTransaction implementation. A NullHttpTransaction
-// can be used to drive connection level semantics (such as SSL handshakes
-// tunnels) so that a nsHttpConnection becomes fully established in
-// anticiation of a real transaction needing to use it soon.
-
-namespace mozilla { namespace net {
-
-class NullHttpTransaction : public nsAHttpTransaction
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSAHTTPTRANSACTION
-
-  NullHttpTransaction(nsHttpConnectionInfo *ci,
-                      nsIInterfaceRequestor *callbacks,
-                      nsIEventTarget *target,
-                      PRUint8 caps);
-  ~NullHttpTransaction();
-
-  PRUint8 Caps() { return mCaps; }
-  nsHttpConnectionInfo *ConnectionInfo() { return mConnectionInfo; }
-
-private:
-
-  nsresult mStatus;
-  PRUint8  mCaps;
-  nsRefPtr<nsAHttpConnection> mConnection;
-  nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
-  nsCOMPtr<nsIEventTarget> mEventTarget;
-  nsRefPtr<nsHttpConnectionInfo> mConnectionInfo;
-  nsHttpRequestHead *mRequestHead;
-};
-
-}} // namespace mozilla::net
-
-#endif // mozilla_net_NullHttpTransaction_h
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -65,17 +65,16 @@
 #include "nsDNSPrefetch.h"
 #include "nsChannelClassifier.h"
 #include "nsIRedirectResultListener.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 #include "nsDOMError.h"
 #include "nsAlgorithm.h"
 #include "sampler.h"
-#include "NullHttpTransaction.h"
 
 using namespace mozilla;
 
 // Device IDs for various cache types
 const char kDiskDeviceID[] = "disk";
 const char kMemoryDeviceID[] = "memory";
 const char kOfflineDeviceID[] = "offline";
 
@@ -226,26 +225,16 @@ nsHttpChannel::Connect(bool firstTime)
     }
 
     // ensure that we are using a valid hostname
     if (!net_IsValidHostName(nsDependentCString(mConnectionInfo->Host())))
         return NS_ERROR_UNKNOWN_HOST;
 
     // true when called from AsyncOpen
     if (firstTime) {
-
-        // Before we take the latency hit of dealing with the cache, try and
-        // get the TCP (and SSL) handshakes going so they can overlap.
-        nsCOMPtr<nsIInterfaceRequestor> callbacks;
-        NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
-                                               getter_AddRefs(callbacks));
-        if (callbacks)
-            gHttpHandler->SpeculativeConnect(mConnectionInfo,
-                                             callbacks, NS_GetCurrentThread());
-
         // are we offline?
         bool offline = gIOService->IsOffline();
         if (offline)
             mLoadFlags |= LOAD_ONLY_FROM_CACHE;
         else if (PL_strcmp(mConnectionInfo->ProxyType(), "unknown") == 0)
             return ResolveProxy();  // Lazily resolve proxy info
 
         // Don't allow resuming when cache must be used
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -395,37 +395,33 @@ nsHttpConnection::SetupNPN(PRUint8 caps)
     mSetupNPNCalled = true;
 
     // Setup NPN Negotiation if necessary (only for SPDY)
     if (!mNPNComplete) {
 
         mNPNComplete = true;
 
         if (mConnInfo->UsingSSL() &&
-            !mConnInfo->UsingHttpProxy()) {
-            LOG(("nsHttpConnection::SetupNPN Setting up "
-                 "Next Protocol Negotiation"));
+            !(caps & NS_HTTP_DISALLOW_SPDY) &&
+            !mConnInfo->UsingHttpProxy() &&
+            gHttpHandler->IsSpdyEnabled()) {
+            LOG(("nsHttpConnection::Init Setting up SPDY Negotiation"));
             nsCOMPtr<nsISupports> securityInfo;
             nsresult rv =
                 mSocketTransport->GetSecurityInfo(getter_AddRefs(securityInfo));
             if (NS_FAILED(rv))
                 return;
 
             nsCOMPtr<nsISSLSocketControl> ssl =
                 do_QueryInterface(securityInfo, &rv);
             if (NS_FAILED(rv))
                 return;
 
             nsTArray<nsCString> protocolArray;
-            if (gHttpHandler->IsSpdyEnabled() &&
-                !(caps & NS_HTTP_DISALLOW_SPDY)) {
-                LOG(("nsHttpConnection::SetupNPN Allow SPDY NPN selection"));
-                protocolArray.AppendElement(NS_LITERAL_CSTRING("spdy/2"));
-            }
-
+            protocolArray.AppendElement(NS_LITERAL_CSTRING("spdy/2"));
             protocolArray.AppendElement(NS_LITERAL_CSTRING("http/1.1"));
             if (NS_SUCCEEDED(ssl->SetNPNList(protocolArray))) {
                 LOG(("nsHttpConnection::Init Setting up SPDY Negotiation OK"));
                 mNPNComplete = false;
             }
         }
     }
 }
@@ -1100,17 +1096,17 @@ nsHttpConnection::OnSocketWritable()
             LOG(("  writing transaction request stream\n"));
             rv = mTransaction->ReadSegments(this, nsIOService::gDefaultSegmentSize, &n);
         }
 
         LOG(("  ReadSegments returned [rv=%x read=%u sock-cond=%x]\n",
             rv, n, mSocketOutCondition));
 
         // XXX some streams return NS_BASE_STREAM_CLOSED to indicate EOF.
-        if (rv == NS_BASE_STREAM_CLOSED && !mTransaction->IsDone()) {
+        if (rv == NS_BASE_STREAM_CLOSED) {
             rv = NS_OK;
             n = 0;
         }
 
         if (NS_FAILED(rv)) {
             // if the transaction didn't want to write any more data, then
             // wait for the transaction to call ResumeSend.
             if (rv == NS_BASE_STREAM_WOULD_BLOCK)
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
@@ -86,16 +86,18 @@ nsHttpConnectionInfo::SetOriginServer(co
         mHashKey.Append(')');
     }
 }
 
 nsHttpConnectionInfo*
 nsHttpConnectionInfo::Clone() const
 {
     nsHttpConnectionInfo* clone = new nsHttpConnectionInfo(mHost, mPort, mProxyInfo, mUsingSSL);
+    if (!clone)
+        return nsnull;
 
     // Make sure the anonymous flag is transferred!
     clone->SetAnonymous(mHashKey.CharAt(2) == 'A');
     
     return clone;
 }
 
 bool
--- a/netwerk/protocol/http/nsHttpConnectionInfo.h
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.h
@@ -93,17 +93,16 @@ public:
 
     void SetOriginServer(const nsACString &host, PRInt32 port);
 
     void SetOriginServer(const char *host, PRInt32 port)
     {
         SetOriginServer(nsDependentCString(host), port);
     }
     
-    // OK to treat this as an infalible allocation
     nsHttpConnectionInfo* Clone() const;
 
     const char *ProxyHost() const { return mProxyInfo ? mProxyInfo->Host().get() : nsnull; }
     PRInt32     ProxyPort() const { return mProxyInfo ? mProxyInfo->Port() : -1; }
     const char *ProxyType() const { return mProxyInfo ? mProxyInfo->Type() : nsnull; }
 
     // Compare this connection info to another...
     // Two connections are 'equal' if they end up talking the same
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -48,17 +48,16 @@
 
 #include "nsIObserverService.h"
 
 #include "nsISSLSocketControl.h"
 #include "prnetdb.h"
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla;
-using namespace mozilla::net;
 
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 
 static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
 
 //-----------------------------------------------------------------------------
 
@@ -332,34 +331,16 @@ nsHttpConnectionMgr::PruneDeadConnection
 
 nsresult
 nsHttpConnectionMgr::ClosePersistentConnections()
 {
     return PostEvent(&nsHttpConnectionMgr::OnMsgClosePersistentConnections);
 }
 
 nsresult
-nsHttpConnectionMgr::SpeculativeConnect(nsHttpConnectionInfo *ci,
-                                        nsIInterfaceRequestor *callbacks,
-                                        nsIEventTarget *target)
-{
-    LOG(("nsHttpConnectionMgr::SpeculativeConnect [ci=%s]\n",
-         ci->HashKey().get()));
-
-    nsRefPtr<NullHttpTransaction> trans =
-        new NullHttpTransaction(ci, callbacks, target, 0);
-
-    nsresult rv =
-        PostEvent(&nsHttpConnectionMgr::OnMsgSpeculativeConnect, 0, trans);
-    if (NS_SUCCEEDED(rv))
-        trans.forget();
-    return rv;
-}
-
-nsresult
 nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
 {
     // This object doesn't get reinitialized if the offline state changes, so our
     // socket thread target might be uninitialized if we were offline when this
     // object was being initialized, and we go online later on.  This call takes
     // care of initializing the socket thread target if that's the case.
     EnsureSocketThreadTargetIfOnline();
 
@@ -1067,32 +1048,16 @@ nsHttpConnectionMgr::ClosePersistentConn
                                                   nsAutoPtr<nsConnectionEntry> &ent,
                                                   void *closure)
 {
     nsHttpConnectionMgr *self = static_cast<nsHttpConnectionMgr *>(closure);
     self->ClosePersistentConnections(ent);
     return PL_DHASH_NEXT;
 }
 
-bool
-nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent)
-{
-    NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
-
-    // If this host is trying to negotiate a SPDY session right now,
-    // don't create any new ssl connections until the result of the
-    // negotiation is known.
-    
-    return ent->mConnInfo->UsingSSL() &&
-        gHttpHandler->IsSpdyEnabled() &&
-        !ent->mConnInfo->UsingHttpProxy() &&
-        (!ent->mTestedSpdy || ent->mUsingSpdy) &&
-        (ent->mHalfOpens.Length() || ent->mActiveConns.Length());
-}
-
 void
 nsHttpConnectionMgr::GetConnection(nsConnectionEntry *ent,
                                    nsHttpTransaction *trans,
                                    bool onlyReusedConnection,
                                    nsHttpConnection **result)
 {
     LOG(("nsHttpConnectionMgr::GetConnection [ci=%s caps=%x]\n",
         ent->mConnInfo->HashKey().get(), PRUint32(trans->Caps())));
@@ -1145,35 +1110,29 @@ nsHttpConnectionMgr::GetConnection(nsCon
     }
 
     if (!conn) {
 
         // If the onlyReusedConnection parameter is TRUE, then GetConnection()
         // does not create new transports under any circumstances.
         if (onlyReusedConnection)
             return;
-
-        PRUint32 halfOpenLength = ent->mHalfOpens.Length();
-        for (PRUint32 i = 0; i < halfOpenLength; i++) {
-            if (ent->mHalfOpens[i]->IsSpeculative()) {
-                // We've found a speculative connection in the half
-                // open list. Remove the speculative bit from it and that
-                // connection can later be used for this transaction
-                // (or another one in the pending queue) - we don't
-                // need to open a new connection here.
-                LOG(("nsHttpConnectionMgr::GetConnection [ci = %s]\n"
-                     "Found a speculative half open connection\n",
-                     ent->mConnInfo->HashKey().get()));
-                ent->mHalfOpens[i]->SetSpeculative(false);
+        
+        if (gHttpHandler->IsSpdyEnabled() &&
+            ent->mConnInfo->UsingSSL() &&
+            !ent->mConnInfo->UsingHttpProxy())
+        {
+            // If this host is trying to negotiate a SPDY session right now,
+            // don't create any new connections until the result of the
+            // negotiation is known.
+    
+            if ((!ent->mTestedSpdy || ent->mUsingSpdy) &&
+                (ent->mHalfOpens.Length() || ent->mActiveConns.Length()))
                 return;
-            }
         }
-
-        if (RestrictConnections(ent))
-            return;
         
         // Check if we need to purge an idle connection. Note that we may have
         // removed one above; if so, this will be a no-op. We do this before
         // checking the active connection limit to catch the case where we do
         // have an idle connection, but the purge timer hasn't fired yet.
         // XXX this just purges a random idle connection.  we should instead
         // enumerate the entire hash table to find the eldest idle connection.
         if (mNumIdleConns && mNumIdleConns + mNumActiveConns + 1 >= mMaxConns)
@@ -1189,17 +1148,17 @@ nsHttpConnectionMgr::GetConnection(nsCon
             return;
         }
 
         LOG(("nsHttpConnectionMgr::GetConnection Open Connection "
              "%s %s ent=%p spdy=%d",
              ent->mConnInfo->Host(), ent->mCoalescingKey.get(),
              ent, ent->mUsingSpdy));
         
-        nsresult rv = CreateTransport(ent, trans, trans->Caps(), false);
+        nsresult rv = CreateTransport(ent, trans);
         if (NS_FAILED(rv))
             trans->Close(rv);
         return;
     }
 
     if (addConnToActiveList) {
         // hold an owning ref to this connection
         ent->mActiveConns.AppendElement(conn);
@@ -1229,29 +1188,25 @@ nsHttpConnectionMgr::StartedConnect()
 void
 nsHttpConnectionMgr::RecvdConnect()
 {
     mNumActiveConns--;
 }
 
 nsresult
 nsHttpConnectionMgr::CreateTransport(nsConnectionEntry *ent,
-                                     nsAHttpTransaction *trans,
-                                     PRUint8 caps,
-                                     bool speculative)
+                                     nsHttpTransaction *trans)
 {
     NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
 
-    nsRefPtr<nsHalfOpenSocket> sock = new nsHalfOpenSocket(ent, trans, caps);
+    nsRefPtr<nsHalfOpenSocket> sock = new nsHalfOpenSocket(ent, trans);
     nsresult rv = sock->SetupPrimaryStreams();
     NS_ENSURE_SUCCESS(rv, rv);
 
     ent->mHalfOpens.AppendElement(sock);
-    if (speculative)
-        sock->SetSpeculative(true);
     return NS_OK;
 }
 
 nsresult
 nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent,
                                          nsHttpTransaction *aTrans,
                                          PRUint8 caps,
                                          nsHttpConnection *conn)
@@ -1267,38 +1222,16 @@ nsHttpConnectionMgr::DispatchTransaction
              "Connection host = %s\n",
              aTrans->ConnectionInfo()->Host(),
              conn->ConnectionInfo()->Host()));
         rv = conn->Activate(aTrans, caps, priority);
         NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "SPDY Cannot Fail Dispatch");
         return rv;
     }
 
-    return DispatchAbstractTransaction(ent, aTrans, caps, conn, priority);
-}
-
-
-// Use this method for dispatching nsAHttpTransction's. It can only safely be
-// used upon first use of a connection when NPN has not negotiated SPDY vs
-// HTTP/1 yet as multiplexing onto an existing SPDY session requires a
-// concrete nsHttpTransaction
-nsresult
-nsHttpConnectionMgr::DispatchAbstractTransaction(nsConnectionEntry *ent,
-                                                 nsAHttpTransaction *aTrans,
-                                                 PRUint8 caps,
-                                                 nsHttpConnection *conn,
-                                                 PRInt32 priority)
-{
-    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));
-    nsresult rv;
-    
     nsConnectionHandle *handle = new nsConnectionHandle(conn);
     if (!handle)
         return NS_ERROR_OUT_OF_MEMORY;
     NS_ADDREF(handle);
 
     nsHttpPipeline *pipeline = nsnull;
     nsAHttpTransaction *trans = aTrans;
 
@@ -1372,29 +1305,16 @@ nsHttpConnectionMgr::BuildPipeline(nsCon
     if (numAdded == 0)
         return false;
 
     LOG(("  pipelined %u transactions\n", numAdded));
     NS_ADDREF(*result = pipeline);
     return true;
 }
 
-nsHttpConnectionMgr::nsConnectionEntry *
-nsHttpConnectionMgr::GetOrCreateConnectionEntry(nsHttpConnectionInfo *ci)
-{
-    nsConnectionEntry *ent = mCT.Get(ci->HashKey());
-    if (ent)
-        return ent;
-
-    nsHttpConnectionInfo *clone = ci->Clone();
-    ent = new nsConnectionEntry(clone);
-    mCT.Put(ci->HashKey(), ent);
-    return ent;
-}
-
 nsresult
 nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
 {
     NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
 
     // since "adds" and "cancels" are processed asynchronously and because
     // various events might trigger an "add" directly on the socket thread,
     // we must take care to avoid dispatching a transaction that has already
@@ -1403,17 +1323,26 @@ nsHttpConnectionMgr::ProcessNewTransacti
         LOG(("  transaction was canceled... dropping event!\n"));
         return NS_OK;
     }
 
     PRUint8 caps = trans->Caps();
     nsHttpConnectionInfo *ci = trans->ConnectionInfo();
     NS_ASSERTION(ci, "no connection info");
 
-    nsConnectionEntry *ent = GetOrCreateConnectionEntry(ci);
+    nsConnectionEntry *ent = mCT.Get(ci->HashKey());
+    if (!ent) {
+        nsHttpConnectionInfo *clone = ci->Clone();
+        if (!clone)
+            return NS_ERROR_OUT_OF_MEMORY;
+        ent = new nsConnectionEntry(clone);
+        if (!ent)
+            return NS_ERROR_OUT_OF_MEMORY;
+        mCT.Put(ci->HashKey(), ent);
+    }
 
     // SPDY coalescing of hostnames means we might redirect from this
     // connection entry onto the preferred one.
     nsConnectionEntry *preferredEntry = GetSpdyPreferredEnt(ent);
     if (preferredEntry && (preferredEntry != ent)) {
         LOG(("nsHttpConnectionMgr::ProcessNewTransaction trans=%p "
              "redirected via coalescing from %s to %s\n", trans,
              ent->mConnInfo->Host(), preferredEntry->mConnInfo->Host()));
@@ -1666,36 +1595,16 @@ void
 nsHttpConnectionMgr::OnMsgClosePersistentConnections(PRInt32, void *)
 {
     LOG(("nsHttpConnectionMgr::OnMsgClosePersistentConnections\n"));
 
     mCT.Enumerate(ClosePersistentConnectionsCB, this);
 }
 
 void
-nsHttpConnectionMgr::OnMsgSpeculativeConnect(PRInt32, void *param)
-{
-    NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
-
-    nsRefPtr<NullHttpTransaction> trans =
-        dont_AddRef(static_cast<NullHttpTransaction *>(param));
-
-    LOG(("nsHttpConnectionMgr::OnMsgSpeculativeConnect [ci=%s]\n",
-         trans->ConnectionInfo()->HashKey().get()));
-
-    nsConnectionEntry *ent =
-        GetOrCreateConnectionEntry(trans->ConnectionInfo());
-
-    if (!ent->mIdleConns.Length() && !RestrictConnections(ent) &&
-        !AtActiveConnectionLimit(ent, trans->Caps())) {
-        CreateTransport(ent, trans, trans->Caps(), true);
-    }
-}
-
-void
 nsHttpConnectionMgr::OnMsgReclaimConnection(PRInt32, void *param)
 {
     LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection [conn=%p]\n", param));
 
     nsHttpConnection *conn = (nsHttpConnection *) param;
 
     // 
     // 1) remove the connection from the active list
@@ -1975,22 +1884,19 @@ nsHttpConnectionMgr::nsConnectionHandle:
 NS_IMPL_THREADSAFE_ISUPPORTS4(nsHttpConnectionMgr::nsHalfOpenSocket,
                               nsIOutputStreamCallback,
                               nsITransportEventSink,
                               nsIInterfaceRequestor,
                               nsITimerCallback)
 
 nsHttpConnectionMgr::
 nsHalfOpenSocket::nsHalfOpenSocket(nsConnectionEntry *ent,
-                                   nsAHttpTransaction *trans,
-                                   PRUint8 caps)
+                                   nsHttpTransaction *trans)
     : mEnt(ent),
-      mTransaction(trans),
-      mCaps(caps),
-      mSpeculative(false)
+      mTransaction(trans)
 {
     NS_ABORT_IF_FALSE(ent && trans, "constructor with null arguments");
     LOG(("Creating nsHalfOpenSocket [this=%p trans=%p ent=%s]\n",
          this, trans, ent->mConnInfo->Host()));
 }
 
 nsHttpConnectionMgr::nsHalfOpenSocket::~nsHalfOpenSocket()
 {
@@ -2030,20 +1936,20 @@ nsHalfOpenSocket::SetupStreams(nsISocket
     rv = sts->CreateTransport(types, typeCount,
                               nsDependentCString(mEnt->mConnInfo->Host()),
                               mEnt->mConnInfo->Port(),
                               mEnt->mConnInfo->ProxyInfo(),
                               getter_AddRefs(socketTransport));
     NS_ENSURE_SUCCESS(rv, rv);
     
     PRUint32 tmpFlags = 0;
-    if (mCaps & NS_HTTP_REFRESH_DNS)
+    if (mTransaction->Caps() & NS_HTTP_REFRESH_DNS)
         tmpFlags = nsISocketTransport::BYPASS_CACHE;
 
-    if (mCaps & NS_HTTP_LOAD_ANONYMOUS)
+    if (mTransaction->Caps() & NS_HTTP_LOAD_ANONYMOUS)
         tmpFlags |= nsISocketTransport::ANONYMOUS_CONNECT;
 
     // For backup connections, we disable IPv6. That's because some users have
     // broken IPv6 connectivity (leading to very long timeouts), and disabling
     // IPv6 on the backup connection gives them a much better user experience
     // with dual-stack hosts, though they still pay the 250ms delay for each new
     // connection. This strategy is also known as "happy eyeballs".
     if (isBackup && gHttpHandler->FastFallbackToIPv4())
@@ -2125,17 +2031,17 @@ nsHttpConnectionMgr::nsHalfOpenSocket::S
 }
 
 void
 nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupTimer()
 {
     PRUint16 timeout = gHttpHandler->GetIdleSynTimeout();
     NS_ABORT_IF_FALSE(!mSynTimer, "timer already initd");
     
-    if (timeout && !mTransaction->IsDone()) {
+    if (timeout) {
         // Setup the timer that will establish a backup socket
         // if we do not get a writable event on the main one.
         // We do this because a lost SYN takes a very long time
         // to repair at the TCP level.
         //
         // Failure to setup the timer is something we can live with,
         // so don't return an error in that case.
         nsresult rv;
@@ -2188,17 +2094,17 @@ nsHttpConnectionMgr::nsHalfOpenSocket::A
 
 NS_IMETHODIMP // method for nsITimerCallback
 nsHttpConnectionMgr::nsHalfOpenSocket::Notify(nsITimer *timer)
 {
     NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
     NS_ABORT_IF_FALSE(timer == mSynTimer, "wrong timer");
 
     if (!gHttpHandler->ConnMgr()->
-        AtActiveConnectionLimit(mEnt, mCaps)) {
+        AtActiveConnectionLimit(mEnt, mTransaction->Caps())) {
         SetupBackupStreams();
     }
 
     mSynTimer = nsnull;
     return NS_OK;
 }
 
 // method for nsIAsyncOutputStreamCallback
@@ -2255,23 +2161,23 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
         LOG(("nsHalfOpenSocket::OnOutputStreamReady "
              "conn->init (%p) failed %x\n", conn.get(), rv));
         return rv;
     }
 
     // if this is still in the pending list, remove it and dispatch it
     index = mEnt->mPendingQ.IndexOf(mTransaction);
     if (index != -1) {
-        NS_ABORT_IF_FALSE(!mSpeculative,
-                          "Speculative Half Open found mTranscation");
-        nsRefPtr<nsHttpTransaction> temp = dont_AddRef(mEnt->mPendingQ[index]);
         mEnt->mPendingQ.RemoveElementAt(index);
+        nsHttpTransaction *temp = mTransaction;
+        NS_RELEASE(temp);
         gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
-        rv = gHttpHandler->ConnMgr()->DispatchTransaction(mEnt, temp,
-                                                          mCaps, conn);
+        rv = gHttpHandler->ConnMgr()->DispatchTransaction(mEnt, mTransaction,
+                                                          mTransaction->Caps(),
+                                                          conn);
     }
     else {
         // this transaction was dispatched off the pending q before all the
         // sockets established themselves.
 
         // We need to establish a small non-zero idle timeout so the connection
         // mgr perceives this socket as suitable for persistent connection reuse
         const PRIntervalTime k5Sec = PR_SecondsToInterval(5);
@@ -2280,41 +2186,18 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
         else
             conn->SetIdleTimeout(gHttpHandler->IdleTimeout());
 
         // 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()) {
-            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);
-            rv = gHttpHandler->ConnMgr()->
-                DispatchAbstractTransaction(mEnt, trans, mCaps, conn, 0);
-        }
-        else {
-            // otherwise just put this in the persistent connection pool
-            LOG(("nsHalfOpenSocket::OnOutputStreamReady no transaction match "
-                 "returning conn %p to pool\n", conn.get()));
-            nsRefPtr<nsHttpConnection> copy(conn);
-            // forget() to effectively addref because onmsg*() will drop a ref
-            gHttpHandler->ConnMgr()->OnMsgReclaimConnection(
-                NS_OK, conn.forget().get());
-        }
+        nsRefPtr<nsHttpConnection> copy(conn);  // because onmsg*() expects to drop a reference
+        gHttpHandler->ConnMgr()->OnMsgReclaimConnection(NS_OK, conn.forget().get());
     }
 
     return rv;
 }
 
 // method for nsITransportEventSink
 NS_IMETHODIMP
 nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport *trans,
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -37,17 +37,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsHttpConnectionMgr_h__
 #define nsHttpConnectionMgr_h__
 
 #include "nsHttpConnectionInfo.h"
 #include "nsHttpConnection.h"
 #include "nsHttpTransaction.h"
-#include "NullHttpTransaction.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
 #include "nsAutoPtr.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsISocketTransportService.h"
 #include "nsHashSets.h"
@@ -121,26 +120,16 @@ public:
     // Close all idle persistent connections and prevent any active connections
     // from being reused.
     nsresult ClosePersistentConnections();
 
     // called to get a reference to the socket transport service.  the socket
     // transport service is not available when the connection manager is down.
     nsresult GetSocketThreadTarget(nsIEventTarget **);
 
-    // called to indicate a transaction for the connectionInfo is likely coming
-    // soon. The connection manager may use this information to start a TCP
-    // and/or SSL level handshake for that resource immediately so that it is
-    // ready when the transaction is submitted. No obligation is taken on by the
-    // connection manager, nor is the submitter obligated to actually submit a
-    // real transaction for this connectionInfo.
-    nsresult SpeculativeConnect(nsHttpConnectionInfo *,
-                                nsIInterfaceRequestor *,
-                                nsIEventTarget *);
-
     // called when a connection is done processing a transaction.  if the 
     // connection can be reused then it will be added to the idle list, else
     // it will be closed.
     nsresult ReclaimConnection(nsHttpConnection *conn);
 
     // called to update a parameter after the connection manager has already
     // been initialized.
     nsresult UpdateParam(nsParamName name, PRUint16 value);
@@ -257,51 +246,37 @@ private:
     public:
         NS_DECL_ISUPPORTS
         NS_DECL_NSIOUTPUTSTREAMCALLBACK
         NS_DECL_NSITRANSPORTEVENTSINK
         NS_DECL_NSIINTERFACEREQUESTOR
         NS_DECL_NSITIMERCALLBACK
 
         nsHalfOpenSocket(nsConnectionEntry *ent,
-                         nsAHttpTransaction *trans,
-                         PRUint8 caps);
+                         nsHttpTransaction *trans);
         ~nsHalfOpenSocket();
         
         nsresult SetupStreams(nsISocketTransport **,
                               nsIAsyncInputStream **,
                               nsIAsyncOutputStream **,
                               bool isBackup);
         nsresult SetupPrimaryStreams();
         nsresult SetupBackupStreams();
         void     SetupBackupTimer();
         void     CancelBackupTimer();
         void     Abandon();
         
-        nsAHttpTransaction *Transaction() { return mTransaction; }
-
-        bool IsSpeculative() { return mSpeculative; }
-        void SetSpeculative(bool val) { mSpeculative = val; }
+        nsHttpTransaction *Transaction() { return mTransaction; }
 
     private:
         nsConnectionEntry              *mEnt;
-        nsRefPtr<nsAHttpTransaction>   mTransaction;
+        nsRefPtr<nsHttpTransaction>    mTransaction;
         nsCOMPtr<nsISocketTransport>   mSocketTransport;
         nsCOMPtr<nsIAsyncOutputStream> mStreamOut;
         nsCOMPtr<nsIAsyncInputStream>  mStreamIn;
-        PRUint8                        mCaps;
-
-        // mSpeculative is set if the socket was created from
-        // SpeculativeConnect(). It is cleared when a transaction would normally
-        // start a new connection from scratch but instead finds this one in
-        // the half open list and claims it for its own use. (which due to
-        // the vagaries of scheduling from the pending queue might not actually
-        // match up - but it prevents a speculative connection from opening
-        // more connections that are needed.)
-        bool                           mSpeculative;
 
         // for syn retry
         nsCOMPtr<nsITimer>             mSynTimer;
         nsCOMPtr<nsISocketTransport>   mBackupTransport;
         nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut;
         nsCOMPtr<nsIAsyncInputStream>  mBackupStreamIn;
     };
     friend class nsHalfOpenSocket;
@@ -332,34 +307,28 @@ private:
     static PLDHashOperator ProcessOneTransactionCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
 
     static PLDHashOperator PruneDeadConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
     static PLDHashOperator ShutdownPassCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
     static PLDHashOperator PurgeExcessIdleConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
     static PLDHashOperator ClosePersistentConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
     bool     ProcessPendingQForEntry(nsConnectionEntry *);
     bool     AtActiveConnectionLimit(nsConnectionEntry *, PRUint8 caps);
-    bool     RestrictConnections(nsConnectionEntry *);
     void     GetConnection(nsConnectionEntry *, nsHttpTransaction *,
                            bool, nsHttpConnection **);
     nsresult DispatchTransaction(nsConnectionEntry *, nsHttpTransaction *,
                                  PRUint8 caps, nsHttpConnection *);
-    nsresult DispatchAbstractTransaction(nsConnectionEntry *,
-                                         nsAHttpTransaction *, PRUint8 caps,
-                                         nsHttpConnection *, PRInt32);
     bool     BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
     nsresult ProcessNewTransaction(nsHttpTransaction *);
     nsresult EnsureSocketThreadTargetIfOnline();
     void     ClosePersistentConnections(nsConnectionEntry *ent);
-    nsresult CreateTransport(nsConnectionEntry *, nsAHttpTransaction *,
-                             PRUint8, bool);
+    nsresult CreateTransport(nsConnectionEntry *, nsHttpTransaction *);
     void     AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
     void     StartedConnect();
     void     RecvdConnect();
-    nsConnectionEntry *GetOrCreateConnectionEntry(nsHttpConnectionInfo *);
 
     // Manage the preferred spdy connection entry for this address
     nsConnectionEntry *GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry);
     void               RemoveSpdyPreferredEnt(nsACString &aDottedDecimal);
     nsHttpConnection  *GetSpdyPreferredConn(nsConnectionEntry *ent);
     nsDataHashtable<nsCStringHashKey, nsConnectionEntry *>   mSpdyPreferredHash;
     nsConnectionEntry *LookupConnectionEntry(nsHttpConnectionInfo *ci,
                                              nsHttpConnection *conn,
@@ -420,17 +389,16 @@ private:
 
     // message handlers
     void OnMsgShutdown             (PRInt32, void *);
     void OnMsgNewTransaction       (PRInt32, void *);
     void OnMsgReschedTransaction   (PRInt32, void *);
     void OnMsgCancelTransaction    (PRInt32, void *);
     void OnMsgProcessPendingQ      (PRInt32, void *);
     void OnMsgPruneDeadConnections (PRInt32, void *);
-    void OnMsgSpeculativeConnect   (PRInt32, void *);
     void OnMsgReclaimConnection    (PRInt32, void *);
     void OnMsgUpdateParam          (PRInt32, void *);
     void OnMsgClosePersistentConnections (PRInt32, void *);
 
     // Total number of active connections in all of the ConnectionEntry objects
     // that are accessed from mCT connection table.
     PRUint16 mNumActiveConns;
     // Total number of idle connections in all of the ConnectionEntry objects
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -176,23 +176,16 @@ public:
         return mConnMgr->ProcessPendingQ(cinfo);
     }
 
     nsresult GetSocketThreadTarget(nsIEventTarget **target)
     {
         return mConnMgr->GetSocketThreadTarget(target);
     }
 
-    nsresult SpeculativeConnect(nsHttpConnectionInfo *ci,
-                                nsIInterfaceRequestor *callbacks,
-                                nsIEventTarget *target)
-    {
-        return mConnMgr->SpeculativeConnect(ci, callbacks, target);
-    }
-
     // for anything that wants to know if we're in private browsing mode.
     bool InPrivateBrowsingMode();
 
     //
     // The HTTP handler caches pointers to specific XPCOM services, and
     // provides the following helper routines for accessing those services:
     //
     nsresult GetStreamConverterService(nsIStreamConverterService **);