bug 973207 - revert 905460 for nightly crashes r=backout
authorPatrick McManus <mcmanus@ducksong.com>
Mon, 17 Feb 2014 13:53:25 -0500
changeset 169133 4f9f58d41eac
parent 169132 fefba9d06e03
child 169170 6b6450d3fbf0
child 169175 48cd98deecd7
push id26233
push userphilringnalda@gmail.com
push date2014-02-17 23:08 +0000
treeherdermozilla-central@4f9f58d41eac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs973207, 905460
milestone30.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 973207 - revert 905460 for nightly crashes r=backout
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnectionInfo.cpp
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsHttpPipeline.cpp
netwerk/protocol/http/nsHttpPipeline.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -75,22 +75,22 @@ nsHttpConnection::nsHttpConnection()
     , mPriority(nsISupportsPriority::PRIORITY_NORMAL)
     , mReportedSpdy(false)
     , mEverUsedSpdy(false)
     , mLastHttpResponseVersion(NS_HTTP_VERSION_1_1)
     , mTransactionCaps(0)
     , mResponseTimeoutEnabled(false)
     , mTCPKeepaliveConfig(kTCPKeepaliveDisabled)
 {
-    LOG(("Creating nsHttpConnection @%p\n", this));
+    LOG(("Creating nsHttpConnection @%x\n", this));
 }
 
 nsHttpConnection::~nsHttpConnection()
 {
-    LOG(("Destroying nsHttpConnection @%p\n", this));
+    LOG(("Destroying nsHttpConnection @%x\n", this));
 
     ReportDataUsage(false);
     if (!mEverUsedSpdy) {
         LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n",
              this, mHttp1xTransactionCount));
         Telemetry::Accumulate(Telemetry::HTTP_REQUEST_PER_CONN,
                               mHttp1xTransactionCount);
     }
@@ -308,17 +308,17 @@ npnComplete:
 
 // called on the socket thread
 nsresult
 nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri)
 {
     nsresult rv;
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    LOG(("nsHttpConnection::Activate [this=%p trans=%p caps=%x]\n",
+    LOG(("nsHttpConnection::Activate [this=%p trans=%x caps=%x]\n",
          this, trans, caps));
 
     if (!trans->IsNullTransaction())
         mExperienced = true;
 
     mTransactionCaps = caps;
     mPriority = pri;
     if (mTransaction && mUsingSpdyVersion)
@@ -1242,17 +1242,17 @@ nsHttpConnection::EndIdleMonitoring()
 
 //-----------------------------------------------------------------------------
 // nsHttpConnection <private>
 //-----------------------------------------------------------------------------
 
 void
 nsHttpConnection::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
 {
-    LOG(("nsHttpConnection::CloseTransaction[this=%p trans=%p reason=%x]\n",
+    LOG(("nsHttpConnection::CloseTransaction[this=%p trans=%x reason=%x]\n",
         this, trans, reason));
 
     MOZ_ASSERT(trans == mTransaction, "wrong transaction");
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
 
     if (mCurrentBytesRead > mMaxBytesRead)
         mMaxBytesRead = mCurrentBytesRead;
 
@@ -1804,17 +1804,16 @@ nsHttpConnection::OnInputStreamReady(nsI
         // The only read event that is protocol compliant for an idle connection
         // is an EOF, which we check for with CanReuse(). If the data is
         // something else then just ignore it and suspend checking for EOF -
         // our normal timers or protocol stack are the place to deal with
         // any exception logic.
 
         if (!CanReuse()) {
             LOG(("Server initiated close of idle conn %p\n", this));
-            // CloseIdleConnection may delete "this" - return immediately
             gHttpHandler->ConnMgr()->CloseIdleConnection(this);
             return NS_OK;
         }
 
         LOG(("Input data on idle conn %p, but not closing yet\n", this));
         return NS_OK;
     }
 
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
@@ -22,17 +22,17 @@ namespace net {
 
 nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &host, int32_t port,
                                            nsProxyInfo* proxyInfo,
                                            bool usingSSL)
     : mProxyInfo(proxyInfo)
     , mUsingSSL(usingSSL)
     , mUsingConnect(false)
 {
-    LOG(("Creating nsHttpConnectionInfo @%p\n", this));
+    LOG(("Creating nsHttpConnectionInfo @%x\n", this));
 
     mUsingHttpProxy = (proxyInfo && proxyInfo->IsHTTP());
 
     if (mUsingHttpProxy) {
         mUsingConnect = mUsingSSL;  // SSL always uses CONNECT
         uint32_t resolveFlags = 0;
         if (NS_SUCCEEDED(mProxyInfo->GetResolveFlags(&resolveFlags)) &&
             resolveFlags & nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL) {
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -36,36 +36,55 @@ extern PRThread *gSocketThread;
 
 namespace mozilla {
 namespace net {
 
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS1(nsHttpConnectionMgr, nsIObserver)
 
+static void
+InsertTransactionSorted(nsTArray<nsHttpTransaction*> &pendingQ, nsHttpTransaction *trans)
+{
+    // insert into queue with smallest valued number first.  search in reverse
+    // order under the assumption that many of the existing transactions will
+    // have the same priority (usually 0).
+
+    for (int32_t i=pendingQ.Length()-1; i>=0; --i) {
+        nsHttpTransaction *t = pendingQ[i];
+        if (trans->Priority() >= t->Priority()) {
+            pendingQ.InsertElementAt(i+1, trans);
+            return;
+        }
+    }
+    pendingQ.InsertElementAt(0, trans);
+}
+
+//-----------------------------------------------------------------------------
+
 nsHttpConnectionMgr::nsHttpConnectionMgr()
     : mReentrantMonitor("nsHttpConnectionMgr.mReentrantMonitor")
     , mMaxConns(0)
     , mMaxPersistConnsPerHost(0)
     , mMaxPersistConnsPerProxy(0)
     , mIsShuttingDown(false)
     , mNumActiveConns(0)
     , mNumIdleConns(0)
     , mNumSpdyActiveConns(0)
     , mNumHalfOpenConns(0)
     , mTimeOfNextWakeUp(UINT64_MAX)
     , mTimeoutTickArmed(false)
     , mTimeoutTickNext(1)
 {
-    LOG(("Creating nsHttpConnectionMgr @%p\n", this));
+    LOG(("Creating nsHttpConnectionMgr @%x\n", this));
 }
 
 nsHttpConnectionMgr::~nsHttpConnectionMgr()
 {
-    LOG(("Destroying nsHttpConnectionMgr @%p\n", this));
+    LOG(("Destroying nsHttpConnectionMgr @%x\n", this));
     if (mTimeoutTick)
         mTimeoutTick->Cancel();
 }
 
 nsresult
 nsHttpConnectionMgr::EnsureSocketThreadTarget()
 {
     nsresult rv;
@@ -153,17 +172,18 @@ nsHttpConnectionMgr::PostEvent(nsConnEve
     EnsureSocketThreadTarget();
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     nsresult rv;
     if (!mSocketThreadTarget) {
         NS_WARNING("cannot post event if not initialized");
         rv = NS_ERROR_NOT_INITIALIZED;
-    } else {
+    }
+    else {
         nsRefPtr<nsIRunnable> event = new nsConnEvent(this, handler, iparam, vparam);
         rv = mSocketThreadTarget->Dispatch(event, NS_DISPATCH_NORMAL);
     }
     return rv;
 }
 
 void
 nsHttpConnectionMgr::PruneDeadConnectionsAfter(uint32_t timeInSeconds)
@@ -229,87 +249,85 @@ nsHttpConnectionMgr::Observe(nsISupports
                              const char16_t *data)
 {
     LOG(("nsHttpConnectionMgr::Observe [topic=\"%s\"]\n", topic));
 
     if (0 == strcmp(topic, NS_TIMER_CALLBACK_TOPIC)) {
         nsCOMPtr<nsITimer> timer = do_QueryInterface(subject);
         if (timer == mTimer) {
             PruneDeadConnections();
-        } else if (timer == mTimeoutTick) {
+        }
+        else if (timer == mTimeoutTick) {
             TimeoutTick();
-        } else {
+        }
+        else {
             MOZ_ASSERT(false, "unexpected timer-callback");
             LOG(("Unexpected timer object\n"));
             return NS_ERROR_UNEXPECTED;
         }
     }
 
     return NS_OK;
 }
 
 
 //-----------------------------------------------------------------------------
 
 nsresult
-nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *aTrans, int32_t priority)
+nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *trans, int32_t priority)
 {
-    LOG(("nsHttpConnectionMgr::AddTransaction [trans=%p %d]\n", aTrans, priority));
-
-    nsRefPtr<nsHttpTransaction> trans(aTrans);
+    LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", trans, priority));
+
+    NS_ADDREF(trans);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgNewTransaction, priority, trans);
-    if (NS_SUCCEEDED(rv)) {
-        trans.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(trans);
     return rv;
 }
 
 nsresult
-nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *aTrans, int32_t priority)
+nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *trans, int32_t priority)
 {
-    LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%p %d]\n", aTrans, priority));
-
-    nsRefPtr<nsHttpTransaction> trans(aTrans);
+    LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%x %d]\n", trans, priority));
+
+    NS_ADDREF(trans);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReschedTransaction, priority, trans);
-    if (NS_SUCCEEDED(rv)) {
-        trans.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(trans);
     return rv;
 }
 
 nsresult
-nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *aTrans, nsresult reason)
+nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *trans, nsresult reason)
 {
-    LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%p reason=%x]\n", aTrans, reason));
-
-    nsRefPtr<nsHttpTransaction> trans(aTrans);
+    LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%x reason=%x]\n", trans, reason));
+
+    NS_ADDREF(trans);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgCancelTransaction,
                             static_cast<int32_t>(reason), trans);
-    if (NS_SUCCEEDED(rv)) {
-        trans.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(trans);
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::PruneDeadConnections()
 {
     return PostEvent(&nsHttpConnectionMgr::OnMsgPruneDeadConnections);
 }
 
 nsresult
 nsHttpConnectionMgr::DoShiftReloadConnectionCleanup(nsHttpConnectionInfo *aCI)
 {
     nsRefPtr<nsHttpConnectionInfo> connInfo(aCI);
 
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgDoShiftReloadConnectionCleanup,
                             0, connInfo);
-    if (NS_SUCCEEDED(rv)) {
+    if (NS_SUCCEEDED(rv))
         connInfo.forget();
-    }
     return rv;
 }
 
 class SpeculativeConnectArgs
 {
 public:
     SpeculativeConnectArgs() { mOverridesOK = false; }
     virtual ~SpeculativeConnectArgs() {}
@@ -373,42 +391,40 @@ nsHttpConnectionMgr::SpeculativeConnect(
             &args->mParallelSpeculativeConnectLimit);
         overrider->GetIgnoreIdle(&args->mIgnoreIdle);
         overrider->GetIgnorePossibleSpdyConnections(
             &args->mIgnorePossibleSpdyConnections);
     }
 
     nsresult rv =
         PostEvent(&nsHttpConnectionMgr::OnMsgSpeculativeConnect, 0, args);
-    if (NS_SUCCEEDED(rv)) {
+    if (NS_SUCCEEDED(rv))
         args.forget();
-    }
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
 {
     EnsureSocketThreadTarget();
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     NS_IF_ADDREF(*target = mSocketThreadTarget);
     return NS_OK;
 }
 
 nsresult
-nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *aConn)
+nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *conn)
 {
-    LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%p]\n", aConn));
-
-    nsRefPtr<nsHttpConnection> conn(aConn);
+    LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", conn));
+
+    NS_ADDREF(conn);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReclaimConnection, 0, conn);
-    if (NS_SUCCEEDED(rv)) {
-        conn.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(conn);
     return rv;
 }
 
 // A structure used to marshall 2 pointers across the various necessary
 // threads to complete an HTTP upgrade.
 class nsCompleteUpgradeData
 {
 public:
@@ -423,40 +439,38 @@ nsCompleteUpgradeData(nsAHttpConnection 
 nsresult
 nsHttpConnectionMgr::CompleteUpgrade(nsAHttpConnection *aConn,
                                      nsIHttpUpgradeListener *aUpgradeListener)
 {
     nsCompleteUpgradeData *data =
         new nsCompleteUpgradeData(aConn, aUpgradeListener);
     nsresult rv;
     rv = PostEvent(&nsHttpConnectionMgr::OnMsgCompleteUpgrade, 0, data);
-    if (NS_FAILED(rv)) {
+    if (NS_FAILED(rv))
         delete data;
-    }
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value)
 {
     uint32_t param = (uint32_t(name) << 16) | uint32_t(value);
     return PostEvent(&nsHttpConnectionMgr::OnMsgUpdateParam, 0,
                      (void *)(uintptr_t) param);
 }
 
 nsresult
-nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *aCI)
+nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *ci)
 {
-    LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", aCI->HashKey().get()));
-
-    nsRefPtr<nsHttpConnectionInfo> ci(aCI);
+    LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get()));
+
+    NS_ADDREF(ci);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci);
-    if (NS_SUCCEEDED(rv)) {
-        ci.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(ci);
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::ProcessPendingQ()
 {
     LOG(("nsHttpConnectionMgr::ProcessPendingQ [All CI]\n"));
     return PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, nullptr);
@@ -474,19 +488,18 @@ nsresult
 nsHttpConnectionMgr::UpdateRequestTokenBucket(EventTokenBucket *aBucket)
 {
     nsRefPtr<EventTokenBucket> bucket(aBucket);
 
     // Call From main thread when a new EventTokenBucket has been made in order
     // to post the new value to the socket thread.
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgUpdateRequestTokenBucket,
                             0, bucket.get());
-    if (NS_SUCCEEDED(rv)) {
+    if (NS_SUCCEEDED(rv))
         bucket.forget();
-    }
     return rv;
 }
 
 // Given a nsHttpConnectionInfo find the connection entry object that
 // contains either the nshttpconnection or nshttptransaction parameter.
 // Normally this is done by the hashkey lookup of connectioninfo,
 // but if spdy coalescing is in play it might be found in a redirected
 // entry
@@ -530,29 +543,28 @@ nsHttpConnectionMgr::LookupConnectionEnt
 }
 
 nsresult
 nsHttpConnectionMgr::CloseIdleConnection(nsHttpConnection *conn)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::CloseIdleConnection %p conn=%p",
          this, conn));
-    nsRefPtr<nsHttpConnection> deleteProtector(conn);
 
     if (!conn->ConnectionInfo())
         return NS_ERROR_UNEXPECTED;
 
     nsConnectionEntry *ent = LookupConnectionEntry(conn->ConnectionInfo(),
                                                    conn, nullptr);
 
     if (!ent || !ent->mIdleConns.RemoveElement(conn))
         return NS_ERROR_UNEXPECTED;
 
     conn->Close(NS_ERROR_ABORT);
-    conn = nullptr;
+    NS_RELEASE(conn);
     mNumIdleConns--;
     ConditionallyStopPruneDeadConnectionsTimer();
     return NS_OK;
 }
 
 // This function lets a connection, after completing the NPN phase,
 // report whether or not it is using spdy through the usingSpdy
 // argument. It would not be necessary if NPN were driven out of
@@ -836,20 +848,20 @@ nsHttpConnectionMgr::PurgeExcessIdleConn
 {
     nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
 
     while (self->mNumIdleConns + self->mNumActiveConns + 1 >= self->mMaxConns) {
         if (!ent->mIdleConns.Length()) {
             // There are no idle conns left in this connection entry
             return PL_DHASH_NEXT;
         }
-        nsRefPtr<nsHttpConnection> conn(ent->mIdleConns[0]);
+        nsHttpConnection *conn = ent->mIdleConns[0];
         ent->mIdleConns.RemoveElementAt(0);
         conn->Close(NS_ERROR_ABORT);
-        conn = nullptr;
+        NS_RELEASE(conn);
         self->mNumIdleConns--;
         self->ConditionallyStopPruneDeadConnectionsTimer();
     }
     return PL_DHASH_STOP;
 }
 
 // If the global number of connections is preventing the opening of
 // new connections to a host without idle connections, then
@@ -885,38 +897,39 @@ nsHttpConnectionMgr::PruneDeadConnection
 
     LOG(("  pruning [ci=%s]\n", ent->mConnInfo->HashKey().get()));
 
     // Find out how long it will take for next idle connection to not be reusable
     // anymore.
     uint32_t timeToNextExpire = UINT32_MAX;
     int32_t count = ent->mIdleConns.Length();
     if (count > 0) {
-        for (int32_t i = count - 1; i >= 0; --i) {
-            if (!ent->mIdleConns[i]->CanReuse()) {
-                nsRefPtr<nsHttpConnection> conn(ent->mIdleConns[i]);
+        for (int32_t i=count-1; i>=0; --i) {
+            nsHttpConnection *conn = ent->mIdleConns[i];
+            if (!conn->CanReuse()) {
                 ent->mIdleConns.RemoveElementAt(i);
                 conn->Close(NS_ERROR_ABORT);
+                NS_RELEASE(conn);
                 self->mNumIdleConns--;
             } else {
-                timeToNextExpire = std::min(timeToNextExpire,
-                                            ent->mIdleConns[i]->TimeToLive());
+                timeToNextExpire = std::min(timeToNextExpire, conn->TimeToLive());
             }
         }
     }
 
     if (ent->mUsingSpdy) {
         for (uint32_t index = 0; index < ent->mActiveConns.Length(); ++index) {
             nsHttpConnection *conn = ent->mActiveConns[index];
             if (conn->UsingSpdy()) {
                 if (!conn->CanReuse()) {
                     // marking it dont reuse will create an active tear down if
                     // the spdy session is idle.
                     conn->DontReuse();
-                } else {
+                }
+                else {
                     timeToNextExpire = std::min(timeToNextExpire,
                                               conn->TimeToLive());
                 }
             }
         }
     }
 
     // If time to next expire found is shorter than time to next wake-up, we need to
@@ -962,42 +975,52 @@ nsHttpConnectionMgr::PruneDeadConnection
 
 PLDHashOperator
 nsHttpConnectionMgr::ShutdownPassCB(const nsACString &key,
                                     nsAutoPtr<nsConnectionEntry> &ent,
                                     void *closure)
 {
     nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
 
-    // close all active connections and release list references
+    nsHttpTransaction *trans;
+    nsHttpConnection *conn;
+
+    // close all active connections
     while (ent->mActiveConns.Length()) {
-        nsRefPtr<nsHttpConnection> conn(ent->mActiveConns[0]);
+        conn = ent->mActiveConns[0];
 
         ent->mActiveConns.RemoveElementAt(0);
         self->DecrementActiveConnCount(conn);
 
         conn->Close(NS_ERROR_ABORT);
+        NS_RELEASE(conn);
     }
 
-    // close all idle connections and release list references
+    // close all idle connections
     while (ent->mIdleConns.Length()) {
-        nsRefPtr<nsHttpConnection> conn(ent->mIdleConns[0]);
+        conn = ent->mIdleConns[0];
+
         ent->mIdleConns.RemoveElementAt(0);
         self->mNumIdleConns--;
+
         conn->Close(NS_ERROR_ABORT);
+        NS_RELEASE(conn);
     }
     // If all idle connections are removed,
     // we can stop pruning dead connections.
     self->ConditionallyStopPruneDeadConnectionsTimer();
 
-    // close all pending transactions and release list references
+    // close all pending transactions
     while (ent->mPendingQ.Length()) {
-        nsRefPtr<nsHttpTransaction> trans(ent->mPendingQ[0]);
+        trans = ent->mPendingQ[0];
+
         ent->mPendingQ.RemoveElementAt(0);
+
         trans->Close(NS_ERROR_ABORT);
+        NS_RELEASE(trans);
     }
 
     // close all half open tcp connections
     for (int32_t i = ((int32_t) ent->mHalfOpens.Length()) - 1; i >= 0; i--)
         ent->mHalfOpens[i]->Abandon();
 
     return PL_DHASH_REMOVE;
 }
@@ -1042,16 +1065,17 @@ nsHttpConnectionMgr::ProcessPendingQForE
             if (NS_SUCCEEDED(rv))
                 LOG(("  dispatching pending transaction...\n"));
             else
                 LOG(("  removing pending transaction based on "
                      "TryDispatchTransaction returning hard error %x\n", rv));
 
             if (ent->mPendingQ.RemoveElement(trans)) {
                 dispatchedSuccessfully = true;
+                NS_RELEASE(trans);
                 continue; // dont ++i as we just made the array shorter
             }
 
             LOG(("  transaction not found in pending queue\n"));
         }
 
         if (dispatchedSuccessfully && !considerAll)
             break;
@@ -1234,20 +1258,21 @@ nsHttpConnectionMgr::AtActiveConnectionL
 }
 
 void
 nsHttpConnectionMgr::ClosePersistentConnections(nsConnectionEntry *ent)
 {
     LOG(("nsHttpConnectionMgr::ClosePersistentConnections [ci=%s]\n",
          ent->mConnInfo->HashKey().get()));
     while (ent->mIdleConns.Length()) {
-        nsRefPtr<nsHttpConnection> conn(ent->mIdleConns[0]);
+        nsHttpConnection *conn = ent->mIdleConns[0];
         ent->mIdleConns.RemoveElementAt(0);
         mNumIdleConns--;
         conn->Close(NS_ERROR_ABORT);
+        NS_RELEASE(conn);
     }
 
     int32_t activeCount = ent->mActiveConns.Length();
     for (int32_t i=0; i < activeCount; i++)
         ent->mActiveConns[i]->DontReuse();
 }
 
 PLDHashOperator
@@ -1450,19 +1475,18 @@ nsHttpConnectionMgr::AddToShortestPipeli
         }
     }
 
     if (!bestConn)
         return false;
 
     activeTrans = bestConn->Transaction();
     nsresult rv = activeTrans->AddTransaction(trans);
-    if (NS_FAILED(rv)) {
+    if (NS_FAILED(rv))
         return false;
-    }
 
     LOG(("   scheduling trans %p on pipeline at position %d\n",
          trans, trans->PipelinePosition()));
 
     if ((ent->PipelineState() == PS_YELLOW) && (trans->PipelinePosition() > 1))
         ent->SetYellowConnection(bestConn);
 
     if (!trans->GetPendingTime().IsNull()) {
@@ -1558,17 +1582,17 @@ nsHttpConnectionMgr::TryDispatchTransact
     // step 0
     // look for existing spdy connection - that's always best because it is
     // essentially pipelining without head of line blocking
 
     if (!(caps & NS_HTTP_DISALLOW_SPDY) && gHttpHandler->IsSpdyEnabled()) {
         nsRefPtr<nsHttpConnection> conn = GetSpdyPreferredConn(ent);
         if (conn) {
             if ((caps & NS_HTTP_ALLOW_KEEPALIVE) || !conn->IsExperienced()) {
-                LOG(("   dispatch to spdy: [conn=%p]\n", conn.get()));
+                LOG(("   dispatch to spdy: [conn=%x]\n", conn.get()));
                 trans->RemoveDispatchedAsBlocking();  /* just in case */
                 DispatchTransaction(ent, trans, conn);
                 return NS_OK;
             }
             unusedSpdyPersistentConnection = conn;
         }
     }
 
@@ -1584,17 +1608,18 @@ nsHttpConnectionMgr::TryDispatchTransact
                 if (NS_SUCCEEDED(loadGroupCI->GetBlockingTransactionCount(&blockers)) &&
                     blockers) {
                     // need to wait for blockers to clear
                     LOG(("   blocked by load group: [blockers=%d]\n", blockers));
                     return NS_ERROR_NOT_AVAILABLE;
                 }
             }
         }
-    } else {
+    }
+    else {
         // Mark the transaction and its load group as blocking right now to prevent
         // other transactions from being reordered in the queue due to slow syns.
         trans->DispatchedAsBlocking();
     }
 
     // step 1
     // If connection pressure, then we want to favor pipelining of any kind
     if (IsUnderPressure(ent, classification) && !attemptedOptimisticPipeline) {
@@ -1626,25 +1651,28 @@ nsHttpConnectionMgr::TryDispatchTransact
     // step 2
     // consider an idle persistent connection
     if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
         nsRefPtr<nsHttpConnection> conn;
         while (!conn && (ent->mIdleConns.Length() > 0)) {
             conn = ent->mIdleConns[0];
             ent->mIdleConns.RemoveElementAt(0);
             mNumIdleConns--;
+            nsHttpConnection *temp = conn;
+            NS_RELEASE(temp);
 
             // we check if the connection can be reused before even checking if
             // it is a "matching" connection.
             if (!conn->CanReuse()) {
-                LOG(("   dropping stale connection: [conn=%p]\n", conn.get()));
+                LOG(("   dropping stale connection: [conn=%x]\n", conn.get()));
                 conn->Close(NS_ERROR_ABORT);
                 conn = nullptr;
-            } else {
-                LOG(("   reusing connection [conn=%p]\n", conn.get()));
+            }
+            else {
+                LOG(("   reusing connection [conn=%x]\n", conn.get()));
                 conn->EndIdleMonitoring();
             }
 
             // If there are no idle connections left at all, we need to make
             // sure that we are not pruning dead connections anymore.
             ConditionallyStopPruneDeadConnectionsTimer();
         }
         if (conn) {
@@ -1709,17 +1737,17 @@ nsHttpConnectionMgr::DispatchTransaction
                                          nsHttpTransaction *trans,
                                          nsHttpConnection *conn)
 {
     uint32_t caps = trans->Caps();
     int32_t priority = trans->Priority();
     nsresult rv;
 
     LOG(("nsHttpConnectionMgr::DispatchTransaction "
-         "[ci=%s trans=%p caps=%x conn=%p priority=%d]\n",
+         "[ci=%s trans=%x caps=%x conn=%x priority=%d]\n",
          ent->mConnInfo->HashKey().get(), trans, caps, conn, priority));
 
     // It is possible for a rate-paced transaction to be dispatched independent
     // of the token bucket when the amount of parallelization has changed or
     // when a muxed connection (e.g. spdy or pipelines) becomes available.
     trans->CancelPacing(NS_OK);
 
     if (conn->UsingSpdy()) {
@@ -1769,17 +1797,17 @@ nsHttpConnectionMgr::DispatchAbstractTra
                                                  nsAHttpTransaction *aTrans,
                                                  uint32_t caps,
                                                  nsHttpConnection *conn,
                                                  int32_t priority)
 {
     MOZ_ASSERT(!conn->UsingSpdy(),
                "Spdy Must Not Use DispatchAbstractTransaction");
     LOG(("nsHttpConnectionMgr::DispatchAbstractTransaction "
-         "[ci=%s trans=%p caps=%x conn=%p]\n",
+         "[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. Make an exception
        for CLASS_SOLO as that connection will never pipeline until it goes
        quiescent */
 
@@ -1787,40 +1815,42 @@ nsHttpConnectionMgr::DispatchAbstractTra
     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 {
+    }
+    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.
     transaction->SetConnection(handle);
 
     rv = conn->Activate(transaction, caps, priority);
     if (NS_FAILED(rv)) {
         LOG(("  conn->Activate failed [rv=%x]\n", rv));
-        nsRefPtr<nsHttpConnection> deleteProtector(conn);
         ent->mActiveConns.RemoveElement(conn);
         if (conn == ent->mYellowConnection)
             ent->OnYellowComplete();
         DecrementActiveConnCount(conn);
         ConditionallyStopTimeoutTick();
 
         // sever back references to connection, and do so without triggering
         // a call to ReclaimConnection ;-)
         transaction->SetConnection(nullptr);
-        handle->Reset();
+        NS_RELEASE(handle->mConn);
+        // destroy the connection
+        NS_RELEASE(conn);
     }
 
     // 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;
@@ -1836,17 +1866,17 @@ nsHttpConnectionMgr::BuildPipeline(nsCon
     /* form a pipeline here even if nothing is pending so that we
        can stream-feed it as new transactions arrive */
 
     /* the first transaction can go in unconditionally - 1 transaction
        on a nsHttpPipeline object is not a real HTTP pipeline */
 
     nsRefPtr<nsHttpPipeline> pipeline = new nsHttpPipeline();
     pipeline->AddTransaction(firstTrans);
-    pipeline.forget(result);
+    NS_ADDREF(*result = pipeline);
     return NS_OK;
 }
 
 void
 nsHttpConnectionMgr::ReportProxyTelemetry(nsConnectionEntry *ent)
 {
     enum { PROXY_NONE = 1, PROXY_HTTP = 2, PROXY_SOCKS = 3 };
 
@@ -1917,30 +1947,33 @@ nsHttpConnectionMgr::ProcessNewTransacti
     if (NS_SUCCEEDED(rv)) {
         LOG(("  ProcessNewTransaction Dispatch Immediately trans=%p\n", trans));
         return rv;
     }
 
     if (rv == NS_ERROR_NOT_AVAILABLE) {
         LOG(("  adding transaction to pending queue "
              "[trans=%p pending-count=%u]\n",
-             trans, ent->mPendingQ.Length() + 1));
+             trans, ent->mPendingQ.Length()+1));
         // put this transaction on the pending queue...
         InsertTransactionSorted(ent->mPendingQ, trans);
+        NS_ADDREF(trans);
         return NS_OK;
     }
 
     LOG(("  ProcessNewTransaction Hard Error trans=%p rv=%x\n", trans, rv));
     return rv;
 }
 
+
 void
 nsHttpConnectionMgr::AddActiveConn(nsHttpConnection *conn,
                                    nsConnectionEntry *ent)
 {
+    NS_ADDREF(conn);
     ent->mActiveConns.AppendElement(conn);
     mNumActiveConns++;
     ActivateTimeoutTick();
 }
 
 void
 nsHttpConnectionMgr::DecrementActiveConnCount(nsHttpConnection *conn)
 {
@@ -1990,17 +2023,17 @@ nsHttpConnectionMgr::CreateTransport(nsC
 
 void
 nsHttpConnectionMgr::ProcessSpdyPendingQ(nsConnectionEntry *ent)
 {
     nsHttpConnection *conn = GetSpdyPreferredConn(ent);
     if (!conn || !conn->CanDirectlyActivate())
         return;
 
-    nsTArray<nsRefPtr<nsHttpTransaction> > leftovers;
+    nsTArray<nsHttpTransaction*> leftovers;
     uint32_t index;
 
     // Dispatch all the transactions we can
     for (index = 0;
          index < ent->mPendingQ.Length() && conn->CanDirectlyActivate();
          ++index) {
         nsHttpTransaction *trans = ent->mPendingQ[index];
 
@@ -2011,25 +2044,27 @@ nsHttpConnectionMgr::ProcessSpdyPendingQ
         }
 
         nsresult rv = DispatchTransaction(ent, trans, conn);
         if (NS_FAILED(rv)) {
             // this cannot happen, but if due to some bug it does then
             // close the transaction
             MOZ_ASSERT(false, "Dispatch SPDY Transaction");
             LOG(("ProcessSpdyPendingQ Dispatch Transaction failed trans=%p\n",
-                 trans));
+                    trans));
             trans->Close(rv);
         }
+        NS_RELEASE(trans);
     }
 
     // Slurp up the rest of the pending queue into our leftovers bucket (we
     // might have some left if conn->CanDirectlyActivate returned false)
     for (; index < ent->mPendingQ.Length(); ++index) {
-        leftovers.AppendElement(ent->mPendingQ[index]);
+        nsHttpTransaction *trans = ent->mPendingQ[index];
+        leftovers.AppendElement(trans);
     }
 
     // Put the leftovers back in the pending queue and get rid of the
     // transactions we dispatched
     leftovers.SwapElements(ent->mPendingQ);
     leftovers.Clear();
 }
 
@@ -2115,74 +2150,75 @@ nsHttpConnectionMgr::OnMsgShutdownConfir
     *shutdown = true;
 }
 
 void
 nsHttpConnectionMgr::OnMsgNewTransaction(int32_t priority, void *param)
 {
     LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
 
-    nsRefPtr<nsHttpTransaction> trans =
-        dont_AddRef(static_cast<nsHttpTransaction *>(param));
+    nsHttpTransaction *trans = (nsHttpTransaction *) param;
     trans->SetPriority(priority);
     nsresult rv = ProcessNewTransaction(trans);
-    if (NS_FAILED(rv)) {
+    if (NS_FAILED(rv))
         trans->Close(rv); // for whatever its worth
-    }
+    NS_RELEASE(trans);
 }
 
 void
 nsHttpConnectionMgr::OnMsgReschedTransaction(int32_t priority, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::OnMsgReschedTransaction [trans=%p]\n", param));
 
-    nsRefPtr<nsHttpTransaction> trans =
-        dont_AddRef(static_cast<nsHttpTransaction *>(param));
+    nsHttpTransaction *trans = (nsHttpTransaction *) param;
     trans->SetPriority(priority);
 
     nsConnectionEntry *ent = LookupConnectionEntry(trans->ConnectionInfo(),
                                                    nullptr, trans);
 
     if (ent) {
         int32_t index = ent->mPendingQ.IndexOf(trans);
         if (index >= 0) {
             ent->mPendingQ.RemoveElementAt(index);
             InsertTransactionSorted(ent->mPendingQ, trans);
         }
     }
+
+    NS_RELEASE(trans);
 }
 
 void
 nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param));
 
     nsresult closeCode = static_cast<nsresult>(reason);
-    nsRefPtr<nsHttpTransaction> trans =
-        dont_AddRef(static_cast<nsHttpTransaction *>(param));
+    nsHttpTransaction *trans = (nsHttpTransaction *) param;
     //
     // if the transaction owns a connection and the transaction is not done,
     // then ask the connection to close the transaction.  otherwise, close the
     // transaction directly (removing it from the pending queue first).
     //
     nsAHttpConnection *conn = trans->Connection();
     if (conn && !trans->IsDone()) {
         conn->CloseTransaction(trans, closeCode);
     } else {
         nsConnectionEntry *ent =
             LookupConnectionEntry(trans->ConnectionInfo(), nullptr, trans);
 
         if (ent) {
             int32_t index = ent->mPendingQ.IndexOf(trans);
             if (index >= 0) {
                 LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]"
-                     " found in pending queue\n", trans.get()));
+                     " found in pending queue\n", trans));
                 ent->mPendingQ.RemoveElementAt(index);
+                nsHttpTransaction *temp = trans;
+                NS_RELEASE(temp); // b/c NS_RELEASE nulls its argument!
             }
         }
         trans->Close(closeCode);
 
         // Cancel is a pretty strong signal that things might be hanging
         // so we want to cancel any null transactions related to this connection
         // entry. They are just optimizations, but they aren't hooked up to
         // anything that might get canceled from the rest of gecko, so best
@@ -2191,29 +2227,29 @@ nsHttpConnectionMgr::OnMsgCancelTransact
         for (uint32_t index = 0;
              ent && (index < ent->mActiveConns.Length());
              ++index) {
             nsHttpConnection *activeConn = ent->mActiveConns[index];
             nsAHttpTransaction *liveTransaction = activeConn->Transaction();
             if (liveTransaction && liveTransaction->IsNullTransaction()) {
                 LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p] "
                      "also canceling Null Transaction %p on conn %p\n",
-                     trans.get(), liveTransaction, activeConn));
+                     trans, liveTransaction, activeConn));
                 activeConn->CloseTransaction(liveTransaction, closeCode);
             }
         }
     }
+    NS_RELEASE(trans);
 }
 
 void
 nsHttpConnectionMgr::OnMsgProcessPendingQ(int32_t, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    nsRefPtr<nsHttpConnectionInfo> ci =
-        dont_AddRef(static_cast<nsHttpConnectionInfo *>(param));
+    nsHttpConnectionInfo *ci = (nsHttpConnectionInfo *) param;
 
     if (!ci) {
         LOG(("nsHttpConnectionMgr::OnMsgProcessPendingQ [ci=nullptr]\n"));
         // Try and dispatch everything
         mCT.Enumerate(ProcessAllTransactionsCB, this);
         return;
     }
 
@@ -2222,16 +2258,18 @@ nsHttpConnectionMgr::OnMsgProcessPending
 
     // start by processing the queue identified by the given connection info.
     nsConnectionEntry *ent = mCT.Get(ci->HashKey());
     if (!(ent && ProcessPendingQForEntry(ent, false))) {
         // if we reach here, it means that we couldn't dispatch a transaction
         // for the specified connection info.  walk the connection table...
         mCT.Enumerate(ProcessOneTransactionCB, this);
     }
+
+    NS_RELEASE(ci);
 }
 
 void
 nsHttpConnectionMgr::OnMsgPruneDeadConnections(int32_t, void *)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::OnMsgPruneDeadConnections\n"));
 
@@ -2259,36 +2297,36 @@ nsHttpConnectionMgr::OnMsgDoShiftReloadC
 }
 
 void
 nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection [conn=%p]\n", param));
 
-    nsRefPtr<nsHttpConnection> conn =
-        dont_AddRef(static_cast<nsHttpConnection *>(param));
+    nsHttpConnection *conn = (nsHttpConnection *) param;
 
     //
     // 1) remove the connection from the active list
     // 2) if keep-alive, add connection to idle list
     // 3) post event to process the pending transaction queue
     //
 
     nsConnectionEntry *ent = LookupConnectionEntry(conn->ConnectionInfo(),
                                                    conn, nullptr);
-    nsRefPtr<nsHttpConnectionInfo> ci;
+    nsHttpConnectionInfo *ci = nullptr;
 
     if (!ent) {
         // this should never happen
         LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection ent == null\n"));
         MOZ_ASSERT(false, "no connection entry");
-        ci = conn->ConnectionInfo();
-    } else {
-        ci = ent->mConnInfo;
+        NS_ADDREF(ci = conn->ConnectionInfo());
+    }
+    else {
+        NS_ADDREF(ci = ent->mConnInfo);
 
         // If the connection is in the active list, remove that entry
         // and the reference held by the mActiveConns list.
         // This is never the final reference on conn as the event context
         // is also holding one that is released at the end of this function.
 
         if (ent->mUsingSpdy) {
             // Spdy connections aren't reused in the traditional HTTP way in
@@ -2298,17 +2336,18 @@ nsHttpConnectionMgr::OnMsgReclaimConnect
             // is really complete and is meant to be shut down and not
             // reused.
             conn->DontReuse();
         }
 
         if (ent->mActiveConns.RemoveElement(conn)) {
             if (conn == ent->mYellowConnection)
                 ent->OnYellowComplete();
-
+            nsHttpConnection *temp = conn;
+            NS_RELEASE(temp);
             DecrementActiveConnCount(conn);
             ConditionallyStopTimeoutTick();
         }
 
         if (conn->CanReuse()) {
             LOG(("  adding connection to idle list\n"));
             // Keep The idle connection list sorted with the connections that
             // have moved the largest data pipelines at the front because these
@@ -2319,33 +2358,36 @@ nsHttpConnectionMgr::OnMsgReclaimConnect
 
             uint32_t idx;
             for (idx = 0; idx < ent->mIdleConns.Length(); idx++) {
                 nsHttpConnection *idleConn = ent->mIdleConns[idx];
                 if (idleConn->MaxBytesRead() < conn->MaxBytesRead())
                     break;
             }
 
+            NS_ADDREF(conn);
             ent->mIdleConns.InsertElementAt(idx, conn);
             mNumIdleConns++;
             conn->BeginIdleMonitoring();
 
             // If the added connection was first idle connection or has shortest
             // time to live among the watched connections, pruning dead
             // connections needs to be done when it can't be reused anymore.
             uint32_t timeToLive = conn->TimeToLive();
             if(!mTimer || NowInSeconds() + timeToLive < mTimeOfNextWakeUp)
                 PruneDeadConnectionsAfter(timeToLive);
-        } else {
+        }
+        else {
             LOG(("  connection cannot be reused; closing connection\n"));
             conn->Close(NS_ERROR_ABORT);
         }
     }
 
-    OnMsgProcessPendingQ(0, ci.forget().get()); // releases |ci ref|
+    OnMsgProcessPendingQ(0, ci); // releases |ci|
+    NS_RELEASE(conn);
 }
 
 void
 nsHttpConnectionMgr::OnMsgCompleteUpgrade(int32_t, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     nsCompleteUpgradeData *data = (nsCompleteUpgradeData *) param;
     LOG(("nsHttpConnectionMgr::OnMsgCompleteUpgrade "
@@ -2398,16 +2440,18 @@ nsHttpConnectionMgr::OnMsgUpdateParam(in
     }
 }
 
 // nsHttpConnectionMgr::nsConnectionEntry
 nsHttpConnectionMgr::nsConnectionEntry::~nsConnectionEntry()
 {
     if (mSpdyPreferred)
         gHttpHandler->ConnMgr()->RemoveSpdyPreferredEnt(mCoalescingKey);
+
+    NS_RELEASE(mConnInfo);
 }
 
 void
 nsHttpConnectionMgr::OnMsgProcessFeedback(int32_t, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     nsHttpPipelineFeedback *fb = (nsHttpPipelineFeedback *)param;
 
@@ -2520,43 +2564,24 @@ nsHttpConnectionMgr::TimeoutTickCB(const
         }
     }
     if (ent->mHalfOpens.Length()) {
         self->mTimeoutTickNext = 1;
     }
     return PL_DHASH_NEXT;
 }
 
-void
-nsHttpConnectionMgr::
-InsertTransactionSorted(nsTArray<nsRefPtr<nsHttpTransaction> > &pendingQ,
-                        nsHttpTransaction *trans)
-{
-    // Insert into queue with smallest valued number first. Search in reverse
-    // order under the assumption that many of the existing transactions will
-    // have the same priority (usually 0).
-    // List holds a reference on all members of mPendingQ
-
-    for (int32_t i = pendingQ.Length() - 1; i >= 0; --i) {
-        nsHttpTransaction *t = pendingQ[i];
-        if (trans->Priority() >= t->Priority()) {
-            pendingQ.InsertElementAt(i + 1, trans);
-            return;
-        }
-    }
-    pendingQ.InsertElementAt(0, trans);
-}
-
 //-----------------------------------------------------------------------------
 // nsHttpConnectionMgr::nsConnectionHandle
 
 nsHttpConnectionMgr::nsConnectionHandle::~nsConnectionHandle()
 {
     if (mConn) {
         gHttpHandler->ReclaimConnection(mConn);
+        NS_RELEASE(mConn);
     }
 }
 
 NS_IMPL_ISUPPORTS0(nsHttpConnectionMgr::nsConnectionHandle)
 
 nsHttpConnectionMgr::nsConnectionEntry *
 nsHttpConnectionMgr::GetOrCreateConnectionEntry(nsHttpConnectionInfo *ci)
 {
@@ -2627,17 +2652,18 @@ nsHttpConnectionMgr::OnMsgSpeculativeCon
     }
 
     if (mNumHalfOpenConns < parallelSpeculativeConnectLimit &&
         ((ignoreIdle && (ent->mIdleConns.Length() < parallelSpeculativeConnectLimit)) ||
          !ent->mIdleConns.Length()) &&
         !RestrictConnections(ent, ignorePossibleSpdyConnections) &&
         !AtActiveConnectionLimit(ent, args->mTrans->Caps())) {
         CreateTransport(ent, args->mTrans, args->mTrans->Caps(), true);
-    } else {
+    }
+    else {
         LOG(("  Transport not created due to existing connection count\n"));
     }
 }
 
 bool
 nsHttpConnectionMgr::nsConnectionHandle::IsPersistent()
 {
     return mConn->IsPersistent();
@@ -2977,17 +3003,18 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
 
         if (NS_SUCCEEDED(mSocketTransport->GetPeerAddr(&peeraddr)))
             mEnt->RecordIPFamilyPreference(peeraddr.raw.family);
 
         // The nsHttpConnection object now owns these streams and sockets
         mStreamOut = nullptr;
         mStreamIn = nullptr;
         mSocketTransport = nullptr;
-    } else {
+    }
+    else {
         TimeDuration rtt = TimeStamp::Now() - mBackupSynStarted;
         rv = conn->Init(mEnt->mConnInfo,
                         gHttpHandler->ConnMgr()->mMaxRequestDelay,
                         mBackupTransport, mBackupStreamIn, mBackupStreamOut,
                         callbacks,
                         PR_MillisecondsToInterval(
                           static_cast<uint32_t>(rtt.ToMilliseconds())));
 
@@ -3010,21 +3037,22 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
     // from counter of actual connections used for checking limits.
     mHasConnected = true;
 
     // if this is still in the pending list, remove it and dispatch it
     index = mEnt->mPendingQ.IndexOf(mTransaction);
     if (index != -1) {
         MOZ_ASSERT(!mSpeculative,
                    "Speculative Half Open found mTranscation");
-        nsRefPtr<nsHttpTransaction> temp(mEnt->mPendingQ[index]);
+        nsRefPtr<nsHttpTransaction> temp = dont_AddRef(mEnt->mPendingQ[index]);
         mEnt->mPendingQ.RemoveElementAt(index);
         gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
         rv = gHttpHandler->ConnMgr()->DispatchTransaction(mEnt, temp, conn);
-    } else {
+    }
+    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);
         if (k5Sec < gHttpHandler->IdleTimeout())
             conn->SetIdleTimeout(k5Sec);
@@ -3049,17 +3077,18 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
                 new NullHttpTransaction(mEnt->mConnInfo,
                                         callbacks,
                                         mCaps & ~NS_HTTP_ALLOW_PIPELINING);
 
             gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
             conn->Classify(nsAHttpTransaction::CLASS_SOLO);
             rv = gHttpHandler->ConnMgr()->
                 DispatchAbstractTransaction(mEnt, trans, mCaps, conn, 0);
-        } else {
+        }
+        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(
                 0, conn.forget().get());
         }
@@ -3203,16 +3232,17 @@ nsConnectionEntry::nsConnectionEntry(nsH
     , mPipeliningPenalty(0)
     , mSpdyCWND(0)
     , mUsingSpdy(false)
     , mTestedSpdy(false)
     , mSpdyPreferred(false)
     , mPreferIPv4(false)
     , mPreferIPv6(false)
 {
+    NS_ADDREF(mConnInfo);
     if (gHttpHandler->GetPipelineAggressive()) {
         mGreenDepth = kPipelineUnlimited;
         mPipelineState = PS_GREEN;
     }
     mInitialGreenDepth = mGreenDepth;
     memset(mPipeliningClassPenalty, 0, sizeof(int16_t) * nsAHttpTransaction::CLASS_MAX);
 }
 
@@ -3328,17 +3358,18 @@ nsConnectionEntry::OnPipelineFeedbackInf
         mPipeliningPenalty = std::min(mPipeliningPenalty, kPenalty);
         mPipeliningClassPenalty[classification] =
           std::min(mPipeliningClassPenalty[classification], kPenalty);
 
         LOG(("Assessing red penalty to %s class %d for event %d. "
              "Penalty now %d, throttle[%d] = %d\n", mConnInfo->Host(),
              classification, info, mPipeliningPenalty, classification,
              mPipeliningClassPenalty[classification]));
-    } else {
+    }
+    else {
         // hand out credits for neutral and good events such as
         // "headers look ok" events
 
         mPipeliningPenalty = std::max(mPipeliningPenalty - 1, 0);
         mPipeliningClassPenalty[classification] = std::max(mPipeliningClassPenalty[classification] - 1, 0);
     }
 
     if (mPipelineState == PS_RED && !mPipeliningPenalty)
@@ -3363,17 +3394,18 @@ void
 nsHttpConnectionMgr::
 nsConnectionEntry::OnYellowComplete()
 {
     if (mPipelineState == PS_YELLOW) {
         if (mYellowGoodEvents && !mYellowBadEvents) {
             LOG(("transition %s to green\n", mConnInfo->Host()));
             mPipelineState = PS_GREEN;
             mGreenDepth = mInitialGreenDepth;
-        } else {
+        }
+        else {
             // The purpose of the yellow state is to witness at least
             // one successful pipelined transaction without seeing any
             // kind of negative feedback before opening the flood gates.
             // If we haven't confirmed that, then transfer back to red.
             LOG(("transition %s to red from yellow return\n",
                  mConnInfo->Host()));
             mPipelineState = PS_RED;
         }
@@ -3407,17 +3439,18 @@ nsConnectionEntry::CreditPenalty()
         for (int32_t i = 0; i < nsAHttpTransaction::CLASS_MAX; ++i) {
             mPipeliningClassPenalty[i]  =
                 std::max(int32_t(mPipeliningClassPenalty[i] - creditsEarned), 0);
             failed = failed || (mPipeliningClassPenalty[i] > 0);
         }
 
         // update last credit mark to reflect elapsed time
         mLastCreditTime += TimeDuration::FromSeconds(creditsEarned << 4);
-    } else {
+    }
+    else {
         failed = true;                         /* just assume this */
     }
 
     // If we are no longer red then clear the credit counter - you only
     // get credits for time spent in the red state
     if (!failed)
         mLastCreditTime = TimeStamp();    /* reset to null timestamp */
 
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -260,20 +260,20 @@ private:
     // pending transactions.
     //
     class nsConnectionEntry
     {
     public:
         nsConnectionEntry(nsHttpConnectionInfo *ci);
         ~nsConnectionEntry();
 
-        nsRefPtr<nsHttpConnectionInfo> mConnInfo;
-        nsTArray<nsRefPtr<nsHttpTransaction> > mPendingQ;    // pending transaction queue
-        nsTArray<nsRefPtr<nsHttpConnection> >  mActiveConns; // active connections
-        nsTArray<nsRefPtr<nsHttpConnection> >  mIdleConns;   // idle persistent connections
+        nsHttpConnectionInfo        *mConnInfo;
+        nsTArray<nsHttpTransaction*> mPendingQ;    // pending transaction queue
+        nsTArray<nsHttpConnection*>  mActiveConns; // active connections
+        nsTArray<nsHttpConnection*>  mIdleConns;   // idle persistent connections
         nsTArray<nsHalfOpenSocket*>  mHalfOpens;   // half open connections
 
         // calculate the number of half open sockets that have not had at least 1
         // connection complete
         uint32_t UnconnectedHalfOpens();
 
         // Remove a particular half open socket from the mHalfOpens array
         void RemoveHalfOpen(nsHalfOpenSocket *);
@@ -374,28 +374,26 @@ private:
     //
     // thin wrapper around a real connection, used to keep track of references
     // to the connection to determine when the connection may be reused.  the
     // transaction (or pipeline) owns a reference to this handle.  this extra
     // layer of indirection greatly simplifies consumer code, avoiding the
     // need for consumer code to know when to give the connection back to the
     // connection manager.
     //
-    class nsConnectionHandle MOZ_FINAL : public nsAHttpConnection
+    class nsConnectionHandle : public nsAHttpConnection
     {
     public:
         NS_DECL_THREADSAFE_ISUPPORTS
         NS_DECL_NSAHTTPCONNECTION(mConn)
 
-        nsConnectionHandle(nsHttpConnection *conn) : mConn(conn) { }
+        nsConnectionHandle(nsHttpConnection *conn) { NS_ADDREF(mConn = conn); }
         virtual ~nsConnectionHandle();
-        void Reset() { mConn = nullptr; }
 
-    private:
-        nsRefPtr<nsHttpConnection> mConn;
+        nsHttpConnection *mConn;
     };
 
     // nsHalfOpenSocket is used to hold the state of an opening TCP socket
     // while we wait for it to establish and bind it to a connection
 
     class nsHalfOpenSocket MOZ_FINAL : public nsIOutputStreamCallback,
                                        public nsITransportEventSink,
                                        public nsIInterfaceRequestor,
@@ -517,18 +515,16 @@ private:
     void     ReportProxyTelemetry(nsConnectionEntry *ent);
     nsresult CreateTransport(nsConnectionEntry *, nsAHttpTransaction *,
                              uint32_t, bool);
     void     AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
     void     DecrementActiveConnCount(nsHttpConnection *);
     void     StartedConnect();
     void     RecvdConnect();
 
-    static void InsertTransactionSorted(nsTArray<nsRefPtr<nsHttpTransaction> > &,
-                                        nsHttpTransaction *);
     nsConnectionEntry *GetOrCreateConnectionEntry(nsHttpConnectionInfo *);
 
     nsresult MakeNewConnection(nsConnectionEntry *ent,
                                nsHttpTransaction *trans);
     bool     AddToShortestPipeline(nsConnectionEntry *ent,
                                    nsHttpTransaction *trans,
                                    nsHttpTransaction::Classifier classification,
                                    uint16_t depthLimit);
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -106,35 +106,41 @@ namespace net {
 
 static nsresult
 NewURI(const nsACString &aSpec,
        const char *aCharset,
        nsIURI *aBaseURI,
        int32_t aDefaultPort,
        nsIURI **aURI)
 {
-    nsRefPtr<nsStandardURL> url = new nsStandardURL();
+    nsStandardURL *url = new nsStandardURL();
+    if (!url)
+        return NS_ERROR_OUT_OF_MEMORY;
+    NS_ADDREF(url);
 
     nsresult rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY,
                             aDefaultPort, aSpec, aCharset, aBaseURI);
     if (NS_FAILED(rv)) {
+        NS_RELEASE(url);
         return rv;
     }
-    url.forget(aURI);
+
+    *aURI = url; // no QI needed
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpHandler <public>
 //-----------------------------------------------------------------------------
 
 nsHttpHandler *gHttpHandler = nullptr;
 
 nsHttpHandler::nsHttpHandler()
-    : mHttpVersion(NS_HTTP_VERSION_1_1)
+    : mConnMgr(nullptr)
+    , mHttpVersion(NS_HTTP_VERSION_1_1)
     , mProxyHttpVersion(NS_HTTP_VERSION_1_1)
     , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
     , mReferrerLevel(0xff) // by default we always send a referrer
     , mSpoofReferrerSource(false)
     , mReferrerTrimmingPolicy(0)
     , mReferrerXOriginPolicy(0)
     , mFastFallbackToIPv4(false)
     , mProxyPipelining(true)
@@ -220,17 +226,17 @@ nsHttpHandler::nsHttpHandler()
 
 nsHttpHandler::~nsHttpHandler()
 {
     LOG(("Deleting nsHttpHandler [this=%p]\n", this));
 
     // make sure the connection manager is shutdown
     if (mConnMgr) {
         mConnMgr->Shutdown();
-        mConnMgr = nullptr;
+        NS_RELEASE(mConnMgr);
     }
 
     // Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late
     // and it'll segfault.  NeckoChild will get cleaned up by process exit.
 
     nsHttp::DestroyAtomTable();
     if (mPipelineTestTimer) {
         mPipelineTestTimer->Cancel();
@@ -378,16 +384,19 @@ nsHttpHandler::MakeNewRequestTokenBucket
 
 nsresult
 nsHttpHandler::InitConnectionMgr()
 {
     nsresult rv;
 
     if (!mConnMgr) {
         mConnMgr = new nsHttpConnectionMgr();
+        if (!mConnMgr)
+            return NS_ERROR_OUT_OF_MEMORY;
+        NS_ADDREF(mConnMgr);
     }
 
     rv = mConnMgr->Init(mMaxConnections,
                         mMaxPersistentConnectionsPerServer,
                         mMaxPersistentConnectionsPerProxy,
                         mMaxRequestDelay,
                         mMaxPipelinedRequests,
                         mMaxOptimisticPipelinedRequests);
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -340,17 +340,17 @@ private:
     nsMainThreadPtrHandle<nsICookieService>          mCookieService;
     nsMainThreadPtrHandle<nsISiteSecurityService>    mSSService;
 
     // the authentication credentials cache
     nsHttpAuthCache mAuthCache;
     nsHttpAuthCache mPrivateAuthCache;
 
     // the connection manager
-    nsRefPtr<nsHttpConnectionMgr> mConnMgr;
+    nsHttpConnectionMgr *mConnMgr;
 
     //
     // prefs
     //
 
     uint8_t  mHttpVersion;
     uint8_t  mProxyHttpVersion;
     uint32_t mCapabilities;
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
@@ -57,17 +57,18 @@ private:
     uint32_t    mBufLen;
 };
 
 //-----------------------------------------------------------------------------
 // nsHttpPipeline <public>
 //-----------------------------------------------------------------------------
 
 nsHttpPipeline::nsHttpPipeline()
-    : mStatus(NS_OK)
+    : mConnection(nullptr)
+    , mStatus(NS_OK)
     , mRequestIsPartial(false)
     , mResponseIsPartial(false)
     , mClosed(false)
     , mUtilizedPipeline(false)
     , mPushBackBuf(nullptr)
     , mPushBackLen(0)
     , mPushBackMax(0)
     , mHttp1xTransactionCount(0)
@@ -77,29 +78,31 @@ nsHttpPipeline::nsHttpPipeline()
 {
 }
 
 nsHttpPipeline::~nsHttpPipeline()
 {
     // make sure we aren't still holding onto any transactions!
     Close(NS_ERROR_ABORT);
 
+    NS_IF_RELEASE(mConnection);
+
     if (mPushBackBuf)
         free(mPushBackBuf);
 }
 
 nsresult
 nsHttpPipeline::AddTransaction(nsAHttpTransaction *trans)
 {
     LOG(("nsHttpPipeline::AddTransaction [this=%p trans=%x]\n", this, trans));
 
     if (mRequestQ.Length() || mResponseQ.Length())
         mUtilizedPipeline = true;
 
-    trans->AddRef(); // ref held by mRequestQ
+    NS_ADDREF(trans);
     mRequestQ.AppendElement(trans);
     uint32_t qlen = PipelineDepth();
 
     if (qlen != 1) {
         trans->SetPipelinePosition(qlen);
     }
     else {
         // do it for this case in case an idempotent cancellation
@@ -197,21 +200,20 @@ nsHttpPipeline::OnHeadersAvailable(nsAHt
         // The received headers have expanded the eligible
         // pipeline depth for this connection
         gHttpHandler->ConnMgr()->ProcessPendingQForEntry(ci);
 
     return rv;
 }
 
 void
-nsHttpPipeline::CloseTransaction(nsAHttpTransaction *aTrans, nsresult reason)
+nsHttpPipeline::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
 {
-    nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(aTrans));
     LOG(("nsHttpPipeline::CloseTransaction [this=%p trans=%x reason=%x]\n",
-         this, trans.get(), reason));
+        this, trans, reason));
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     MOZ_ASSERT(NS_FAILED(reason), "expecting failure code");
 
     // the specified transaction is to be closed with the given "reason"
 
     int32_t index;
     bool killPipeline = false;
@@ -236,17 +238,17 @@ nsHttpPipeline::CloseTransaction(nsAHttp
         killPipeline = true;
     }
 
     // Marking this connection as non-reusable prevents other items from being
     // added to it and causes it to be torn down soon.
     DontReuse();
 
     trans->Close(reason);
-    trans = nullptr;
+    NS_RELEASE(trans);
 
     if (killPipeline) {
         // reschedule anything from this pipeline onto a different connection
         CancelPipeline(reason);
     }
 
     // If all the transactions have been removed then we can close the connection
     // right away.
@@ -378,21 +380,22 @@ nsHttpPipeline::TakeSubTransactions(
 {
     LOG(("nsHttpPipeline::TakeSubTransactions [this=%p]\n", this));
 
     if (mResponseQ.Length() || mRequestIsPartial)
         return NS_ERROR_ALREADY_OPENED;
 
     int32_t i, count = mRequestQ.Length();
     for (i = 0; i < count; ++i) {
-        nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(Request(i)));
+        nsAHttpTransaction *trans = Request(i);
         // set the transaction conneciton object back to the underlying
         // nsHttpConnectionHandle
         trans->SetConnection(mConnection);
         outTransactions.AppendElement(trans);
+        NS_RELEASE(trans);
     }
     mRequestQ.Clear();
 
     LOG(("   took %d\n", count));
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
@@ -401,23 +404,24 @@ nsHttpPipeline::TakeSubTransactions(
 
 void
 nsHttpPipeline::SetConnection(nsAHttpConnection *conn)
 {
     LOG(("nsHttpPipeline::SetConnection [this=%p conn=%x]\n", this, conn));
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     MOZ_ASSERT(!mConnection, "already have a connection");
-    mConnection = conn;
+
+    NS_IF_ADDREF(mConnection = conn);
 }
 
 nsAHttpConnection *
 nsHttpPipeline::Connection()
 {
-    LOG(("nsHttpPipeline::Connection [this=%p conn=%x]\n", this, mConnection.get()));
+    LOG(("nsHttpPipeline::Connection [this=%p conn=%x]\n", this, mConnection));
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     return mConnection;
 }
 
 void
 nsHttpPipeline::GetSecurityCallbacks(nsIInterfaceRequestor **result)
 {
@@ -679,17 +683,17 @@ nsHttpPipeline::WriteSegments(nsAHttpSeg
         //
         rv = trans->WriteSegments(writer, count, countWritten);
 
         if (rv == NS_BASE_STREAM_CLOSED || trans->IsDone()) {
             trans->Close(NS_OK);
 
             // Release the transaction if it is not IsProxyConnectInProgress()
             if (trans == Response(0)) {
-                nsRefPtr<nsAHttpTransaction> listReference(dont_AddRef(trans));
+                NS_RELEASE(trans);
                 mResponseQ.RemoveElementAt(0);
                 mResponseIsPartial = false;
                 ++mHttp1xTransactionCount;
             }
 
             // ask the connection manager to add additional transactions
             // to our pipeline.
             nsRefPtr<nsHttpConnectionInfo> ci;
@@ -722,47 +726,49 @@ nsHttpPipeline::WriteSegments(nsAHttpSeg
 
     return rv;
 }
 
 uint32_t
 nsHttpPipeline::CancelPipeline(nsresult originalReason)
 {
     uint32_t i, reqLen, respLen, total;
+    nsAHttpTransaction *trans;
 
     reqLen = mRequestQ.Length();
     respLen = mResponseQ.Length();
     total = reqLen + respLen;
 
     // don't count the first response, if presnet
     if (respLen)
         total--;
 
     if (!total)
         return 0;
 
     // any pending requests can ignore this error and be restarted
     // unless it is during a CONNECT tunnel request
     for (i = 0; i < reqLen; ++i) {
-        // Each element on the list has a reference held by the list
-        nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(Request(i)));
+        trans = Request(i);
         if (mConnection && mConnection->IsProxyConnectInProgress())
             trans->Close(originalReason);
         else
             trans->Close(NS_ERROR_NET_RESET);
+        NS_RELEASE(trans);
     }
     mRequestQ.Clear();
 
     // any pending responses can be restarted except for the first one,
     // that we might want to finish on this pipeline or cancel individually.
     // Higher levels of callers ensure that we don't process non-idempotent
     // tranasction with the NS_HTTP_ALLOW_PIPELINING bit set
     for (i = 1; i < respLen; ++i) {
-        nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(Response(i)));
+        trans = Response(i);
         trans->Close(NS_ERROR_NET_RESET);
+        NS_RELEASE(trans);
     }
 
     if (respLen > 1)
         mResponseQ.TruncateLength(1);
 
     DontReuse();
     Classify(nsAHttpTransaction::CLASS_SOLO);
 
@@ -790,36 +796,35 @@ nsHttpPipeline::Close(nsresult reason)
     // numRescheduled can be 0 if there is just a single response in the
     // pipeline object. That isn't really a meaningful pipeline that
     // has been forced to be rescheduled so it does not need to generate
     // negative feedback.
     if (ci && numRescheduled)
         gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
             ci, nsHttpConnectionMgr::RedCanceledPipeline, nullptr, 0);
 
-    if (!Response(0)) {
+    nsAHttpTransaction *trans = Response(0);
+    if (!trans)
         return;
-    }
-    nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(Response(0)));
 
     // The current transaction can be restarted via reset
     // if the response has not started to arrive and the reason
     // for failure is innocuous (e.g. not an SSL error)
     if (!mResponseIsPartial &&
         (reason == NS_ERROR_NET_RESET ||
          reason == NS_OK ||
          reason == NS_ERROR_NET_TIMEOUT ||
          reason == NS_BASE_STREAM_CLOSED)) {
         trans->Close(NS_ERROR_NET_RESET);
     }
     else {
         trans->Close(reason);
     }
 
-    trans = nullptr;
+    NS_RELEASE(trans);
     mResponseQ.Clear();
 }
 
 nsresult
 nsHttpPipeline::OnReadSegment(const char *segment,
                               uint32_t count,
                               uint32_t *countRead)
 {
--- a/netwerk/protocol/http/nsHttpPipeline.h
+++ b/netwerk/protocol/http/nsHttpPipeline.h
@@ -53,17 +53,17 @@ private:
             return nullptr;
 
         return mResponseQ[i];
     }
 
     // overload of nsAHttpTransaction::QueryPipeline()
     nsHttpPipeline *QueryPipeline();
 
-    nsRefPtr<nsAHttpConnection>   mConnection;
+    nsAHttpConnection            *mConnection;
     nsTArray<nsAHttpTransaction*> mRequestQ;  // array of transactions
     nsTArray<nsAHttpTransaction*> mResponseQ; // array of transactions
     nsresult                      mStatus;
 
     // these flags indicate whether or not the first request or response
     // is partial.  a partial request means that Request(0) has been
     // partially written out to the socket.  a partial response means
     // that Response(0) has been partially read in from the socket.
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -84,16 +84,18 @@ LogHeaders(const char *lineStart)
 
 //-----------------------------------------------------------------------------
 // nsHttpTransaction <public>
 //-----------------------------------------------------------------------------
 
 nsHttpTransaction::nsHttpTransaction()
     : mCallbacksLock("transaction mCallbacks lock")
     , mRequestSize(0)
+    , mConnection(nullptr)
+    , mConnInfo(nullptr)
     , mRequestHead(nullptr)
     , mResponseHead(nullptr)
     , mContentLength(-1)
     , mContentRead(0)
     , mInvalidResponseBytesRead(0)
     , mChunkedDecoder(nullptr)
     , mStatus(NS_OK)
     , mPriority(0)
@@ -142,16 +144,19 @@ nsHttpTransaction::~nsHttpTransaction()
     if (mTokenBucketCancel) {
         mTokenBucketCancel->Cancel(NS_ERROR_ABORT);
         mTokenBucketCancel = nullptr;
     }
 
     // Force the callbacks to be released right now
     mCallbacks = nullptr;
 
+    NS_IF_RELEASE(mConnection);
+    NS_IF_RELEASE(mConnInfo);
+
     delete mResponseHead;
     delete mForTakeResponseHead;
     delete mChunkedDecoder;
     ReleaseBlockingTransaction();
 }
 
 nsHttpTransaction::Classifier
 nsHttpTransaction::Classify()
@@ -259,17 +264,17 @@ nsHttpTransaction::Init(uint32_t caps,
     // if the activity observer is not active. when the observer is active
     // we need not to coalesce any events to get all expected notifications
     // of the transaction state, necessary for correct debugging and logging.
     rv = net_NewTransportEventSinkProxy(getter_AddRefs(mTransportSink),
                                         eventsink, target,
                                         !activityDistributorActive);
     if (NS_FAILED(rv)) return rv;
 
-    mConnInfo = cinfo;
+    NS_ADDREF(mConnInfo = cinfo);
     mCallbacks = callbacks;
     mConsumerTarget = target;
     mCaps = caps;
 
     if (requestHead->Method() == nsHttp::Head)
         mNoContent = true;
 
     // Make sure that there is "Content-Length: 0" header in the requestHead
@@ -435,17 +440,18 @@ nsHttpTransaction::TakeSubTransactions(
 
 //----------------------------------------------------------------------------
 // nsHttpTransaction::nsAHttpTransaction
 //----------------------------------------------------------------------------
 
 void
 nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
 {
-    mConnection = conn;
+    NS_IF_RELEASE(mConnection);
+    NS_IF_ADDREF(mConnection = conn);
 
     if (conn) {
         MOZ_EVENT_TRACER_EXEC(static_cast<nsAHttpTransaction*>(this),
                               "net::http::transaction");
     }
 }
 
 void
@@ -950,19 +956,18 @@ nsHttpTransaction::Close(nsresult reason
 
     // mTimings.responseEnd is normally recorded based on the end of a
     // HTTP delimiter such as chunked-encodings or content-length. However,
     // EOF or an error still require an end time be recorded.
     if (TimingEnabled() &&
         mTimings.responseEnd.IsNull() && !mTimings.responseStart.IsNull())
         mTimings.responseEnd = TimeStamp::Now();
 
-    if (relConn) {
-        mConnection = nullptr;
-    }
+    if (relConn && mConnection)
+        NS_RELEASE(mConnection);
 
     // save network statistics in the end of transaction
     SaveNetworkStats(true);
 
     mStatus = reason;
     mTransactionDone = true; // forcibly flag the transaction as complete
     mClosed = true;
     ReleaseBlockingTransaction();
@@ -1106,17 +1111,17 @@ nsHttpTransaction::Restart()
 
     // rewind streams in case we already wrote out the request
     nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mRequestStream);
     if (seekable)
         seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
 
     // clear old connection state...
     mSecurityInfo = 0;
-    mConnection = nullptr;
+    NS_IF_RELEASE(mConnection);
 
     // disable pipelining for the next attempt in case pipelining caused the
     // reset.  this is being overly cautious since we don't know if pipelining
     // was the problem here.
     mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
     SetPipelinePosition(0);
 
     return gHttpHandler->InitiateTransaction(this, mPriority);
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -180,21 +180,20 @@ private:
 
     nsCOMPtr<nsISupports>             mChannel;
     nsCOMPtr<nsIHttpActivityObserver> mActivityDistributor;
 
     nsCString                       mReqHeaderBuf;    // flattened request headers
     nsCOMPtr<nsIInputStream>        mRequestStream;
     uint64_t                        mRequestSize;
 
-    nsRefPtr<nsHttpConnectionInfo>  mConnInfo;
-    nsRefPtr<nsAHttpConnection>     mConnection;
-
+    nsAHttpConnection              *mConnection;      // hard ref
+    nsHttpConnectionInfo           *mConnInfo;        // hard ref
     nsHttpRequestHead              *mRequestHead;     // weak ref
-    nsHttpResponseHead             *mResponseHead;    // owning ref
+    nsHttpResponseHead             *mResponseHead;    // hard ref
 
     nsAHttpSegmentReader           *mReader;
     nsAHttpSegmentWriter           *mWriter;
 
     nsCString                       mLineBuf;         // may contain a partial line
 
     int64_t                         mContentLength;   // equals -1 if unknown
     int64_t                         mContentRead;     // count of consumed content bytes