mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Never recycle the socket transport if the server responded with Connection: close
This commit is contained in:
parent
2fa72ac8a2
commit
b096f987bc
@ -1404,12 +1404,12 @@ nsresult nsHTTPChannel::ResponseCompleted(nsIStreamListener *aListener,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsHTTPChannel::ReleaseTransport(nsIChannel *aTransport)
|
||||
nsresult nsHTTPChannel::ReleaseTransport (nsIChannel *aTransport, PRBool keepAlive)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (aTransport) {
|
||||
(void) mRequest->ReleaseTransport (aTransport);
|
||||
rv = mHandler->ReleaseTransport(aTransport);
|
||||
rv = mHandler->ReleaseTransport (aTransport, keepAlive);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
nsresult ResponseCompleted(nsIStreamListener* aListener,
|
||||
nsresult aStatus,
|
||||
const PRUnichar* aMsg);
|
||||
nsresult ReleaseTransport(nsIChannel *aTransport);
|
||||
nsresult ReleaseTransport (nsIChannel *aTransport, PRBool keepAlive = PR_FALSE);
|
||||
|
||||
nsresult SetResponse(nsHTTPResponse* i_pResp);
|
||||
nsresult GetResponseContext(nsISupports** aContext);
|
||||
|
@ -954,7 +954,7 @@ nsresult nsHTTPHandler::CreateTransport(const char* host,
|
||||
o_pTrans);
|
||||
}
|
||||
|
||||
nsresult nsHTTPHandler::ReleaseTransport(nsIChannel* i_pTrans)
|
||||
nsresult nsHTTPHandler::ReleaseTransport(nsIChannel* i_pTrans, PRBool keepAlive)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 count=0, transportsInUseCount = 0;
|
||||
@ -974,7 +974,7 @@ nsresult nsHTTPHandler::ReleaseTransport(nsIChannel* i_pTrans)
|
||||
rv = mTransportList->RemoveElement(i_pTrans);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Transport not in table...");
|
||||
|
||||
if (mDoKeepAlive)
|
||||
if (mDoKeepAlive && keepAlive)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (i_pTrans, &rv);
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
nsIChannel** o_pTrans);
|
||||
|
||||
/* Remove this transport from the list. */
|
||||
virtual nsresult ReleaseTransport(nsIChannel* i_pTrans);
|
||||
virtual nsresult ReleaseTransport(nsIChannel* i_pTrans, PRBool keepAlive = PR_FALSE);
|
||||
virtual nsresult CancelPendingChannel(nsHTTPChannel* aChannel);
|
||||
PRTime GetSessionStartTime() { return mSessionStartTime; }
|
||||
|
||||
|
@ -52,6 +52,7 @@ nsHTTPResponse::nsHTTPResponse()
|
||||
// The content length is unknown...
|
||||
mContentLength = -1;
|
||||
mChunkedResponse = PR_FALSE;
|
||||
mConnectionToken = HTTP_CONNECTION_TOKEN_NONE;
|
||||
}
|
||||
|
||||
nsHTTPResponse::~nsHTTPResponse()
|
||||
@ -424,7 +425,9 @@ nsresult nsHTTPResponse::ProcessHeader(nsIAtom* aHeader, nsCString& aValue)
|
||||
// When the Content-Length response header is processed, set the
|
||||
// ContentLength in the response ...
|
||||
//
|
||||
else if (nsHTTPAtoms::Content_Length == aHeader) {
|
||||
else
|
||||
if (nsHTTPAtoms::Content_Length == aHeader)
|
||||
{
|
||||
PRInt32 length, status;
|
||||
|
||||
length = aValue.ToInteger(&status);
|
||||
@ -434,9 +437,20 @@ nsresult nsHTTPResponse::ProcessHeader(nsIAtom* aHeader, nsCString& aValue)
|
||||
SetContentLength(length);
|
||||
}
|
||||
}
|
||||
else if (nsHTTPAtoms::Transfer_Encoding == aHeader &&
|
||||
!PL_strcmp(aValue, "chunked"))
|
||||
else
|
||||
if (nsHTTPAtoms::Transfer_Encoding == aHeader && !PL_strcmp(aValue, "chunked"))
|
||||
mChunkedResponse = PR_TRUE;
|
||||
else
|
||||
if (nsHTTPAtoms::Connection == aHeader)
|
||||
{
|
||||
if (!PL_strcasecmp (aValue, "close"))
|
||||
mConnectionToken = HTTP_CONNECTION_TOKEN_CLOSE;
|
||||
else
|
||||
if (!PL_strcasecmp (aValue, "keep-alive"))
|
||||
mConnectionToken = HTTP_CONNECTION_TOKEN_KEEPALIVE;
|
||||
else
|
||||
mConnectionToken = HTTP_CONNECTION_TOKEN_UNKNOWN;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the response header...
|
||||
@ -524,6 +538,12 @@ PRBool nsHTTPResponse::isChunkedResponse ()
|
||||
return mChunkedResponse;
|
||||
}
|
||||
|
||||
HTTPConnectionToken
|
||||
nsHTTPResponse::GetHttpConnectionToken ()
|
||||
{
|
||||
return mConnectionToken;
|
||||
}
|
||||
|
||||
// Check to see if a (cached) HTTP response is stale and, therefore,
|
||||
// must be revalidated with the origin server.
|
||||
//
|
||||
|
@ -40,6 +40,11 @@
|
||||
|
||||
-Gagan Saksena 03/29/99
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
HTTP_CONNECTION_TOKEN_UNKNOWN, HTTP_CONNECTION_TOKEN_NONE, HTTP_CONNECTION_TOKEN_CLOSE, HTTP_CONNECTION_TOKEN_KEEPALIVE
|
||||
} HTTPConnectionToken;
|
||||
|
||||
class nsHTTPResponse : public nsISupports
|
||||
{
|
||||
|
||||
@ -79,6 +84,7 @@ public:
|
||||
|
||||
PRBool IsStale(PRBool aUseHeuristicExpiration);
|
||||
PRBool isChunkedResponse ();
|
||||
HTTPConnectionToken GetHttpConnectionToken ();
|
||||
|
||||
nsresult UpdateHeaders(nsISimpleEnumerator *aEnumerator);
|
||||
|
||||
@ -98,6 +104,7 @@ protected:
|
||||
nsHTTPHeaderArray mHeaders;
|
||||
private:
|
||||
PRBool mChunkedResponse;
|
||||
HTTPConnectionToken mConnectionToken;
|
||||
};
|
||||
|
||||
#endif /* _nsHTTPResponse_h_ */
|
||||
|
@ -453,7 +453,32 @@ nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
|
||||
("nsHTTPServerListener::OnStopRequest [this=%x]. "
|
||||
"Discarding 304 response\n", this));
|
||||
}
|
||||
mChannel->ReleaseTransport(channel);
|
||||
PRBool keepAlive = PR_FALSE;
|
||||
|
||||
if (mResponse)
|
||||
{
|
||||
HTTPVersion ver;
|
||||
rv = mResponse -> GetServerVersion (&ver);
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
HTTPConnectionToken token = mResponse -> GetHttpConnectionToken ();
|
||||
|
||||
if (ver == HTTP_ONE_ONE )
|
||||
{
|
||||
// ruslan: some older incorrect 1.1 servers may do this
|
||||
if (token != HTTP_CONNECTION_TOKEN_CLOSE)
|
||||
keepAlive = PR_TRUE;
|
||||
}
|
||||
else
|
||||
if (ver == HTTP_ONE_ZERO)
|
||||
{
|
||||
if (token == HTTP_CONNECTION_TOKEN_KEEPALIVE)
|
||||
keepAlive = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mChannel -> ReleaseTransport (channel, keepAlive);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mChannel);
|
||||
|
Loading…
Reference in New Issue
Block a user