Fix for link-click problem
git-svn-id: svn://10.0.0.236/branches/linkclickfix_tmp_branch@65508 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -27,6 +27,16 @@ interface nsISocketTransport : nsISupports
|
||||
{
|
||||
attribute boolean reuseConnection;
|
||||
|
||||
/**
|
||||
* socket read/write timeout in seconds; 0 = no timeout
|
||||
*/
|
||||
attribute unsigned long socketTimeout;
|
||||
|
||||
/**
|
||||
* socket connect timeout in seconds; 0 = no timeout
|
||||
*/
|
||||
attribute unsigned long socketConnectTimeout;
|
||||
|
||||
/**
|
||||
* Is used to tell the channel to stop reading data after a certain point;
|
||||
* needed by HTTP/1.1
|
||||
@@ -39,7 +49,7 @@ interface nsISocketTransport : nsISupports
|
||||
*
|
||||
* @param seconds amount of time after which the socket is always deemed to be
|
||||
* dead (no further checking is done in this case); seconds = 0
|
||||
* will cause it not to do timeout checking at all
|
||||
* will cause it not to do the timeout checking at all
|
||||
*/
|
||||
boolean isAlive (in unsigned long seconds);
|
||||
};
|
||||
|
||||
@@ -98,7 +98,6 @@ nsSocketState gStateTable[eSocketOperation_Max][eSocketState_Max] = {
|
||||
#define CONNECT_TIMEOUT_IN_MS 20
|
||||
|
||||
static PRIntervalTime gConnectTimeout = PR_INTERVAL_NO_WAIT;
|
||||
static PRIntervalTime gTimeoutInterval = PR_INTERVAL_NO_WAIT;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
@@ -143,7 +142,9 @@ nsSocketTransport::nsSocketTransport():
|
||||
mWriteBufferIndex(0),
|
||||
mWriteBufferLength(0),
|
||||
mBufferSegmentSize(0),
|
||||
mBufferMaxSize(0)
|
||||
mBufferMaxSize(0),
|
||||
mSocketTimeout (PR_INTERVAL_NO_TIMEOUT),
|
||||
mSocketConnectTimeout (PR_MillisecondsToInterval (DEFAULT_SOCKET_CONNECT_TIMEOUT_IN_MS))
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
@@ -308,16 +309,17 @@ nsresult nsSocketTransport::CheckForTimeout (PRIntervalTime aCurrentTime)
|
||||
|
||||
idleInterval = aCurrentTime - mLastActiveTime;
|
||||
|
||||
//
|
||||
// Only timeout if the transport is waiting to connect to the server
|
||||
//
|
||||
if ((mCurrentState == eSocketState_WaitConnect)
|
||||
&& idleInterval >= gTimeoutInterval)
|
||||
if (mSocketConnectTimeout != PR_INTERVAL_NO_TIMEOUT && mCurrentState == eSocketState_WaitConnect
|
||||
&& idleInterval >= mSocketConnectTimeout
|
||||
||
|
||||
mSocketTimeout != PR_INTERVAL_NO_TIMEOUT && mCurrentState == eSocketState_WaitReadWrite
|
||||
&& idleInterval >= mSocketTimeout)
|
||||
{
|
||||
PR_LOG(gSocketLog, PR_LOG_ERROR,
|
||||
("nsSocketTransport::CheckForTimeout() [%s:%d %x].\t"
|
||||
"TIMED OUT... Idle interval: %d\n",
|
||||
mHostName, mPort, this, idleInterval));
|
||||
PR_LOG (
|
||||
gSocketLog, PR_LOG_ERROR, ("nsSocketTransport::CheckForTimeout() [%s:%d %x].\t"
|
||||
"TIMED OUT... Idle interval: %d\n",
|
||||
mHostName, mPort, this, idleInterval)
|
||||
);
|
||||
|
||||
// Move the transport into the Timeout state...
|
||||
mCurrentState = eSocketState_Timeout;
|
||||
@@ -1254,12 +1256,6 @@ nsresult nsSocketTransport::CloseConnection(PRBool bNow)
|
||||
}
|
||||
|
||||
|
||||
void nsSocketTransport::SetSocketTimeout(PRIntervalTime aTimeInterval)
|
||||
{
|
||||
gTimeoutInterval = aTimeInterval;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// nsISupports implementation...
|
||||
@@ -2156,28 +2152,6 @@ nsSocketTransport::SetNotificationCallbacks(nsIInterfaceRequestor* aNotification
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSocketTransport::fireStatus(PRUint32 aCode)
|
||||
{
|
||||
// need to optimize this - TODO
|
||||
nsXPIDLString tempmesg;
|
||||
nsresult rv = GetSocketErrorString(aCode, getter_Copies(tempmesg));
|
||||
|
||||
nsAutoString mesg(tempmesg);
|
||||
if (mPrintHost)
|
||||
mesg.AppendWithConversion(mPrintHost);
|
||||
else
|
||||
mesg.AppendWithConversion(mHostName);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return mEventSink ? mEventSink->OnStatus(this,
|
||||
mReadContext,
|
||||
mesg.GetUnicode()) // this gets freed elsewhere.
|
||||
: NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::IsAlive (PRUint32 seconds, PRBool *alive)
|
||||
{
|
||||
@@ -2197,11 +2171,11 @@ nsSocketTransport::IsAlive (PRUint32 seconds, PRBool *alive)
|
||||
static char c;
|
||||
PRInt32 rval = PR_Read (mSocketFD, &c, 0);
|
||||
|
||||
if (rval <= 0)
|
||||
if (rval < 0)
|
||||
{
|
||||
PRErrorCode code = PR_GetError ();
|
||||
|
||||
if (rval < 0 && code != PR_WOULD_BLOCK_ERROR)
|
||||
if (code != PR_WOULD_BLOCK_ERROR)
|
||||
*alive = PR_FALSE;
|
||||
}
|
||||
}
|
||||
@@ -2211,6 +2185,75 @@ nsSocketTransport::IsAlive (PRUint32 seconds, PRBool *alive)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::GetSocketTimeout (PRUint32 * o_Seconds)
|
||||
{
|
||||
if (o_Seconds == NULL)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mSocketTimeout == PR_INTERVAL_NO_TIMEOUT)
|
||||
*o_Seconds = 0;
|
||||
else
|
||||
*o_Seconds = PR_IntervalToSeconds (mSocketTimeout);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::SetSocketTimeout (PRUint32 a_Seconds)
|
||||
{
|
||||
if (a_Seconds == 0)
|
||||
mSocketTimeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
else
|
||||
mSocketTimeout = PR_SecondsToInterval (a_Seconds);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::GetSocketConnectTimeout (PRUint32 * o_Seconds)
|
||||
{
|
||||
if (o_Seconds == NULL)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mSocketConnectTimeout == PR_INTERVAL_NO_TIMEOUT)
|
||||
*o_Seconds = 0;
|
||||
else
|
||||
*o_Seconds = PR_IntervalToSeconds (mSocketConnectTimeout);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::SetSocketConnectTimeout (PRUint32 a_Seconds)
|
||||
{
|
||||
if (a_Seconds == 0)
|
||||
mSocketConnectTimeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
else
|
||||
mSocketConnectTimeout = PR_SecondsToInterval (a_Seconds);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSocketTransport::fireStatus(PRUint32 aCode)
|
||||
{
|
||||
// need to optimize this - TODO
|
||||
nsXPIDLString tempmesg;
|
||||
nsresult rv = GetSocketErrorString(aCode, getter_Copies(tempmesg));
|
||||
|
||||
nsAutoString mesg(tempmesg);
|
||||
if (mPrintHost)
|
||||
mesg.AppendWithConversion(mPrintHost);
|
||||
else
|
||||
mesg.AppendWithConversion(mHostName);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return mEventSink ? mEventSink->OnStatus(this,
|
||||
mReadContext,
|
||||
mesg.GetUnicode()) // this gets freed elsewhere.
|
||||
: NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//TODO l10n and i18n stuff here!
|
||||
nsresult
|
||||
nsSocketTransport::GetSocketErrorString(PRUint32 iCode,
|
||||
|
||||
@@ -106,6 +106,12 @@ enum nsSocketReadWriteInfo {
|
||||
eSocketDNS_Wait = 0x2020
|
||||
};
|
||||
|
||||
//
|
||||
// This is the default timeout value (in milliseconds) for sockets which have
|
||||
// no activity...
|
||||
//
|
||||
#define DEFAULT_SOCKET_CONNECT_TIMEOUT_IN_MS 35*1000
|
||||
|
||||
// Forward declarations...
|
||||
class nsSocketTransportService;
|
||||
class nsIInterfaceRequestor;
|
||||
@@ -137,7 +143,7 @@ public:
|
||||
|
||||
nsresult Process(PRInt16 aSelectFlags);
|
||||
|
||||
nsresult CheckForTimeout(PRIntervalTime aCurrentTime);
|
||||
nsresult CheckForTimeout (PRIntervalTime aCurrentTime);
|
||||
|
||||
// Close this socket either right away or once done with the transaction.
|
||||
nsresult CloseConnection(PRBool bNow=PR_TRUE);
|
||||
@@ -149,8 +155,6 @@ public:
|
||||
|
||||
static nsSocketTransport* GetInstance(PRCList* qp) { return (nsSocketTransport*)((char*)qp - offsetof(nsSocketTransport, mListLink)); }
|
||||
|
||||
static void SetSocketTimeout(PRIntervalTime aTimeoutInterval);
|
||||
|
||||
PRBool CanBeReused(void) { return
|
||||
(mCurrentState != eSocketState_Error) && !mCloseConnectionOnceDone;}
|
||||
|
||||
@@ -167,6 +171,9 @@ protected:
|
||||
nsresult GetSocketErrorString(PRUint32 iCode, PRUnichar** oString) const;
|
||||
|
||||
private:
|
||||
PRIntervalTime mSocketTimeout;
|
||||
PRIntervalTime mSocketConnectTimeout;
|
||||
|
||||
// Access methods for manipulating the ReadWriteInfo...
|
||||
inline void SetReadType(nsSocketReadWriteInfo aType) {
|
||||
mReadWriteState = (mReadWriteState & ~eSocketRead_Type_Mask) | aType;
|
||||
|
||||
@@ -49,8 +49,6 @@ nsSocketTransportService::nsSocketTransportService()
|
||||
mActiveTransportList = nsnull;
|
||||
|
||||
mThreadRunning = PR_FALSE;
|
||||
|
||||
SetSocketTimeoutInterval(PR_MillisecondsToInterval(DEFAULT_SOCKET_TIMEOUT_IN_MS));
|
||||
}
|
||||
|
||||
|
||||
@@ -345,24 +343,6 @@ nsresult nsSocketTransportService::RemoveFromSelectList(nsSocketTransport* aTran
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsSocketTransportService::GetSocketTimeoutInterval(PRIntervalTime* aResult)
|
||||
{
|
||||
*aResult = mSocketTimeoutInterval;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSocketTransportService::SetSocketTimeoutInterval(PRIntervalTime aTime)
|
||||
{
|
||||
mSocketTimeoutInterval = aTime;
|
||||
|
||||
// Update the timeout value in the socket transport...
|
||||
nsSocketTransport::SetSocketTimeout(aTime);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// nsISupports implementation...
|
||||
@@ -389,7 +369,7 @@ nsSocketTransportService::Run(void)
|
||||
mSelectFDSet[0].fd = mThreadEvent;
|
||||
mSelectFDSet[0].in_flags = PR_POLL_READ;
|
||||
mSelectFDSetCount = 1;
|
||||
pollTimeout = mSocketTimeoutInterval;
|
||||
pollTimeout = PR_MillisecondsToInterval (DEFAULT_POLL_TIMEOUT_IN_MS);
|
||||
#else
|
||||
//
|
||||
// For now, rather than breaking out of the call to PR_Poll(...) just set
|
||||
|
||||
@@ -38,17 +38,12 @@
|
||||
#define USE_POLLABLE_EVENT
|
||||
#endif
|
||||
|
||||
//
|
||||
// This is the default timeout value (in milliseconds) for sockets which have
|
||||
// no activity...
|
||||
//
|
||||
#define DEFAULT_SOCKET_TIMEOUT_IN_MS 35*1000
|
||||
|
||||
//
|
||||
// This is the Maximum number of Socket Transport instances that can be active
|
||||
// at once...
|
||||
//
|
||||
#define MAX_OPEN_CONNECTIONS 50
|
||||
#define DEFAULT_POLL_TIMEOUT_IN_MS 35*1000
|
||||
|
||||
|
||||
// Forward declarations...
|
||||
@@ -89,8 +84,6 @@ protected:
|
||||
PRLock* mThreadLock;
|
||||
PRBool mThreadRunning;
|
||||
|
||||
PRIntervalTime mSocketTimeoutInterval;
|
||||
|
||||
PRCList mWorkQ;
|
||||
|
||||
PRInt32 mSelectFDSetCount;
|
||||
|
||||
@@ -97,7 +97,8 @@ nsHTTPChannel::nsHTTPChannel(nsIURI* i_URL, nsHTTPHandler* i_Handler):
|
||||
mBufferSegmentSize(0),
|
||||
mBufferMaxSize(0),
|
||||
mStatus(NS_OK),
|
||||
mPipeliningAllowed (PR_TRUE)
|
||||
mPipeliningAllowed (PR_TRUE),
|
||||
mPipelinedRequest (nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
@@ -1327,17 +1328,24 @@ nsHTTPChannel::Open(void)
|
||||
|
||||
if (NS_ERROR_BUSY == rv)
|
||||
{
|
||||
mPipelinedRequest = pReq;
|
||||
if (!mPipelinedRequest)
|
||||
{
|
||||
mPipelinedRequest = pReq;
|
||||
NS_RELEASE (pReq);
|
||||
}
|
||||
|
||||
mState = HS_WAITING_FOR_OPEN;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mPipelinedRequest)
|
||||
NS_RELEASE (pReq);
|
||||
|
||||
if (NS_FAILED (rv))
|
||||
{
|
||||
ResponseCompleted (mResponseDataListener, rv, nsnull);
|
||||
return rv;
|
||||
}
|
||||
NS_RELEASE (pReq);
|
||||
}
|
||||
|
||||
mState = HS_WAITING_FOR_RESPONSE;
|
||||
|
||||
@@ -601,7 +601,9 @@ nsHTTPHandler::nsHTTPHandler():
|
||||
mCapabilities (DEFAULT_ALLOWED_CAPABILITIES ),
|
||||
mKeepAliveTimeout (DEFAULT_KEEP_ALIVE_TIMEOUT),
|
||||
mMaxConnections (MAX_NUMBER_OF_OPEN_TRANSPORTS),
|
||||
mReferrerLevel(0)
|
||||
mReferrerLevel (0),
|
||||
mRequestTimeout (DEFAULT_HTTP_REQUEST_TIMEOUT),
|
||||
mConnectTimeout (DEFAULT_HTTP_CONNECT_TIMEOUT)
|
||||
{
|
||||
NS_INIT_REFCNT ();
|
||||
SetAcceptEncodings (DEFAULT_ACCEPT_ENCODINGS);
|
||||
@@ -970,13 +972,21 @@ nsresult nsHTTPHandler::CreateTransport(const char* host,
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsISocketTransportService, sts,
|
||||
kSocketTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_WITH_SERVICE (nsISocketTransportService, sts, kSocketTransportServiceCID, &rv);
|
||||
if (NS_FAILED (rv))
|
||||
return rv;
|
||||
|
||||
return sts->CreateTransport(host, port, aPrintHost,
|
||||
bufferSegmentSize, bufferMaxSize,
|
||||
o_pTrans);
|
||||
rv = sts -> CreateTransport (host, port, aPrintHost, bufferSegmentSize, bufferMaxSize, o_pTrans);
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (*o_pTrans, &rv);
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
trans -> SetSocketTimeout (mRequestTimeout);
|
||||
trans -> SetSocketConnectTimeout (mConnectTimeout);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsHTTPHandler::ReleaseTransport (nsIChannel* i_pTrans, PRUint32 aCapabilities)
|
||||
@@ -1225,6 +1235,9 @@ nsHTTPHandler::PrefsChanged(const char* pref)
|
||||
mCapabilities &= ~ALLOW_PROXY_PIPELINING;
|
||||
}
|
||||
|
||||
mPrefs -> GetIntPref ("network.http.connect.timeout", &mConnectTimeout);
|
||||
mPrefs -> GetIntPref ("network.http.request.timeout", &mRequestTimeout);
|
||||
|
||||
// Things read only during initialization...
|
||||
if (bChangedAll) // intl.accept_languages
|
||||
{
|
||||
|
||||
@@ -61,6 +61,9 @@ class nsHTTPChannel;
|
||||
// because of HTTP/1.1 is default now
|
||||
#define DEFAULT_ALLOWED_CAPABILITIES (DEFAULT_PROXY_CAPABILITIES|DEFAULT_SERVER_CAPABILITIES)
|
||||
|
||||
#define DEFAULT_HTTP_REQUEST_TIMEOUT 30
|
||||
#define DEFAULT_HTTP_CONNECT_TIMEOUT 30
|
||||
|
||||
class nsHTTPPipelinedRequest;
|
||||
class nsIHTTPChannel;
|
||||
|
||||
@@ -155,6 +158,9 @@ protected:
|
||||
private:
|
||||
|
||||
nsHashtable mCapTable;
|
||||
PRInt32 mRequestTimeout;
|
||||
PRInt32 mConnectTimeout;
|
||||
|
||||
PRUint32 getCapabilities (const char *host, PRInt32 port, PRUint32 cap);
|
||||
void setCapabilities (nsIChannel* i_pTrans, PRUint32 aCapabilities);
|
||||
|
||||
|
||||
@@ -579,9 +579,12 @@ nsHTTPPipelinedRequest::WriteRequest ()
|
||||
|
||||
if (!mTransport)
|
||||
{
|
||||
PRUint32 tMode = mAttempts ? TRANSPORT_OPEN_ALWAYS : TRANSPORT_REUSE_ALIVE;
|
||||
if (mPostDataStream)
|
||||
tMode &= ~(TRANSPORT_REUSE_ALIVE);
|
||||
|
||||
rv = mHandler -> RequestTransport (req -> mURI, req -> mConnection, mBufferSegmentSize, mBufferMaxSize,
|
||||
getter_AddRefs (mTransport),
|
||||
mAttempts ? TRANSPORT_OPEN_ALWAYS : TRANSPORT_REUSE_ALIVE);
|
||||
getter_AddRefs (mTransport), tMode);
|
||||
|
||||
if (NS_FAILED (rv))
|
||||
{
|
||||
@@ -669,10 +672,13 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (mTransport, &rv);
|
||||
|
||||
mOnStopDone = PR_TRUE;
|
||||
nsHTTPRequest * req = (nsHTTPRequest *) mRequests -> ElementAt (0);
|
||||
|
||||
rv = iStatus;
|
||||
|
||||
PR_LOG (gHTTPLog, PR_LOG_DEBUG, ("\nnsHTTPRequest::OnStopRequest () [this=%x], iStatus=%u\n", this, iStatus));
|
||||
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
PRBool isAlive = PR_TRUE;
|
||||
@@ -715,7 +721,7 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
|
||||
else
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mOnStopDone = PR_TRUE;
|
||||
|
||||
WriteRequest (); // write again to see if anything else is queued up
|
||||
}
|
||||
}
|
||||
@@ -739,7 +745,7 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
|
||||
//
|
||||
if (NS_FAILED (rv))
|
||||
{
|
||||
if (mListener == nsnull)
|
||||
if (mTotalProcessed == 0 && mAttempts == 0)
|
||||
{
|
||||
// the pipeline just started - we still can attempt to recover
|
||||
|
||||
@@ -755,7 +761,6 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
|
||||
{
|
||||
mAttempts++;
|
||||
mTotalWritten = 0;
|
||||
mOnStopDone = PR_TRUE;
|
||||
|
||||
rv = WriteRequest ();
|
||||
|
||||
@@ -766,6 +771,11 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mHandler -> ReleaseTransport (mTransport, 0);
|
||||
mTransport = null_nsCOMPtr ();
|
||||
}
|
||||
|
||||
// Notify the HTTPChannel that the request has finished
|
||||
nsCOMPtr<nsIStreamListener> consumer;
|
||||
@@ -785,6 +795,43 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTTPPipelinedRequest::RestartRequest ()
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
PR_LOG (gHTTPLog, PR_LOG_DEBUG, ("\nnsHTTPPipelinedRequest::RestartRequest () [this=%x], mTotalProcessed=%u\n", this, mTotalProcessed));
|
||||
|
||||
if (mTotalProcessed == 0)
|
||||
{
|
||||
// the pipeline just started - we still can attempt to recover
|
||||
|
||||
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (mTransport, &rv);
|
||||
PRUint32 wasKeptAlive = 0;
|
||||
|
||||
if (trans)
|
||||
trans -> GetReuseCount (&wasKeptAlive);
|
||||
|
||||
if (wasKeptAlive && mAttempts == 0)
|
||||
{
|
||||
rv = NS_OK;
|
||||
mListener = nsnull;
|
||||
|
||||
if (mOnStopDone)
|
||||
{
|
||||
mHandler -> ReleaseTransport (mTransport, 0);
|
||||
mTransport = null_nsCOMPtr ();
|
||||
|
||||
mTotalWritten = 0;
|
||||
|
||||
mAttempts++;
|
||||
rv = WriteRequest ();
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTTPPipelinedRequest::IsPending (PRBool *result)
|
||||
{
|
||||
|
||||
@@ -195,6 +195,7 @@ public:
|
||||
|
||||
nsresult GetCurrentRequest (nsHTTPRequest ** o_Req);
|
||||
nsresult AdvanceToNextRequest ();
|
||||
nsresult RestartRequest ();
|
||||
|
||||
nsresult IsPending (PRBool *result);
|
||||
nsresult Cancel (nsresult status );
|
||||
|
||||
@@ -220,7 +220,8 @@ nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandle
|
||||
mCompressHeaderChecked (PR_FALSE),
|
||||
mChunkHeaderEOF(PR_FALSE),
|
||||
mChunkHeaderChecked (PR_FALSE),
|
||||
mPipelinedRequest (request)
|
||||
mPipelinedRequest (request),
|
||||
mDataReceived (PR_FALSE)
|
||||
{
|
||||
nsHTTPRequest * req = nsnull;
|
||||
mChannel -> mHTTPServerListener = this;
|
||||
@@ -264,6 +265,9 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
|
||||
"\tstream=%x. \toffset=%d. \tlength=%d.\n",
|
||||
this, i_pStream, i_SourceOffset, i_Length));
|
||||
|
||||
if (i_Length > 0)
|
||||
mDataReceived = PR_TRUE;
|
||||
|
||||
if (!mResponse)
|
||||
{
|
||||
mResponse = new nsHTTPResponse ();
|
||||
@@ -486,6 +490,7 @@ nsHTTPServerListener::OnStartRequest (nsIChannel* channel, nsISupports* i_pConte
|
||||
mCompressHeaderChecked = PR_FALSE;
|
||||
mChunkHeaderEOF = PR_FALSE;
|
||||
mChunkHeaderChecked = PR_FALSE;
|
||||
mDataReceived = PR_FALSE;
|
||||
mBytesReceived = 0;
|
||||
mBodyBytesReceived = 0;
|
||||
mHeaderBuffer.Truncate ();
|
||||
@@ -523,6 +528,19 @@ nsHTTPServerListener::OnStopRequest (nsIChannel* channel, nsISupports* i_pContex
|
||||
("nsHTTPServerListener::OnStopRequest [this=%x]."
|
||||
"\tStatus = %x\n", this, i_Status));
|
||||
|
||||
if (!mDataReceived)
|
||||
{
|
||||
// no data has been received from the channel at all - must be due to the fact that the
|
||||
// server has dropped the connection on keep-alive
|
||||
|
||||
if (mPipelinedRequest)
|
||||
{
|
||||
nsresult rv = mPipelinedRequest -> RestartRequest ();
|
||||
if (NS_SUCCEEDED (rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !mHeadersDone)
|
||||
{
|
||||
//
|
||||
|
||||
@@ -122,6 +122,7 @@ protected:
|
||||
|
||||
PRBool mCompressHeaderChecked;
|
||||
PRBool mChunkHeaderChecked;
|
||||
PRBool mDataReceived;
|
||||
PRBool mChunkHeaderEOF;
|
||||
nsHTTPPipelinedRequest* mPipelinedRequest;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user