зеркало из https://github.com/mozilla/pjs.git
fixes bug 144442 "Microsoft-IIS/4.x and Netscape-Enterprise/3.x do not support pipelining"
r=gagan sr=rpotts
This commit is contained in:
Родитель
1efbe564f5
Коммит
86d64025f7
|
@ -55,11 +55,11 @@ nsHttpConnection::nsHttpConnection()
|
|||
, mReadStartTime(0)
|
||||
, mLastActiveTime(0)
|
||||
, mIdleTimeout(0)
|
||||
, mServerVersion(NS_HTTP_VERSION_1_0) // assume low-grade server
|
||||
, mKeepAlive(1) // assume to keep-alive by default
|
||||
, mKeepAliveMask(1)
|
||||
, mWriteDone(0)
|
||||
, mReadDone(0)
|
||||
, mSupportsPipelining(PR_FALSE) // assume low-grade server
|
||||
{
|
||||
LOG(("Creating nsHttpConnection @%x\n", this));
|
||||
|
||||
|
@ -165,6 +165,43 @@ nsHttpConnection::IsAlive()
|
|||
return isAlive;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHttpConnection::SupportsPipelining(nsHttpResponseHead *responseHead)
|
||||
{
|
||||
// XXX there should be a strict mode available that disables this
|
||||
// blacklisting.
|
||||
|
||||
// assuming connection is HTTP/1.1 with keep-alive enabled
|
||||
if (mConnectionInfo->UsingHttpProxy() && !mConnectionInfo->UsingSSL()) {
|
||||
// XXX check for bad proxy servers...
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// XXX what about checking for a Via header? (transparent proxies)
|
||||
|
||||
// check for bad origin servers
|
||||
const char *val = responseHead->PeekHeader(nsHttp::Server);
|
||||
if (!val)
|
||||
return PR_FALSE; // no header, no love
|
||||
|
||||
// the list of servers known to do bad things with pipelined requests
|
||||
static const char *bad_servers[] = {
|
||||
"Microsoft-IIS/4.",
|
||||
"Netscape-Enterprise/3.",
|
||||
nsnull
|
||||
};
|
||||
|
||||
for (const char **server = bad_servers; *server; ++server) {
|
||||
if (PL_strcasestr(val, *server) != nsnull) {
|
||||
LOG(("looks like this server does not support pipelining"));
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, let's allow pipelining to this server
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsHttpConnection::nsAHttpConnection
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -195,7 +232,8 @@ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
|
|||
if (!val)
|
||||
val = responseHead->PeekHeader(nsHttp::Proxy_Connection);
|
||||
|
||||
mServerVersion = responseHead->Version();
|
||||
// reset to default (the server may have changed since we last checked)
|
||||
mSupportsPipelining = PR_FALSE;
|
||||
|
||||
if ((responseHead->Version() < NS_HTTP_VERSION_1_1) ||
|
||||
(requestHead->Version() < NS_HTTP_VERSION_1_1)) {
|
||||
|
@ -209,8 +247,10 @@ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
|
|||
// HTTP/1.1 connections are by default persistent
|
||||
if (val && !PL_strcasecmp(val, "close"))
|
||||
mKeepAlive = PR_FALSE;
|
||||
else
|
||||
else {
|
||||
mKeepAlive = PR_TRUE;
|
||||
mSupportsPipelining = SupportsPipelining(responseHead);
|
||||
}
|
||||
}
|
||||
mKeepAliveMask = mKeepAlive;
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
// called to cause the underlying socket to start speaking SSL
|
||||
nsresult ProxyStepUp();
|
||||
|
||||
PRBool SupportsPipelining() { return mServerVersion > NS_HTTP_VERSION_1_0; }
|
||||
PRBool SupportsPipelining() { return mSupportsPipelining; }
|
||||
PRBool IsKeepAlive() { return mKeepAliveMask && mKeepAlive; }
|
||||
PRBool CanReuse(); // can this connection be reused?
|
||||
void DontReuse() { mKeepAliveMask = PR_FALSE;
|
||||
|
@ -104,6 +104,7 @@ private:
|
|||
nsresult SetupSSLProxyConnect();
|
||||
|
||||
PRBool IsAlive();
|
||||
PRBool SupportsPipelining(nsHttpResponseHead *);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISocketTransport> mSocketTransport;
|
||||
|
@ -122,12 +123,11 @@ private:
|
|||
PRUint16 mMaxHangTime; // max download time before dropping keep-alive status
|
||||
PRUint16 mIdleTimeout; // value of keep-alive: timeout=
|
||||
|
||||
PRUint8 mServerVersion;
|
||||
|
||||
PRPackedBool mKeepAlive;
|
||||
PRPackedBool mKeepAliveMask;
|
||||
PRPackedBool mWriteDone;
|
||||
PRPackedBool mReadDone;
|
||||
PRPackedBool mSupportsPipelining;
|
||||
};
|
||||
|
||||
#endif // nsHttpConnection_h__
|
||||
|
|
|
@ -870,6 +870,12 @@ nsHttpHandler::ProcessTransactionQ_Locked()
|
|||
caps = pipelineState.TransactionCaps();
|
||||
NS_ASSERTION(trans, "no transaction");
|
||||
}
|
||||
#if defined(PR_LOGGING)
|
||||
else
|
||||
LOG(("no pipelining [because-of-server=%d because-of-caps=%d]\n",
|
||||
conn->SupportsPipelining() == PR_FALSE,
|
||||
caps & NS_HTTP_ALLOW_PIPELINING == PR_FALSE));
|
||||
#endif
|
||||
|
||||
//
|
||||
// step 4: dispatch this transaction
|
||||
|
|
|
@ -556,6 +556,7 @@ nsHttpPipeline::OnStopTransaction(nsresult status)
|
|||
if (mConnection) {
|
||||
NS_ASSERTION(PR_GetCurrentThread() == NS_SOCKET_THREAD, "wrong thread");
|
||||
nsAutoLock lock(mLock);
|
||||
// XXX this assertion is wrong!! what about network errors??
|
||||
NS_ASSERTION(mStatus == status, "unexpected status");
|
||||
// reset any transactions that haven't already completed.
|
||||
//
|
||||
|
|
Загрузка…
Ссылка в новой задаче