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:
darin%netscape.com 2002-05-24 00:12:28 +00:00
Родитель 1efbe564f5
Коммит 86d64025f7
4 изменённых файлов: 53 добавлений и 6 удалений

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

@ -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.
//