Landing first cut of http pipelining (2487). Don't turn it on yet. Also fix

sockettransport leakage (33929). In case of major bustage - pipelining_reorg_point
is the tag before the check in.
This commit is contained in:
ruslan%netscape.com 2000-04-01 05:19:33 +00:00
parent da78ce03ea
commit 5db8127f56
8 changed files with 968 additions and 448 deletions

View File

@ -77,6 +77,7 @@ static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
nsHTTPChannel::nsHTTPChannel(nsIURI* i_URL, nsHTTPHandler* i_Handler):
mResponse(nsnull),
mRequest (nsnull),
mHandler(dont_QueryInterface(i_Handler)),
mHTTPServerListener(nsnull),
mResponseContext(nsnull),
@ -95,7 +96,8 @@ nsHTTPChannel::nsHTTPChannel(nsIURI* i_URL, nsHTTPHandler* i_Handler):
mProxyPort(-1),
mBufferSegmentSize(0),
mBufferMaxSize(0),
mStatus(NS_OK)
mStatus(NS_OK),
mPipeliningAllowed (PR_FALSE)
{
NS_INIT_REFCNT();
@ -466,15 +468,18 @@ nsHTTPChannel::GetShouldCache(PRBool *aShouldCache)
NS_IMETHODIMP
nsHTTPChannel::GetPipeliningAllowed(PRBool *aPipeliningAllowed)
{
*aPipeliningAllowed = PR_FALSE;
if (aPipeliningAllowed == NULL)
return NS_ERROR_NULL_POINTER;
*aPipeliningAllowed = mPipeliningAllowed;
return NS_OK;
}
NS_IMETHODIMP
nsHTTPChannel::SetPipeliningAllowed(PRBool aPipeliningAllowed)
{
NS_NOTREACHED("SetPipeliningAllowed");
return NS_ERROR_NOT_IMPLEMENTED;
mPipeliningAllowed = aPipeliningAllowed;
return NS_OK;
}
NS_IMETHODIMP
@ -1303,17 +1308,42 @@ nsHTTPChannel::Open(void)
}
} /* WAITING_FOR_OPEN */
rv = mRequest -> WriteRequest ();
nsCOMPtr<nsHTTPPipelinedRequest> pReq = mPipelinedRequest;
if (NS_ERROR_BUSY == rv)
if (!pReq)
{
mState = HS_WAITING_FOR_OPEN;
return NS_OK;
mHandler -> GetPipelinedRequest (this, getter_AddRefs (pReq));
pReq -> AddToPipeline (mRequest);
}
if (NS_FAILED(rv))
PRBool commit = PR_FALSE;
pReq -> GetMustCommit ( &commit);
if (!commit && !mPipeliningAllowed)
commit = PR_TRUE;
if (commit)
{
ResponseCompleted (mResponseDataListener, rv, nsnull);
return rv;
if (!mPipelinedRequest)
mPipelinedRequest = pReq;
rv = pReq -> WriteRequest ();
if (NS_ERROR_BUSY == rv)
{
mState = HS_WAITING_FOR_OPEN;
return NS_OK;
}
if (NS_FAILED (rv))
{
ResponseCompleted (mResponseDataListener, rv, nsnull);
return rv;
}
}
else
{
mHandler -> AddPipelinedRequest (pReq);
}
mState = HS_WAITING_FOR_RESPONSE;
@ -2104,10 +2134,11 @@ nsHTTPChannel::GetSecurityInfo (nsISupports * *aSecurityInfo)
if (!aSecurityInfo)
return NS_ERROR_NULL_POINTER;
nsIChannel * trans;
nsCOMPtr<nsIChannel> trans;
if (mRequest)
{
mRequest -> GetTransport (&trans);
mRequest -> GetTransport (getter_AddRefs (trans));
if (trans)
return trans -> GetSecurityInfo (aSecurityInfo);
}

View File

@ -171,6 +171,9 @@ protected:
nsresult mStatus;
nsCOMPtr<nsIChannel> mCacheTransport;
nsCOMPtr<nsHTTPPipelinedRequest> mPipelinedRequest;
PRBool mPipeliningAllowed;
};
#endif /* _nsHTTPChannel_h_ */

View File

@ -48,6 +48,8 @@
#include "nsICategoryManager.h"
#include "nsISupportsPrimitives.h"
#include "nsHTTPRequest.h"
#ifdef XP_UNIX
#include <sys/utsname.h>
#endif /* XP_UNIX */
@ -767,6 +769,9 @@ nsHTTPHandler::Init()
rv = NS_NewISupportsArray(getter_AddRefs(mIdleTransports));
if (NS_FAILED(rv)) return rv;
rv = NS_NewISupportsArray(getter_AddRefs(mPipelinedRequests));
if (NS_FAILED(rv)) return rv;
// Startup the http category
// Bring alive the objects in the http-protocol-startup category
@ -781,10 +786,11 @@ nsHTTPHandler::~nsHTTPHandler()
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
("Deleting nsHTTPHandler [this=%x].\n", this));
mConnections->Clear();
mIdleTransports->Clear();
mPendingChannelList->Clear();
mTransportList->Clear();
mConnections -> Clear ();
mIdleTransports -> Clear ();
mPendingChannelList -> Clear ();
mTransportList -> Clear ();
mPipelinedRequests -> Clear ();
// Release the Atoms used by the HTTP protocol...
nsHTTPAtoms::ReleaseAtoms();
@ -802,7 +808,6 @@ nsresult nsHTTPHandler::RequestTransport (nsIURI* i_Uri,
PRUint32 bufferSegmentSize,
PRUint32 bufferMaxSize,
nsIChannel** o_pTrans,
PRUint32 * o_Capabilities,
PRUint32 flags)
{
nsresult rv;
@ -826,9 +831,6 @@ nsresult nsHTTPHandler::RequestTransport (nsIURI* i_Uri,
rv = i_Channel -> GetProxyPort (&proxyPort);
if (NS_FAILED (rv)) return rv;
if (o_Capabilities != NULL)
*o_Capabilities = getCapabilities (proxy, proxyPort, DEFAULT_PROXY_CAPABILITIES);
}
else
{
@ -840,9 +842,6 @@ nsresult nsHTTPHandler::RequestTransport (nsIURI* i_Uri,
if (port == -1)
GetDefaultPort (&port);
if (o_Capabilities != NULL)
*o_Capabilities = getCapabilities (host, port, DEFAULT_SERVER_CAPABILITIES);
}
nsIChannel* trans = nsnull;
@ -855,57 +854,64 @@ nsresult nsHTTPHandler::RequestTransport (nsIURI* i_Uri,
// remove old and dead transports first
for (index = count - 1; index >= 0; --index)
if (count > 0)
{
nsIChannel* cTrans = (nsIChannel*) mIdleTransports -> ElementAt (index);
if (cTrans)
for (index = count - 1; index >= 0; --index)
{
nsresult rv;
nsCOMPtr<nsISocketTransport> sTrans = do_QueryInterface (cTrans, &rv);
PRBool isAlive = PR_TRUE;
nsCOMPtr<nsIChannel> cTrans = dont_AddRef ((nsIChannel*) mIdleTransports -> ElementAt (index) );
if (NS_FAILED (rv) || NS_FAILED (sTrans -> IsAlive (mKeepAliveTimeout, &isAlive))
|| !isAlive)
mIdleTransports -> RemoveElement (cTrans);
if (cTrans)
{
nsresult rv;
nsCOMPtr<nsISocketTransport> sTrans = do_QueryInterface (cTrans, &rv);
PRBool isAlive = PR_TRUE;
if (NS_FAILED (rv) || NS_FAILED (sTrans -> IsAlive (mKeepAliveTimeout, &isAlive))
|| !isAlive)
mIdleTransports -> RemoveElement (cTrans);
}
}
}
mIdleTransports -> Count (&count);
for (index = count - 1; index >= 0; --index)
if (count > 0)
{
nsCOMPtr<nsIURI> uri;
nsIChannel* cTrans = (nsIChannel*) mIdleTransports -> ElementAt (index);
if (cTrans &&
(NS_SUCCEEDED (cTrans -> GetURI (getter_AddRefs (uri)))))
for (index = count - 1; index >= 0; --index)
{
nsXPIDLCString idlehost;
if (NS_SUCCEEDED (uri -> GetHost (getter_Copies (idlehost))))
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIChannel> cTrans = dont_AddRef ((nsIChannel*) mIdleTransports -> ElementAt (index) );
if (cTrans &&
(NS_SUCCEEDED (cTrans -> GetURI (getter_AddRefs (uri)))))
{
if (!PL_strcasecmp (usingProxy ? proxy : host, idlehost))
nsXPIDLCString idlehost;
if (NS_SUCCEEDED (uri -> GetHost (getter_Copies (idlehost))))
{
PRInt32 idleport;
if (NS_SUCCEEDED (uri -> GetPort (&idleport)))
if (!PL_strcasecmp (usingProxy ? proxy : host, idlehost))
{
if (idleport == -1)
GetDefaultPort (&idleport);
if (idleport == usingProxy ? proxyPort : port)
PRInt32 idleport;
if (NS_SUCCEEDED (uri -> GetPort (&idleport)))
{
// Addref it before removing it!
NS_ADDREF (cTrans);
// Remove it from the idle
mIdleTransports -> RemoveElement (cTrans);
trans = cTrans;
break;// break out of the for loop
if (idleport == -1)
GetDefaultPort (&idleport);
if (idleport == usingProxy ? proxyPort : port)
{
// Addref it before removing it!
trans = cTrans;
NS_ADDREF (trans);
// Remove it from the idle
mIdleTransports -> RemoveElement (trans);
break;// break out of the for loop
}
}
}
}
}
}
} /* for */
} /* for */
} /* count > 0 */
}
// if we didn't find any from the keep-alive idlelist
if (trans == nsnull)
@ -1289,3 +1295,81 @@ nsHTTPHandler::getCapabilities (const char *host, PRInt32 port, PRUint32 defCap)
return capabilities;
}
nsresult
nsHTTPHandler::GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRequest ** o_Req, PRBool checkExists)
{
if (o_Req == NULL)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIURI> uri;
nsXPIDLCString host;
PRInt32 port = -1;
nsresult rv = i_Channel -> GetURI (getter_AddRefs (uri));
if (NS_SUCCEEDED (rv))
{
rv = uri -> GetHost (getter_Copies (host));
if (NS_SUCCEEDED (rv) && host)
{
uri -> GetPort (&port);
if (port == -1)
GetDefaultPort (&port);
}
}
PRUint32 count = 0;
PRUint32 index = 0;
mPipelinedRequests -> Count (&count);
nsHTTPPipelinedRequest *pReq = nsnull;
for (index = 0; index < count; index++)
{
nsHTTPPipelinedRequest *pReq = (nsHTTPPipelinedRequest *)mPipelinedRequests -> ElementAt (index);
if (pReq != NULL)
{
PRBool same = PR_TRUE;
pReq -> GetSameRequest (host, port, &same);
if (same)
{
mPipelinedRequests -> RemoveElement (pReq);
break;
}
else
{
NS_RELEASE (pReq);
}
}
} /* for */
if (!checkExists && pReq == nsnull)
{
PRBool usingProxy = PR_FALSE;
i_Channel -> GetUsingProxy (&usingProxy);
PRUint32 capabilities;
if (usingProxy)
capabilities = getCapabilities (host, port, DEFAULT_PROXY_CAPABILITIES );
else
capabilities = getCapabilities (host, port, DEFAULT_SERVER_CAPABILITIES);
pReq = new nsHTTPPipelinedRequest (this, host, port, capabilities);
NS_ADDREF (pReq);
}
*o_Req = pReq;
return NS_OK;
}
nsresult
nsHTTPHandler::AddPipelinedRequest (nsHTTPPipelinedRequest *pReq)
{
if (pReq == NULL)
return NS_ERROR_NULL_POINTER;
mPipelinedRequests -> AppendElement (pReq);
return NS_OK;
}

View File

@ -61,6 +61,9 @@ class nsHTTPChannel;
// because of HTTP/1.1 is default now
#define DEFAULT_ALLOWED_CAPABILITIES (DEFAULT_PROXY_CAPABILITIES|DEFAULT_SERVER_CAPABILITIES)
class nsHTTPPipelinedRequest;
class nsIHTTPChannel;
class nsHTTPHandler : public nsIHTTPProtocolHandler
{
public:
@ -79,7 +82,7 @@ public:
nsHTTPChannel* i_Channel,
PRUint32 bufferSegmentSize,
PRUint32 bufferMaxSize,
nsIChannel** o_pTrans, PRUint32 *capabilities, PRUint32 flags = TRANSPORT_REUSE_ALIVE);
nsIChannel** o_pTrans, PRUint32 flags = TRANSPORT_REUSE_ALIVE);
/**
* Called to create a transport from RequestTransport to accually
@ -103,6 +106,9 @@ public:
PRUint32 ReferrerLevel(void) { return mReferrerLevel; } ;
nsresult AddPipelinedRequest (nsHTTPPipelinedRequest *pReq);
nsresult GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRequest ** o_Req, PRBool checkExists = PR_FALSE);
protected:
virtual ~nsHTTPHandler();
nsresult InitUserAgentComponents();
@ -112,6 +118,7 @@ protected:
nsCOMPtr<nsISupportsArray> mConnections;
nsCOMPtr<nsISupportsArray> mPendingChannelList;
nsCOMPtr<nsISupportsArray> mTransportList;
nsCOMPtr<nsISupportsArray> mPipelinedRequests;
// Transports that are idle (ready to be used again)
nsCOMPtr<nsISupportsArray> mIdleTransports;
@ -142,6 +149,8 @@ protected:
nsCString mProduct;
nsCString mProductSub;
nsCString mProductComment;
private:
nsHashtable mCapTable;

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,8 @@
#include "nsHTTPHeaderArray.h"
#include "nsHTTPEnums.h"
#include "nsHTTPHandler.h"
#include "nsISupportsArray.h"
#include "nsXPIDLString.h"
class nsIInputStream;
class nsHTTPChannel;
@ -58,8 +60,10 @@ class nsHTTPChannel;
-Gagan Saksena 03/29/99
*/
class nsHTTPRequest : public nsIStreamObserver,
public nsIRequest
class nsHTTPPipelinedRequest;
class nsHTTPRequest : public nsIRequest
{
public:
@ -68,7 +72,6 @@ public:
nsHTTPRequest(nsIURI* i_URL, nsHTTPHandler* i_Handler, PRUint32 bufferSegmentSize, PRUint32 bufferMaxSize, HTTPMethod i_Method=HM_GET);
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSIREQUEST
// Finally our own methods...
@ -103,13 +106,13 @@ public:
nsresult GetHeaderEnumerator(nsISimpleEnumerator** aResult);
nsresult SetConnection(nsHTTPChannel* i_Connection);
nsresult GetConnection(nsHTTPChannel** o_Connection);
nsresult SetConnection(nsHTTPChannel* i_Connection);
nsresult SetTransport (nsIChannel * aTransport);
nsresult GetTransport (nsIChannel **aTransport);
// Build the actual request string based on the settings.
nsresult WriteRequest();
nsresult GetPostDataStream(nsIInputStream* *aResult);
nsresult SetPostDataStream(nsIInputStream* aStream);
@ -117,6 +120,18 @@ public:
nsresult SetOverrideRequestSpec(const char* i_Spec);
nsresult GetOverrideRequestSpec(char** o_Spec);
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
nsCOMPtr<nsIInputStream> mPostDataStream;
nsresult formHeaders (PRUint32 capabilities);
nsresult formBuffer (nsCString * reqBuffer);
nsHTTPPipelinedRequest* mPipelinedRequest;
nsHTTPChannel* mConnection;
nsCOMPtr<nsIURL> mURI;
protected:
virtual ~nsHTTPRequest();
@ -142,27 +157,69 @@ protected:
}
HTTPMethod mMethod;
nsCOMPtr<nsIURL> mURI;
PRUint32 mVersion;
PRUint32 mKeepAliveTimeout;
PRUint32 mAttempts;
PRUint32 mCapabilities;
nsCOMPtr<nsIChannel> mTransport;
nsHTTPChannel* mConnection;
nsHTTPHeaderArray mHeaders;
nsCString mRequestBuffer;
nsCOMPtr<nsIInputStream> mPostDataStream;
char* mRequestSpec;
nsHTTPHandler* mHandler;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
nsresult mAbortStatus;
};
nsresult formHeaders ();
class nsHTTPPipelinedRequest : public nsIStreamObserver
{
public:
// Constructor
nsHTTPPipelinedRequest (nsHTTPHandler* i_Handler, const char *host, PRInt32 port, PRUint32 capabilities);
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMOBSERVER
nsresult SetTransport (nsIChannel * aTransport);
nsresult GetTransport (nsIChannel **aTransport);
// Build the actual request string based on the settings.
nsresult WriteRequest ();
nsresult AddToPipeline(nsHTTPRequest *aRequest);
nsresult GetRequestCount (PRUint32 * aReqCount);
nsresult GetMustCommit (PRBool * aMustCommit);
nsresult GetSameRequest(const char *host, PRInt32 port, PRBool * aSame);
nsresult GetCurrentRequest (nsHTTPRequest ** o_Req);
nsresult AdvanceToNextRequest ();
nsresult IsPending (PRBool *result);
nsresult Cancel (nsresult status );
nsresult Suspend ();
nsresult Resume ();
protected:
virtual ~nsHTTPPipelinedRequest ();
PRUint32 mCapabilities;
PRUint32 mAttempts;
nsCOMPtr<nsIChannel> mTransport;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRBool mMustCommit;
private:
nsCOMPtr<nsISupportsArray> mRequests;
nsHTTPRequest* mCurReq;
nsHTTPHandler* mHandler;
nsCString mRequestBuffer;
nsCOMPtr<nsIInputStream> mPostDataStream;
nsXPIDLCString mHost;
PRInt32 mPort;
};
#endif /* _nsHTTPRequest_h_ */

View File

@ -210,7 +210,7 @@ nsresult nsHTTPCacheListener::Abort()
//
////////////////////////////////////////////////////////////////////////////////
nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandler *handler)
nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandler *handler, nsHTTPPipelinedRequest * request)
: nsHTTPResponseListener (aChannel, handler),
mResponse(nsnull),
mFirstLineParsed(PR_FALSE),
@ -218,9 +218,11 @@ nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandle
mBytesReceived(0),
mBodyBytesReceived (0),
mCompressHeaderChecked (PR_FALSE),
mChunkHeaderChecked (PR_FALSE)
mChunkHeaderChecked (PR_FALSE),
mPipelinedRequest (request)
{
mChannel->mHTTPServerListener = this;
nsHTTPRequest * req = nsnull;
mChannel -> mHTTPServerListener = this;
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
("Creating nsHTTPServerListener [this=%x].\n", this));
@ -319,7 +321,15 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
// XXX/ruslan: will be replace with the new Cancel (code)
if (NS_SUCCEEDED (rv))
trans -> SetBytesExpected (0);
{
PRUint32 count = 0;
mPipelinedRequest -> GetRequestCount (&count);
if (count == 1)
trans -> SetBytesExpected (0);
else
OnStopRequest (nsnull, context, NS_OK, nsnull);
}
}
}
}
@ -352,20 +362,6 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
if (NS_SUCCEEDED(rv)) {
if (i_Length) {
PRInt32 cl = -1;
mResponse -> GetContentLength (&cl);
mBodyBytesReceived += i_Length;
if (cl != -1 && cl - mBodyBytesReceived == 0)
{
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (channel, &rv);
// XXX/ruslan: will be replaced with the new Cancel (code)
if (NS_SUCCEEDED (rv))
trans -> SetBytesExpected (0);
}
if (!mCompressHeaderChecked)
{
nsXPIDLCString compressHeader;
@ -433,6 +429,29 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
("\tOnDataAvailable [this=%x]. Consumer failed!"
"Status: %x\n", this, rv));
}
PRInt32 cl = -1;
mResponse -> GetContentLength (&cl);
mBodyBytesReceived += i_Length;
if (cl != -1 && cl - mBodyBytesReceived == 0)
{
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (channel, &rv);
// XXX/ruslan: will be replaced with the new Cancel (code)
if (NS_SUCCEEDED (rv))
{
PRUint32 count = 0;
mPipelinedRequest -> GetRequestCount (&count);
if (count == 1)
trans -> SetBytesExpected (0);
else
OnStopRequest (nsnull, context, NS_OK, nsnull);
}
}
}
}
} // end !mChannel->mOpenObserver
@ -442,8 +461,7 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
NS_IMETHODIMP
nsHTTPServerListener::OnStartRequest(nsIChannel* channel,
nsISupports* i_pContext)
nsHTTPServerListener::OnStartRequest (nsIChannel* channel, nsISupports* i_pContext)
{
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
("nsHTTPServerListener::OnStartRequest [this=%x].\n", this));
@ -451,15 +469,36 @@ nsHTTPServerListener::OnStartRequest(nsIChannel* channel,
// Initialize header varaibles...
mHeadersDone = PR_FALSE;
mFirstLineParsed = PR_FALSE;
mCompressHeaderChecked = PR_FALSE;
mChunkHeaderChecked = PR_FALSE;
mBytesReceived = 0;
mBodyBytesReceived = 0;
NS_IF_RELEASE (mResponse);
NS_IF_RELEASE ( mChannel);
mResponse = nsnull;
mChannel = nsnull;
mResponseDataListener = null_nsCOMPtr ();
nsCOMPtr<nsHTTPRequest> req;
mPipelinedRequest -> GetCurrentRequest (getter_AddRefs (req));
if (req)
{
mChannel = req -> mConnection;
if (mChannel)
{
mChannel -> mHTTPServerListener = this;
NS_ADDREF (mChannel);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
nsISupports* i_pContext,
nsresult i_Status,
const PRUnichar* i_pMsg)
nsHTTPServerListener::OnStopRequest (nsIChannel* channel, nsISupports* i_pContext, nsresult i_Status, const PRUnichar* i_pMsg)
{
nsresult rv = NS_OK;
@ -467,7 +506,8 @@ nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
("nsHTTPServerListener::OnStopRequest [this=%x]."
"\tStatus = %x\n", this, i_Status));
if (NS_SUCCEEDED(rv) && !mHeadersDone) {
if (NS_SUCCEEDED(rv) && !mHeadersDone)
{
//
// Oh great!! The server has closed the connection without sending
// an entity. Assume that it has sent all the response headers and
@ -491,15 +531,37 @@ nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
if (mResponse)
mResponse -> GetStatus(&status);
if (!mChannel -> mCachedResponse)
if (status != 304 || !mChannel -> mCachedResponse)
{
mChannel -> ResponseCompleted (mResponseDataListener, i_Status, i_pMsg);
mChannel -> mHTTPServerListener = 0;
}
for ( ; ; )
{
rv = mPipelinedRequest -> AdvanceToNextRequest ();
if (NS_SUCCEEDED (rv))
{
OnStartRequest (nsnull, nsnull);
if (!channel)
return NS_OK;
if (mResponse)
FinishedResponseHeaders ();
if (status != 304 || !mChannel -> mCachedResponse)
{
mChannel -> ResponseCompleted (mResponseDataListener, i_Status, i_pMsg);
mChannel -> mHTTPServerListener = 0;
}
}
else
break;
}
PRUint32 capabilities = 0;
if (mResponse)
if (mResponse && channel) // this is the actual response from the transport
{
HTTPVersion ver;
rv = mResponse -> GetServerVersion (&ver);
@ -533,11 +595,12 @@ nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
}
}
mHandler -> ReleaseTransport (channel, capabilities);
if (channel)
mHandler -> ReleaseTransport (channel, capabilities);
}
NS_IF_RELEASE(mChannel);
NS_IF_RELEASE(mResponse);
NS_IF_RELEASE (mChannel );
NS_IF_RELEASE (mResponse);
return rv;
}
@ -786,25 +849,26 @@ nsresult nsHTTPServerListener::ParseHTTPHeader(nsIBufferInputStream* in,
return mResponse->ParseHeader(mHeaderBuffer);
}
nsresult nsHTTPServerListener::FinishedResponseHeaders(void)
nsresult
nsHTTPServerListener::FinishedResponseHeaders ()
{
nsresult rv;
nsresult rv;
rv = mChannel->FinishedResponseHeaders();
if (NS_FAILED(rv)) return rv;
rv = mChannel -> FinishedResponseHeaders ();
if (NS_FAILED(rv)) return rv;
//
// Fire the OnStartRequest notification - now that user data is available
//
if (NS_SUCCEEDED(rv) && mResponseDataListener) {
rv = mResponseDataListener->OnStartRequest(mChannel,
mChannel->mResponseContext);
if (NS_FAILED(rv)) {
PR_LOG(gHTTPLog, PR_LOG_ERROR,
("\tOnStartRequest [this=%x]. Consumer failed!"
"Status: %x\n", this, rv));
}
}
//
// Fire the OnStartRequest notification - now that user data is available
//
if (NS_SUCCEEDED(rv) && mResponseDataListener)
{
rv = mResponseDataListener -> OnStartRequest (mChannel, mChannel -> mResponseContext);
if (NS_FAILED(rv))
{
PR_LOG(gHTTPLog, PR_LOG_ERROR, ("\tOnStartRequest [this=%x]. Consumer failed!"
"Status: %x\n", this, rv));
}
}
return rv;
return rv;
}

View File

@ -31,6 +31,7 @@
#include "nsIInputStream.h"
#include "nsXPIDLString.h"
#include "nsHTTPHandler.h"
#include "nsHTTPRequest.h"
class nsIBufferInputStream;
class nsHTTPResponse;
@ -85,7 +86,7 @@ class nsHTTPServerListener : public nsHTTPResponseListener
public:
nsHTTPServerListener(nsHTTPChannel* aConnection, nsHTTPHandler *handler);
nsHTTPServerListener (nsHTTPChannel* aConnection, nsHTTPHandler *handler, nsHTTPPipelinedRequest * request);
virtual ~nsHTTPServerListener();
NS_DECL_NSISTREAMOBSERVER
@ -121,6 +122,7 @@ protected:
PRBool mCompressHeaderChecked;
PRBool mChunkHeaderChecked;
nsHTTPPipelinedRequest* mPipelinedRequest;
};