bugzilla 595316 remove static cast of nsAHttp* objs r=honzab
authorPatrick McManus <mcmanus@ducksong.com>
Fri, 08 Apr 2011 14:37:16 -0400
changeset 67712 233dde6c5b44a913639c99f7e4b0c31865b96ad1
parent 67711 e48f48ad28be17759eebde37609b5e60fe8add0a
child 67713 4cadb299e5efac8841181a6547abd4f11cc0e66b
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershonzab
bugs595316
milestone2.2a1pre
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
bugzilla 595316 remove static cast of nsAHttp* objs r=honzab
netwerk/protocol/http/nsAHttpConnection.h
netwerk/protocol/http/nsAHttpTransaction.h
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpPipeline.cpp
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
--- a/netwerk/protocol/http/nsAHttpConnection.h
+++ b/netwerk/protocol/http/nsAHttpConnection.h
@@ -39,16 +39,17 @@
 #define nsAHttpConnection_h__
 
 #include "nsISupports.h"
 
 class nsAHttpTransaction;
 class nsHttpRequestHead;
 class nsHttpResponseHead;
 class nsHttpConnectionInfo;
+class nsHttpConnection;
 
 //-----------------------------------------------------------------------------
 // Abstract base class for a HTTP connection
 //-----------------------------------------------------------------------------
 
 class nsAHttpConnection : public nsISupports
 {
 public:
@@ -105,24 +106,29 @@ public:
     // called by a transaction when the transaction reads more from the socket
     // than it should have (eg. containing part of the next pipelined response).
     virtual nsresult PushBack(const char *data, PRUint32 length) = 0;
 
     // Used by a transaction to manage the state of previous response bodies on
     // the same connection and work around buggy servers.
     virtual PRBool LastTransactionExpectedNoContent() = 0;
     virtual void   SetLastTransactionExpectedNoContent(PRBool) = 0;
+
+    // Transfer the base http connection object along with a
+    // reference to it to the caller.
+    virtual nsHttpConnection *TakeHttpConnection() = 0;
 };
 
 #define NS_DECL_NSAHTTPCONNECTION \
     nsresult OnHeadersAvailable(nsAHttpTransaction *, nsHttpRequestHead *, nsHttpResponseHead *, PRBool *reset); \
     nsresult ResumeSend(); \
     nsresult ResumeRecv(); \
     void CloseTransaction(nsAHttpTransaction *, nsresult); \
     void GetConnectionInfo(nsHttpConnectionInfo **); \
     void GetSecurityInfo(nsISupports **); \
     PRBool IsPersistent(); \
     PRBool IsReused(); \
     nsresult PushBack(const char *, PRUint32); \
     PRBool LastTransactionExpectedNoContent(); \
-    void   SetLastTransactionExpectedNoContent(PRBool);
+    void   SetLastTransactionExpectedNoContent(PRBool); \
+    nsHttpConnection *TakeHttpConnection();
 
 #endif // nsAHttpConnection_h__
--- a/netwerk/protocol/http/nsAHttpTransaction.h
+++ b/netwerk/protocol/http/nsAHttpTransaction.h
@@ -40,16 +40,17 @@
 
 #include "nsISupports.h"
 
 class nsAHttpConnection;
 class nsAHttpSegmentReader;
 class nsAHttpSegmentWriter;
 class nsIInterfaceRequestor;
 class nsIEventTarget;
+class nsHttpRequestHead;
 
 //----------------------------------------------------------------------------
 // Abstract base class for a HTTP transaction:
 //
 // A transaction is a "sink" for the response data.  The connection pushes
 // data to the transaction by writing to it.  The transaction supports
 // WriteSegments and may refuse to accept data if its buffers are full (its
 // write function returns NS_BASE_STREAM_WOULD_BLOCK in this case).
@@ -81,29 +82,37 @@ public:
                                   PRUint32 count, PRUint32 *countRead) = 0;
 
     // called to write response data to the transaction.
     virtual nsresult WriteSegments(nsAHttpSegmentWriter *writer,
                                    PRUint32 count, PRUint32 *countWritten) = 0;
 
     // called to close the transaction
     virtual void Close(nsresult reason) = 0;
+
+    // called to indicate a failure at the SSL setup level
+    virtual void SetSSLConnectFailed() = 0;
+    
+    // called to retrieve the request headers of the transaction
+    virtual nsHttpRequestHead *RequestHead() = 0;
 };
 
 #define NS_DECL_NSAHTTPTRANSACTION \
     void SetConnection(nsAHttpConnection *); \
     void GetSecurityCallbacks(nsIInterfaceRequestor **, \
                               nsIEventTarget **);       \
     void OnTransportStatus(nsresult status, PRUint64 progress); \
     PRBool   IsDone(); \
     nsresult Status(); \
     PRUint32 Available(); \
     nsresult ReadSegments(nsAHttpSegmentReader *, PRUint32, PRUint32 *); \
     nsresult WriteSegments(nsAHttpSegmentWriter *, PRUint32, PRUint32 *); \
-    void     Close(nsresult reason);
+    void     Close(nsresult reason);                                    \
+    void     SetSSLConnectFailed();                                     \
+    nsHttpRequestHead *RequestHead();
 
 //-----------------------------------------------------------------------------
 // nsAHttpSegmentReader
 //-----------------------------------------------------------------------------
 
 class nsAHttpSegmentReader
 {
 public:
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -417,22 +417,17 @@ nsHttpConnection::OnHeadersAvailable(nsA
                 LOG(("ProxyStartSSL failed [rv=%x]\n", rv));
             mCompletedSSLConnect = PR_TRUE;
             rv = mSocketOut->AsyncWait(this, 0, 0, nsnull);
             // XXX what if this fails -- need to handle this error
             NS_ASSERTION(NS_SUCCEEDED(rv), "mSocketOut->AsyncWait failed");
         }
         else {
             LOG(("SSL proxy CONNECT failed!\n"));
-            // NOTE: this cast is valid since this connection cannot be
-            // processing a transaction pipeline until after the first HTTP/1.1
-            // response.
-            nsHttpTransaction *trans =
-                    static_cast<nsHttpTransaction *>(mTransaction.get());
-            trans->SetSSLConnectFailed();
+            mTransaction->SetSSLConnectFailed();
         }
     }
 
     return NS_OK;
 }
 
 PRBool
 nsHttpConnection::IsReused()
@@ -722,29 +717,24 @@ nsHttpConnection::SetupSSLProxyConnect()
     request.SetMethod(nsHttp::Connect);
     request.SetVersion(gHttpHandler->HttpVersion());
     request.SetRequestURI(buf);
     request.SetHeader(nsHttp::User_Agent, gHttpHandler->UserAgent());
 
     // send this header for backwards compatibility.
     request.SetHeader(nsHttp::Proxy_Connection, NS_LITERAL_CSTRING("keep-alive"));
 
-    // NOTE: this cast is valid since this connection cannot be processing a
-    // transaction pipeline until after the first HTTP/1.1 response.
-    nsHttpTransaction *trans =
-        static_cast<nsHttpTransaction *>(mTransaction.get());
-    
-    val = trans->RequestHead()->PeekHeader(nsHttp::Host);
+    val = mTransaction->RequestHead()->PeekHeader(nsHttp::Host);
     if (val) {
         // all HTTP/1.1 requests must include a Host header (even though it
         // may seem redundant in this case; see bug 82388).
         request.SetHeader(nsHttp::Host, nsDependentCString(val));
     }
 
-    val = trans->RequestHead()->PeekHeader(nsHttp::Proxy_Authorization);
+    val = mTransaction->RequestHead()->PeekHeader(nsHttp::Proxy_Authorization);
     if (val) {
         // we don't know for sure if this authorization is intended for the
         // SSL proxy, so we add it just in case.
         request.SetHeader(nsHttp::Proxy_Authorization, nsDependentCString(val));
     }
 
     buf.Truncate();
     request.Flatten(buf, PR_FALSE);
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -871,32 +871,28 @@ nsHttpConnectionMgr::ProcessNewTransacti
         if (!clone)
             return NS_ERROR_OUT_OF_MEMORY;
         ent = new nsConnectionEntry(clone);
         if (!ent)
             return NS_ERROR_OUT_OF_MEMORY;
         mCT.Put(&key, ent);
     }
 
-    nsHttpConnection *conn;
+    // Check if the transaction already has a sticky reference to a connection.
+    // If so, then we can just use it directly by transferring its reference
+    // to the new connection var instead of calling GetConnection() to search
+    // for an available one.
 
-    // check if the transaction already has a sticky reference to a connection.
-    // if so, then we can just use it directly.  XXX check if alive??
-    // XXX add a TakeConnection method or something to make this clearer!
-    nsConnectionHandle *handle = (nsConnectionHandle *) trans->Connection();
-    if (handle) {
+    nsAHttpConnection *wrappedConnection = trans->Connection();
+    nsHttpConnection  *conn;
+    conn = wrappedConnection ? wrappedConnection->TakeHttpConnection() : nsnull;
+
+    if (conn) {
         NS_ASSERTION(caps & NS_HTTP_STICKY_CONNECTION, "unexpected caps");
-        NS_ASSERTION(handle->mConn, "no connection");
 
-        // steal reference from connection handle.
-        // XXX prevent SetConnection(nsnull) from calling ReclaimConnection
-        conn = handle->mConn;
-        handle->mConn = nsnull;
-
-        // destroy connection handle.
         trans->SetConnection(nsnull);
     }
     else
         GetConnection(ent, trans, &conn);
 
     nsresult rv;
     if (!conn) {
         LOG(("  adding transaction to pending queue [trans=%x pending-count=%u]\n",
@@ -1508,16 +1504,29 @@ nsHttpConnectionMgr::nsHalfOpenSocket::G
         nsCOMPtr<nsIInterfaceRequestor> callbacks;
         mTransaction->GetSecurityCallbacks(getter_AddRefs(callbacks), nsnull);
         if (callbacks)
             return callbacks->GetInterface(iid, result);
     }
     return NS_ERROR_NO_INTERFACE;
 }
 
+
+nsHttpConnection *
+nsHttpConnectionMgr::nsConnectionHandle::TakeHttpConnection()
+{
+    // return our connection object to the caller and clear it internally
+    // do not drop our reference - the caller now owns it.
+
+    NS_ASSERTION(mConn, "no connection");
+    nsHttpConnection *conn = mConn;
+    mConn = nsnull;
+    return conn;
+}
+
 PRBool
 nsHttpConnectionMgr::nsConnectionHandle::LastTransactionExpectedNoContent()
 {
     return mConn->LastTransactionExpectedNoContent();
 }
 
 void
 nsHttpConnectionMgr::
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
@@ -298,16 +298,43 @@ nsHttpPipeline::LastTransactionExpectedN
 
 void
 nsHttpPipeline::SetLastTransactionExpectedNoContent(PRBool val)
 {
     NS_ABORT_IF_FALSE(mConnection, "no connection");
      mConnection->SetLastTransactionExpectedNoContent(val);
 }
 
+nsHttpConnection *
+nsHttpPipeline::TakeHttpConnection()
+{
+    if (mConnection)
+        return mConnection->TakeHttpConnection();
+    return nsnull;
+}
+
+void
+nsHttpPipeline::SetSSLConnectFailed()
+{
+    nsAHttpTransaction *trans = Request(0);
+
+    if (trans)
+        trans->SetSSLConnectFailed();
+}
+
+nsHttpRequestHead *
+nsHttpPipeline::RequestHead()
+{
+    nsAHttpTransaction *trans = Request(0);
+
+    if (trans)
+        return trans->RequestHead();
+    return nsnull;
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpPipeline::nsAHttpConnection
 //-----------------------------------------------------------------------------
 
 void
 nsHttpPipeline::SetConnection(nsAHttpConnection *conn)
 {
     LOG(("nsHttpPipeline::SetConnection [this=%x conn=%x]\n", this, conn));
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -313,16 +313,28 @@ nsHttpTransaction::TakeResponseHead()
         return nsnull;
     }
 
     nsHttpResponseHead *head = mResponseHead;
     mResponseHead = nsnull;
     return head;
 }
 
+void
+nsHttpTransaction::SetSSLConnectFailed()
+{
+    mSSLConnectFailed = PR_TRUE;
+}
+
+nsHttpRequestHead *
+nsHttpTransaction::RequestHead()
+{
+    return mRequestHead;
+}
+
 //----------------------------------------------------------------------------
 // nsHttpTransaction::nsAHttpTransaction
 //----------------------------------------------------------------------------
 
 void
 nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
 {
     NS_IF_RELEASE(mConnection);
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -109,32 +109,30 @@ public:
                   nsIEventTarget        *consumerTarget,
                   nsIInterfaceRequestor *callbacks,
                   nsITransportEventSink *eventsink,
                   nsIAsyncInputStream  **responseBody);
 
     // attributes
     PRUint8                Caps()           { return mCaps; }
     nsHttpConnectionInfo  *ConnectionInfo() { return mConnInfo; }
-    nsHttpRequestHead     *RequestHead()    { return mRequestHead; }
     nsHttpResponseHead    *ResponseHead()   { return mHaveAllHeaders ? mResponseHead : nsnull; }
     nsISupports           *SecurityInfo()   { return mSecurityInfo; }
 
     nsIInterfaceRequestor *Callbacks()      { return mCallbacks; } 
     nsIEventTarget        *ConsumerTarget() { return mConsumerTarget; }
     nsAHttpConnection     *Connection()     { return mConnection; }
 
     // Called to take ownership of the response headers; the transaction
     // will drop any reference to the response headers after this call.
     nsHttpResponseHead *TakeResponseHead();
 
     // Called to find out if the transaction generated a complete response.
     PRBool ResponseIsComplete() { return mResponseIsComplete; }
 
-    void   SetSSLConnectFailed() { mSSLConnectFailed = PR_TRUE; }
     PRBool    SSLConnectFailed() { return mSSLConnectFailed; }
 
     // These methods may only be used by the connection manager.
     void    SetPriority(PRInt32 priority) { mPriority = priority; }
     PRInt32    Priority()                 { return mPriority; }
 
 private:
     nsresult Restart();