Landing the next batch of http pipelining changes. Still not enabled by default

(but you can set a pref in all.js and it'll work and some sites will load
ultra-fast). pipelining_reorg_point2 is pre-checkin tag in case of major
bustages (which there should be none).
This commit is contained in:
ruslan%netscape.com 2000-04-05 01:43:57 +00:00
Родитель 81e3d6e157
Коммит 2f521bf728
12 изменённых файлов: 228 добавлений и 178 удалений

Просмотреть файл

@ -1459,31 +1459,33 @@ nsSocketTransport::Resume(void)
NS_IMETHODIMP
nsSocketTransport::OnFull(nsIPipe* aPipe)
{
PR_LOG(gSocketLog, PR_LOG_DEBUG,
("nsSocketTransport::OnFull() [%s:%d %x] nsIPipe=%x.\n",
mHostName, mPort, this, aPipe));
//
// The socket transport has filled up the pipe. Remove the
// transport from the select list until the consumer can
// make room...
//
nsCOMPtr<nsIBufferInputStream> in;
nsresult rv = aPipe->GetInputStream(getter_AddRefs(in));
if (NS_SUCCEEDED(rv) && in == mReadPipeIn) {
// Enter the socket transport lock...
nsAutoMonitor mon(mMonitor);
NS_ASSERTION(!GetFlag(eSocketRead_Wait), "Already waiting!");
SetFlag(eSocketRead_Wait);
mSelectFlags &= (~PR_POLL_READ);
return NS_OK;
}
// Else, since we might get an OnFull without an intervening OnWrite
// try the OnWrite case to see if we need to resume the blocking write operation:
return OnWrite(aPipe, 0);
PR_LOG(gSocketLog, PR_LOG_DEBUG,
("nsSocketTransport::OnFull() [%s:%d %x] nsIPipe=%x.\n",
mHostName, mPort, this, aPipe));
//
// The socket transport has filled up the pipe. Remove the
// transport from the select list until the consumer can
// make room...
//
nsCOMPtr<nsIBufferInputStream> in;
nsresult rv = aPipe->GetInputStream(getter_AddRefs(in));
if (NS_SUCCEEDED(rv) && in == mReadPipeIn)
{
// Enter the socket transport lock...
nsAutoMonitor mon(mMonitor);
if (!GetFlag(eSocketRead_Wait))
{
SetFlag(eSocketRead_Wait);
mSelectFlags &= (~PR_POLL_READ);
}
return NS_OK;
}
// Else, since we might get an OnFull without an intervening OnWrite
// try the OnWrite case to see if we need to resume the blocking write operation:
return OnWrite(aPipe, 0);
}
@ -1826,6 +1828,7 @@ nsSocketTransport::AsyncWrite(nsIInputStream* aFromStream,
// Create a marshalling stream observer to receive notifications...
if (aObserver) {
mWriteObserver = null_nsCOMPtr();
rv = NS_NewAsyncStreamObserver(getter_AddRefs(mWriteObserver),
aObserver, NS_CURRENT_EVENTQ);
}

Просмотреть файл

@ -97,8 +97,7 @@ nsHTTPChannel::nsHTTPChannel(nsIURI* i_URL, nsHTTPHandler* i_Handler):
mBufferSegmentSize(0),
mBufferMaxSize(0),
mStatus(NS_OK),
mPipeliningAllowed (PR_FALSE),
mPipelinedRequest (nsnull)
mPipeliningAllowed (PR_TRUE)
{
NS_INIT_REFCNT();
@ -124,7 +123,6 @@ nsHTTPChannel::~nsHTTPChannel()
#endif
NS_IF_RELEASE(mResponse);
NS_IF_RELEASE(mCachedResponse);
NS_IF_RELEASE(mPipelinedRequest);
mHandler = null_nsCOMPtr();
mEventSink = null_nsCOMPtr();
@ -1310,29 +1308,26 @@ nsHTTPChannel::Open(void)
}
} /* WAITING_FOR_OPEN */
nsHTTPPipelinedRequest * pReq = mPipelinedRequest;
nsHTTPPipelinedRequest * pReq;
if (!pReq)
{
if (mState != HS_WAITING_FOR_OPEN)
mHandler -> GetPipelinedRequest (this, &pReq);
pReq -> AddToPipeline (mRequest);
}
else
pReq = mPipelinedRequest;
PRBool commit = PR_FALSE;
pReq -> GetMustCommit ( &commit);
if (!commit && !mPipeliningAllowed)
commit = PR_TRUE;
if (commit)
if (pReq)
{
if (!mPipelinedRequest)
mPipelinedRequest = pReq;
if (mState != HS_WAITING_FOR_OPEN)
pReq -> AddToPipeline (mRequest);
if (!mPipeliningAllowed)
pReq -> SetMustCommit (PR_TRUE);
rv = pReq -> WriteRequest ();
if (NS_ERROR_BUSY == rv)
{
mPipelinedRequest = pReq;
mState = HS_WAITING_FOR_OPEN;
return NS_OK;
}
@ -1342,10 +1337,6 @@ nsHTTPChannel::Open(void)
ResponseCompleted (mResponseDataListener, rv, nsnull);
return rv;
}
}
else
{
mHandler -> AddPipelinedRequest (pReq);
NS_RELEASE (pReq);
}

Просмотреть файл

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

Просмотреть файл

@ -1298,7 +1298,7 @@ nsHTTPHandler::getCapabilities (const char *host, PRInt32 port, PRUint32 defCap)
nsresult
nsHTTPHandler::GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRequest ** o_Req, PRBool checkExists)
nsHTTPHandler::GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRequest ** o_Req)
{
if (o_Req == NULL)
return NS_ERROR_NULL_POINTER;
@ -1325,26 +1325,27 @@ nsHTTPHandler::GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRe
nsHTTPPipelinedRequest *pReq = nsnull;
for (index = 0; index < count; index++)
for (index = 0; index < count; index++, pReq = nsnull)
{
nsHTTPPipelinedRequest *pReq = (nsHTTPPipelinedRequest *)mPipelinedRequests -> ElementAt (index);
pReq = (nsHTTPPipelinedRequest *)mPipelinedRequests -> ElementAt (index);
if (pReq != NULL)
{
PRBool same = PR_TRUE;
pReq -> GetSameRequest (host, port, &same);
if (same)
{
mPipelinedRequests -> RemoveElement (pReq);
break;
PRBool commit = PR_FALSE;
pReq -> GetMustCommit (&commit);
if (!commit)
break;
}
else
{
NS_RELEASE (pReq);
}
}
} /* for */
if (!checkExists && pReq == nsnull)
if (pReq == nsnull)
{
PRBool usingProxy = PR_FALSE;
i_Channel -> GetUsingProxy (&usingProxy);
@ -1357,6 +1358,8 @@ nsHTTPHandler::GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRe
pReq = new nsHTTPPipelinedRequest (this, host, port, capabilities);
NS_ADDREF (pReq);
mPipelinedRequests -> AppendElement (pReq);
}
*o_Req = pReq;
@ -1364,7 +1367,7 @@ nsHTTPHandler::GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRe
}
nsresult
nsHTTPHandler::AddPipelinedRequest (nsHTTPPipelinedRequest *pReq)
nsHTTPHandler::AddPipelinedRequest (nsHTTPPipelinedRequest *pReq)
{
if (pReq == NULL)
return NS_ERROR_NULL_POINTER;
@ -1373,3 +1376,14 @@ nsHTTPHandler::AddPipelinedRequest (nsHTTPPipelinedRequest *pReq)
return NS_OK;
}
nsresult
nsHTTPHandler::ReleasePipelinedRequest (nsHTTPPipelinedRequest *pReq)
{
if (pReq == NULL)
return NS_ERROR_NULL_POINTER;
mPipelinedRequests -> RemoveElement (pReq);
return NS_OK;
}

Просмотреть файл

@ -107,7 +107,8 @@ public:
PRUint32 ReferrerLevel(void) { return mReferrerLevel; } ;
nsresult AddPipelinedRequest (nsHTTPPipelinedRequest *pReq);
nsresult GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRequest ** o_Req, PRBool checkExists = PR_FALSE);
nsresult GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRequest ** o_Req);
nsresult ReleasePipelinedRequest (nsHTTPPipelinedRequest *pReq);
protected:
virtual ~nsHTTPHandler();

Просмотреть файл

@ -62,7 +62,8 @@ nsHTTPRequest::nsHTTPRequest(nsIURI* i_URL, nsHTTPHandler* i_Handler, PRUint32 b
mKeepAliveTimeout (0),
mRequestSpec(0),
mHandler (i_Handler),
mAbortStatus(NS_OK)
mAbortStatus(NS_OK),
mHeadersFormed (PR_FALSE)
{
NS_INIT_REFCNT();
@ -278,6 +279,9 @@ nsHTTPRequest::GetOverrideRequestSpec(char** o_Spec)
nsresult
nsHTTPRequest::formHeaders (PRUint32 capabilities)
{
if (mHeadersFormed)
return NS_OK;
nsXPIDLCString host;
mURI -> GetHost (getter_Copies (host));
PRInt32 port = -1;
@ -377,6 +381,8 @@ nsHTTPRequest::formHeaders (PRUint32 capabilities)
else
SetHeader (nsHTTPAtoms::Connection, "close");
mHeadersFormed = PR_TRUE;
return NS_OK;
}
@ -486,8 +492,12 @@ nsHTTPPipelinedRequest::nsHTTPPipelinedRequest (nsHTTPHandler* i_Handler, const
mBufferSegmentSize (0),
mBufferMaxSize (0),
mMustCommit (PR_FALSE),
mHandler (i_Handler),
mPort (port)
mHandler (i_Handler),
mTotalProcessed (0),
mTotalWritten (0),
mListener (nsnull),
mPort (port),
mOnStopDone (PR_TRUE)
{
NS_INIT_REFCNT ();
@ -546,7 +556,7 @@ nsHTTPPipelinedRequest::GetTransport (nsIChannel **aTransport)
nsresult
nsHTTPPipelinedRequest::WriteRequest ()
{
nsresult rv;
nsresult rv = NS_OK;
PRUint32 count = 0;
PRUint32 index;
@ -554,12 +564,15 @@ nsHTTPPipelinedRequest::WriteRequest ()
if (!mRequests)
return NS_ERROR_FAILURE;
if (!mOnStopDone)
return NS_OK;
mRequests -> Count (&count);
if (count == 0)
return NS_ERROR_FAILURE;
if (count == 0 || mTotalWritten - mTotalProcessed >= count)
return NS_OK;
if (mAttempts > 2)
if (mAttempts > 1)
return NS_ERROR_FAILURE;
nsHTTPRequest * req = (nsHTTPRequest *) mRequests -> ElementAt (0);
@ -579,22 +592,16 @@ nsHTTPPipelinedRequest::WriteRequest ()
NS_RELEASE (req);
if (NS_FAILED (rv))
return rv;
if (mAttempts++ == 0)
for (index = mTotalWritten - mTotalProcessed; index < count; index++)
{
for (index = 0; index < count; index++)
{
req = (nsHTTPRequest *) mRequests -> ElementAt (index);
req -> formHeaders (mCapabilities);
NS_RELEASE (req);
}
req = (nsHTTPRequest *) mRequests -> ElementAt (index);
req -> formHeaders (mCapabilities);
NS_RELEASE (req);
}
mRequestBuffer.Truncate ();
for (index = 0; index < count; index++)
for (index = mTotalWritten - mTotalProcessed; index < count; index++)
{
req = (nsHTTPRequest *) mRequests -> ElementAt (index);
req -> formBuffer (&mRequestBuffer);
@ -602,6 +609,7 @@ nsHTTPPipelinedRequest::WriteRequest ()
mTransport -> SetNotificationCallbacks (req -> mConnection);
NS_RELEASE (req);
mTotalWritten++;
}
//
@ -634,8 +642,10 @@ nsHTTPPipelinedRequest::WriteRequest ()
if (NS_FAILED(rv)) return rv;
req = (nsHTTPRequest *) mRequests -> ElementAt (0);
mOnStopDone = PR_FALSE;
rv = mTransport->AsyncWrite(stream, this, (nsISupports*)(nsIRequest*)req -> mConnection);
NS_RELEASE (req);
return rv;
}
@ -666,7 +676,8 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
if (NS_SUCCEEDED (rv))
{
PRBool isAlive = PR_TRUE;
if (trans)
if (!mListener && trans)
trans -> IsAlive (0, &isAlive);
if (isAlive)
@ -691,19 +702,26 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
("nsHTTPRequest [this=%x]. Finished writing request to server." "\tStatus: %x\n", this, iStatus));
nsHTTPResponseListener* pListener = new nsHTTPServerListener (req -> mConnection, mHandler, this);
if (pListener)
if (mListener == nsnull)
{
NS_ADDREF (pListener);
rv = mTransport -> AsyncRead (pListener, i_Context);
NS_RELEASE (pListener);
nsHTTPResponseListener* pListener = new nsHTTPServerListener (req -> mConnection, mHandler, this);
if (pListener)
{
NS_ADDREF (pListener);
rv = mTransport -> AsyncRead (pListener, i_Context);
mListener = pListener;
NS_RELEASE (pListener);
}
else
rv = NS_ERROR_OUT_OF_MEMORY;
}
else
rv = NS_ERROR_OUT_OF_MEMORY;
mOnStopDone = PR_TRUE;
WriteRequest (); // write again to see if anything else is queued up
}
}
else
rv = NS_ERROR_FAILURE; /* isAlive */
} /* NS_SUCCEEDED */
//
@ -721,22 +739,31 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
//
if (NS_FAILED (rv))
{
PRUint32 wasKeptAlive = 0;
if (trans)
trans -> GetReuseCount (&wasKeptAlive);
mHandler -> ReleaseTransport (mTransport, 0);
mTransport = null_nsCOMPtr ();
if (wasKeptAlive)
if (mListener == nsnull)
{
rv = WriteRequest ();
if (NS_SUCCEEDED (rv))
// the pipeline just started - we still can attempt to recover
PRUint32 wasKeptAlive = 0;
if (trans)
trans -> GetReuseCount (&wasKeptAlive);
mHandler -> ReleaseTransport (mTransport, 0);
mTransport = null_nsCOMPtr ();
if (wasKeptAlive)
{
NS_IF_RELEASE (req);
return rv;
mAttempts++;
mTotalWritten = 0;
mOnStopDone = PR_TRUE;
rv = WriteRequest ();
if (NS_SUCCEEDED (rv))
{
NS_IF_RELEASE (req);
return rv;
}
}
}
@ -752,7 +779,7 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
//
// These resouces are no longer needed...
//
mRequestBuffer.Truncate ();
// mRequestBuffer.Truncate ();
mPostDataStream = null_nsCOMPtr ();
return rv;
@ -808,15 +835,18 @@ nsHTTPPipelinedRequest::AddToPipeline (nsHTTPRequest *aRequest)
if (!mRequests )
return NS_ERROR_FAILURE;
if (mMustCommit)
return NS_ERROR_FAILURE;
PRUint32 count = 0;
mRequests -> Count (&count);
if (count > 0 && aRequest -> mPostDataStream)
return NS_ERROR_FAILURE;
if (count > 0)
{
if (aRequest -> mPostDataStream)
return NS_ERROR_FAILURE;
if (mMustCommit)
return NS_ERROR_FAILURE;
}
if (aRequest -> mPostDataStream)
{
@ -833,10 +863,6 @@ nsHTTPPipelinedRequest::AddToPipeline (nsHTTPRequest *aRequest)
mMustCommit = PR_TRUE;
mRequests -> AppendElement (aRequest);
aRequest -> mPipelinedRequest = this;
if (count == 0)
mCurReq = aRequest;
if (mBufferSegmentSize < aRequest -> mBufferSegmentSize)
mBufferSegmentSize = aRequest -> mBufferSegmentSize;
@ -888,6 +914,13 @@ nsHTTPPipelinedRequest::GetMustCommit (PRBool * o_Val)
return NS_OK;
}
nsresult
nsHTTPPipelinedRequest::SetMustCommit (PRBool val)
{
mMustCommit = val;
return NS_OK;
}
nsresult
nsHTTPPipelinedRequest::AdvanceToNextRequest ()
{
@ -902,11 +935,12 @@ nsHTTPPipelinedRequest::AdvanceToNextRequest ()
req = (nsHTTPRequest *) mRequests -> ElementAt (0);
if (req)
{
mTransport -> SetNotificationCallbacks (nsnull);
req -> mPipelinedRequest = nsnull;
mRequests -> RemoveElement (req);
NS_RELEASE (req);
mTotalProcessed++;
}
mRequests -> Count (&count);
@ -919,6 +953,7 @@ nsHTTPPipelinedRequest::AdvanceToNextRequest ()
if (req)
{
mTransport -> SetNotificationCallbacks (req -> mConnection);
NS_RELEASE (req);
}

Просмотреть файл

@ -38,6 +38,7 @@
class nsIInputStream;
class nsHTTPChannel;
class nsHTTPResponseListener;
/*
The nsHTTPRequest class is the request object created for each HTTP
@ -166,6 +167,7 @@ protected:
nsHTTPHandler* mHandler;
nsresult mAbortStatus;
PRBool mHeadersFormed;
};
class nsHTTPPipelinedRequest : public nsIStreamObserver
@ -188,6 +190,7 @@ public:
nsresult GetRequestCount (PRUint32 * aReqCount);
nsresult GetMustCommit (PRBool * aMustCommit);
nsresult SetMustCommit (PRBool aMustCommit);
nsresult GetSameRequest(const char *host, PRInt32 port, PRBool * aSame);
nsresult GetCurrentRequest (nsHTTPRequest ** o_Req);
@ -209,10 +212,12 @@ protected:
PRUint32 mBufferMaxSize;
PRBool mMustCommit;
PRUint32 mTotalWritten;
PRUint32 mTotalProcessed;
private:
nsCOMPtr<nsISupportsArray> mRequests;
nsHTTPRequest* mCurReq;
nsHTTPHandler* mHandler;
nsCString mRequestBuffer;
@ -220,6 +225,9 @@ private:
nsXPIDLCString mHost;
PRInt32 mPort;
nsHTTPResponseListener* mListener;
PRBool mOnStopDone;
};
#endif /* _nsHTTPRequest_h_ */

Просмотреть файл

@ -317,19 +317,22 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
mResponse -> GetStatus (&statusCode);
if (statusCode == 304) // no content
{
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (channel, &rv);
// XXX/ruslan: will be replace with the new Cancel (code)
if (NS_SUCCEEDED (rv))
rv = mPipelinedRequest -> AdvanceToNextRequest ();
if (NS_FAILED (rv))
{
PRUint32 count = 0;
mPipelinedRequest -> GetRequestCount (&count);
mHandler -> ReleasePipelinedRequest (mPipelinedRequest);
mPipelinedRequest = nsnull;
if (count == 1)
trans -> SetBytesExpected (0);
else
OnStopRequest (nsnull, context, NS_OK, nsnull);
}
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (channel, &rv);
// XXX/ruslan: will be replaced with the new Cancel (code)
if (NS_SUCCEEDED (rv))
trans -> SetBytesExpected (0);
}
else
{
OnStartRequest (nsnull, nsnull);
}
}
}
}
@ -392,6 +395,7 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
if (!mChunkHeaderChecked)
{
mChunkHeaderChecked = PR_TRUE;
mChunkHeaderEOF = PR_FALSE;
nsXPIDLCString chunkHeader;
rv = mResponse -> GetHeader (nsHTTPAtoms::Transfer_Encoding, getter_Copies (chunkHeader));
@ -410,48 +414,53 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
fromStr.GetUnicode(),
toStr.GetUnicode(),
mResponseDataListener,
channel,
(nsISupports *) &mChunkHeaderEOF, // XXX/ruslan: hack for now - FIX ME
getter_AddRefs (converterListener));
if (NS_FAILED(rv)) return rv;
mResponseDataListener = converterListener;
}
}
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
("\tOnDataAvailable [this=%x]. Calling consumer "
"OnDataAvailable.\tlength:%d\n", this, i_Length));
rv = mResponseDataListener->OnDataAvailable(mChannel,
mChannel->mResponseContext,
i_pStream, 0, i_Length);
if (NS_FAILED(rv)) {
PR_LOG(gHTTPLog, PR_LOG_ERROR,
("\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)
if (cl != -1 && cl - mBodyBytesReceived == 0 || mChunkHeaderEOF)
{
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (channel, &rv);
// XXX/ruslan: will be replaced with the new Cancel (code)
if (NS_SUCCEEDED (rv))
rv = mPipelinedRequest -> AdvanceToNextRequest ();
if (NS_FAILED (rv))
{
PRUint32 count = 0;
mPipelinedRequest -> GetRequestCount (&count);
mHandler -> ReleasePipelinedRequest (mPipelinedRequest);
mPipelinedRequest = nsnull;
if (count == 1)
trans -> SetBytesExpected (0);
else
OnStopRequest (nsnull, context, NS_OK, nsnull);
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (channel, &rv);
// XXX/ruslan: will be replaced with the new Cancel (code)
if (NS_SUCCEEDED (rv))
trans -> SetBytesExpected (0);
rv = mResponseDataListener -> OnDataAvailable (mChannel, mChannel -> mResponseContext, i_pStream, 0, i_Length);
}
else
{
rv = mResponseDataListener -> OnDataAvailable (mChannel, mChannel -> mResponseContext, i_pStream, 0, i_Length);
PRUint32 status = 0;
if (mResponse)
mResponse -> GetStatus(&status);
if (status != 304 || !mChannel -> mCachedResponse)
{
mChannel -> ResponseCompleted (mResponseDataListener, NS_OK, nsnull);
mChannel -> mHTTPServerListener = 0;
}
OnStartRequest (nsnull, nsnull);
}
}
else
rv = mResponseDataListener -> OnDataAvailable (mChannel, mChannel -> mResponseContext, i_pStream, 0, i_Length);
}
}
} // end !mChannel->mOpenObserver
@ -473,6 +482,7 @@ nsHTTPServerListener::OnStartRequest (nsIChannel* channel, nsISupports* i_pConte
mChunkHeaderChecked = PR_FALSE;
mBytesReceived = 0;
mBodyBytesReceived = 0;
mHeaderBuffer.Truncate ();
NS_IF_RELEASE (mResponse);
NS_IF_RELEASE ( mChannel);
@ -528,7 +538,6 @@ nsHTTPServerListener::OnStopRequest (nsIChannel* channel, nsISupports* i_pContex
if (mChannel)
{
PRUint32 status = 0;
if (mResponse)
mResponse -> GetStatus(&status);
@ -538,28 +547,6 @@ nsHTTPServerListener::OnStopRequest (nsIChannel* channel, nsISupports* i_pContex
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 && channel) // this is the actual response from the transport
@ -596,6 +583,19 @@ nsHTTPServerListener::OnStopRequest (nsIChannel* channel, nsISupports* i_pContex
}
}
if (mPipelinedRequest)
{
while (NS_SUCCEEDED (mPipelinedRequest -> AdvanceToNextRequest ()))
{
OnStartRequest (nsnull, nsnull);
mChannel -> ResponseCompleted (mResponseDataListener, i_Status, i_pMsg);
mChannel -> mHTTPServerListener = 0;
}
mHandler -> ReleasePipelinedRequest (mPipelinedRequest);
mPipelinedRequest = nsnull;
}
if (channel)
mHandler -> ReleaseTransport (channel, capabilities);
}

Просмотреть файл

@ -122,6 +122,7 @@ protected:
PRBool mCompressHeaderChecked;
PRBool mChunkHeaderChecked;
PRBool mChunkHeaderEOF;
nsHTTPPipelinedRequest* mPipelinedRequest;
};

Просмотреть файл

@ -25,7 +25,6 @@
#include "plstr.h"
#include "prlog.h"
#include "nsIChannel.h"
#include "nsISocketTransport.h"
#include "nsCOMPtr.h"
#include "nsIByteArrayInputStream.h"
#include "nsIStringStream.h"
@ -200,11 +199,9 @@ nsHTTPChunkConv::OnDataAvailable (
}
else
{
nsresult rv;
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (mAsyncConvContext, &rv);
if (NS_SUCCEEDED (rv))
trans -> SetBytesExpected (0);
PRBool * eof = (PRBool *) mAsyncConvContext;
if (eof != NULL)
*eof = PR_TRUE;
}
mState = CHUNK_STATE_INIT;

Просмотреть файл

@ -85,7 +85,7 @@ private:
char mLenBuf[20];
PRUint32 mLenBufCnt;
nsCOMPtr<nsISupports> mAsyncConvContext;
void * mAsyncConvContext;
};

Просмотреть файл

@ -143,7 +143,7 @@ nsHTTPCompressConv::OnDataAvailable (
mInpBuffer = (unsigned char *) nsAllocator::Realloc (mInpBuffer, mInpBufferLen = streamLen);
if (mOutBufferLen < streamLen * 2)
mInpBuffer = (unsigned char *) nsAllocator::Realloc (mOutBuffer, mInpBufferLen = streamLen * 3);
mOutBuffer = (unsigned char *) nsAllocator::Realloc (mOutBuffer, mOutBufferLen = streamLen * 3);
if (mInpBuffer == NULL || mOutBuffer == NULL)
return NS_ERROR_OUT_OF_MEMORY;