зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
81e3d6e157
Коммит
2f521bf728
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче