diff --git a/netwerk/protocol/http/src/nsHttp.h b/netwerk/protocol/http/src/nsHttp.h index 27f8cb351c1..20b4dbaf227 100644 --- a/netwerk/protocol/http/src/nsHttp.h +++ b/netwerk/protocol/http/src/nsHttp.h @@ -44,21 +44,28 @@ extern PRLogModuleInfo *gHttpLog; #endif +// http logging #define LOG1(args) PR_LOG(gHttpLog, 1, args) #define LOG2(args) PR_LOG(gHttpLog, 2, args) #define LOG3(args) PR_LOG(gHttpLog, 3, args) #define LOG4(args) PR_LOG(gHttpLog, 4, args) #define LOG(args) LOG4(args) +// http default buffer geometry #define NS_HTTP_SEGMENT_SIZE 4096 #define NS_HTTP_BUFFER_SIZE 4096*4 // 16k maximum -enum nsHttpVersion { - NS_HTTP_VERSION_UNKNOWN, - NS_HTTP_VERSION_0_9, - NS_HTTP_VERSION_1_0, - NS_HTTP_VERSION_1_1 -}; +// http version codes +#define NS_HTTP_VERSION_UNKNOWN 0 +#define NS_HTTP_VERSION_0_9 9 +#define NS_HTTP_VERSION_1_0 10 +#define NS_HTTP_VERSION_1_1 11 + +typedef PRUint8 nsHttpVersion; + +// http connection capabilities +#define NS_HTTP_ALLOW_KEEPALIVE (1<<0) +#define NS_HTTP_ALLOW_PIPELINING (1<<1) //----------------------------------------------------------------------------- // http atoms... @@ -117,4 +124,8 @@ PRTimeToSeconds(PRTime t_usec) #define NowInSeconds() PRTimeToSeconds(PR_Now()) -#endif +// ripped from glib.h +#undef CLAMP +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +#endif // nsHttp_h__ diff --git a/netwerk/protocol/http/src/nsHttpChannel.cpp b/netwerk/protocol/http/src/nsHttpChannel.cpp index 94c13fe5518..288bfd2548a 100644 --- a/netwerk/protocol/http/src/nsHttpChannel.cpp +++ b/netwerk/protocol/http/src/nsHttpChannel.cpp @@ -52,8 +52,8 @@ nsHttpChannel::nsHttpChannel() , mPrevTransaction(nsnull) , mConnectionInfo(nsnull) , mLoadFlags(LOAD_NORMAL) - , mCapabilities(0) , mStatus(NS_OK) + , mCapabilities(0) , mReferrerType(REFERRER_NONE) , mCachedResponseHead(nsnull) , mCacheAccess(0) @@ -98,7 +98,7 @@ nsHttpChannel::~nsHttpChannel() nsresult nsHttpChannel::Init(nsIURI *uri, - PRUint32 caps, + PRUint8 caps, const char *proxyHost, PRInt32 proxyPort, const char *proxyType) @@ -171,8 +171,7 @@ nsHttpChannel::Init(nsIURI *uri, PRBool useProxy = (proxyHost && !PL_strcmp(proxyType, "http")); rv = nsHttpHandler::get()->AddStandardRequestHeaders(&mRequestHead.Headers(), - caps, - useProxy); + caps, useProxy); if (NS_FAILED(rv)) return rv; // check to see if authorization headers should be included @@ -1922,7 +1921,7 @@ nsHttpChannel::SetReferrer(nsIURI *referrer, PRUint32 referrerType) mReferrer = referrer; // save a copy of the referrer type for redirects - mReferrerType = referrerType; + mReferrerType = (PRUint8) referrerType; // clear the old referer first mRequestHead.SetHeader(nsHttp::Referer, nsnull); diff --git a/netwerk/protocol/http/src/nsHttpChannel.h b/netwerk/protocol/http/src/nsHttpChannel.h index 0e6f879c7c7..df4bf92b71b 100644 --- a/netwerk/protocol/http/src/nsHttpChannel.h +++ b/netwerk/protocol/http/src/nsHttpChannel.h @@ -73,7 +73,7 @@ public: virtual ~nsHttpChannel(); nsresult Init(nsIURI *uri, - PRUint32 capabilities, + PRUint8 capabilities, const char *proxyHost=0, PRInt32 proxyPort=-1, const char *proxyType=0); @@ -133,9 +133,9 @@ private: nsXPIDLCString mSpec; PRUint32 mLoadFlags; - PRUint32 mCapabilities; PRUint32 mStatus; - PRUint32 mReferrerType; + PRUint8 mCapabilities; + PRUint8 mReferrerType; // cache specific data nsCOMPtr mCacheEntry; diff --git a/netwerk/protocol/http/src/nsHttpConnection.cpp b/netwerk/protocol/http/src/nsHttpConnection.cpp index aad14fc21db..3bda741ae1e 100644 --- a/netwerk/protocol/http/src/nsHttpConnection.cpp +++ b/netwerk/protocol/http/src/nsHttpConnection.cpp @@ -47,10 +47,8 @@ nsHttpConnection::nsHttpConnection() : mTransaction(0) , mConnectionInfo(0) , mLock(nsnull) - , mReuseCount(0) - , mMaxReuseCount(0) - , mIdleTimeout(0) , mLastActiveTime(0) + , mIdleTimeout(0) , mKeepAlive(0) , mWriteDone(0) , mReadDone(0) @@ -166,30 +164,20 @@ nsHttpConnection::OnHeadersAvailable(nsHttpTransaction *trans, PRBool *reset) // if this connection is persistent, then the server may send a "Keep-Alive" // header specifying the maximum number of times the connection can be // reused as well as the maximum amount of time the connection can be idle - // before the server will close it. If this header is not present, then we - // pick a suitably large number. Technically, any number > 0 will do, since - // we reset this each time, and with HTTP/1.1 connections continue until we - // get a {Proxy-,}Connection: close header. Don't just use 1 though, because - // of pipelining + // before the server will close it. we ignore the max reuse count, because + // a "keep-alive" connection is by definition capable of being reused, and + // we only care about being able to reuse it once. if a timeout is not + // specified then we use our advertized timeout value. if (mKeepAlive) { val = trans->ResponseHead()->PeekHeader(nsHttp::Keep_Alive); - LOG(("val = [%s]\n", val)); - - const char *cp = PL_strcasestr(val, "max="); - if (cp) - mMaxReuseCount = (PRUint32) atoi(cp + 4); - else - mMaxReuseCount = 100; - - cp = PL_strcasestr(val, "timeout="); + const char *cp = PL_strcasestr(val, "timeout="); if (cp) mIdleTimeout = (PRUint32) atoi(cp + 8); else mIdleTimeout = nsHttpHandler::get()->IdleTimeout(); - LOG(("Connection can be reused [this=%x max-reuse=%u " - "keep-alive-timeout=%u\n", this, mMaxReuseCount, mIdleTimeout)); + LOG(("Connection can be reused [this=%x idle-timeout=%u\n", this, mIdleTimeout)); } // if we're doing an SSL proxy connect, then we need to check whether or not @@ -302,8 +290,8 @@ nsHttpConnection::ProxyStepUp() PRBool nsHttpConnection::CanReuse() { - return mKeepAlive && (mReuseCount < mMaxReuseCount) && - (NowInSeconds() - mLastActiveTime < mIdleTimeout) && IsAlive(); + return mKeepAlive && (NowInSeconds() - mLastActiveTime < mIdleTimeout) + && IsAlive(); } PRBool diff --git a/netwerk/protocol/http/src/nsHttpConnection.h b/netwerk/protocol/http/src/nsHttpConnection.h index 06f38878b28..f6ccec74063 100644 --- a/netwerk/protocol/http/src/nsHttpConnection.h +++ b/netwerk/protocol/http/src/nsHttpConnection.h @@ -86,13 +86,9 @@ public: PRBool CanReuse(); // can this connection be reused? PRBool IsAlive(); PRBool IsKeepAlive() { return mKeepAlive; } - PRUint32 ReuseCount() { return mReuseCount; } - PRUint32 MaxReuseCount() { return mMaxReuseCount; } - PRUint32 IdleTimeout() { return mIdleTimeout; } + PRUint16 IdleTimeout() { return mIdleTimeout; } void DontReuse() { mKeepAlive = PR_FALSE; - mReuseCount = 0; - mMaxReuseCount = 0; mIdleTimeout = 0; } void DropTransaction(); @@ -126,10 +122,8 @@ private: PRLock *mLock; - PRUint32 mReuseCount; - PRUint32 mMaxReuseCount; // value of keep-alive: max= - PRUint32 mIdleTimeout; // value of keep-alive: timeout= PRUint32 mLastActiveTime; + PRUint16 mIdleTimeout; // value of keep-alive: timeout= PRPackedBool mKeepAlive; PRPackedBool mWriteDone; diff --git a/netwerk/protocol/http/src/nsHttpHandler.cpp b/netwerk/protocol/http/src/nsHttpHandler.cpp index 6b679d3be7a..526725683db 100644 --- a/netwerk/protocol/http/src/nsHttpHandler.cpp +++ b/netwerk/protocol/http/src/nsHttpHandler.cpp @@ -86,16 +86,13 @@ nsHttpHandler *nsHttpHandler::mGlobalInstance = 0; nsHttpHandler::nsHttpHandler() : mAuthCache(nsnull) , mHttpVersion(NS_HTTP_VERSION_1_1) - , mReferrerLevel(PRUint32(-1)) // by default we always send a referrer - , mCapabilities(ALLOW_KEEPALIVE) - , mProxyCapabilities(ALLOW_KEEPALIVE) - , mProxySSLConnectAllowed(PR_TRUE) - , mConnectTimeout(30) - , mRequestTimeout(30) + , mReferrerLevel(0xff) // by default we always send a referrer + , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE) + , mProxyCapabilities(NS_HTTP_ALLOW_KEEPALIVE) , mIdleTimeout(10) + , mMaxRequestAttempts(10) , mMaxConnections(16) , mMaxConnectionsPerServer(8) - , mMaxIdleConnections(16) , mMaxIdleConnectionsPerServer(4) , mActiveConnections(0) , mIdleConnections(0) @@ -243,7 +240,7 @@ nsHttpHandler::Init() nsresult nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request, - PRUint32 caps, + PRUint8 caps, PRBool useProxy) { nsresult rv; @@ -275,15 +272,16 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request, // and "Keep-alive" request headers should not be sent by HTTP/1.1 // user-agents. Otherwise, problems with proxy servers (especially // transparent proxies) can result. + // // However, we need to send something so that we can use keepalive - // with HTTP/1.0 servers/proxies. We use Proxy-Connection: when we're - // talking to an http proxy, and Connection: otherwise + // with HTTP/1.0 servers/proxies. We use "Proxy-Connection:" when + // we're talking to an http proxy, and "Connection:" otherwise const char* connectionType = "close"; - if (caps & ALLOW_KEEPALIVE) { + if (caps & NS_HTTP_ALLOW_KEEPALIVE) { char buf[32]; - PR_snprintf(buf, sizeof(buf), "%d", mIdleTimeout); + PR_snprintf(buf, sizeof(buf), "%u", (PRUintn) mIdleTimeout); rv = request->SetHeader(nsHttp::Keep_Alive, buf); if (NS_FAILED(rv)) return rv; @@ -294,8 +292,9 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request, request->SetHeader(nsHttp::Connection, "close"); } - const nsHttpAtom& connAtom = useProxy ? nsHttp::Proxy_Connection : nsHttp::Connection; - return request->SetHeader(connAtom, connectionType); + const nsHttpAtom &header = + useProxy ? nsHttp::Proxy_Connection : nsHttp::Connection; + return request->SetHeader(header, connectionType); } PRBool @@ -632,7 +631,7 @@ nsHttpHandler::ProcessTransactionQ() PRInt32 i; for (i=0; (i < mTransactionQ.Count()) && - (mActiveConnections.Count() < mMaxConnections); ++i) { + (mActiveConnections.Count() < PRInt32(mMaxConnections)); ++i) { pt = (nsPendingTransaction *) mTransactionQ[i]; @@ -677,8 +676,8 @@ nsHttpHandler::InitiateTransaction_Locked(nsHttpTransaction *trans, LOG(("nsHttpHandler::InitiateTransaction_Locked [failIfBusy=%d]\n", failIfBusy)); - if ((mActiveConnections.Count() == mMaxConnections) || - (CountActiveConnections(ci) == PRUint32(mMaxConnectionsPerServer))) { + if ((mActiveConnections.Count() == PRInt32(mMaxConnections)) || + (CountActiveConnections(ci) == mMaxConnectionsPerServer)) { LOG(("unable to perform the transaction at this time [trans=%x]\n", trans)); if (failIfBusy) return NS_ERROR_FAILURE; return EnqueueTransaction(trans, ci); @@ -775,10 +774,10 @@ nsHttpHandler::RemovePendingTransaction(nsHttpTransaction *trans) return NS_ERROR_NOT_AVAILABLE; } -PRUint32 +PRUint8 nsHttpHandler::CountActiveConnections(nsHttpConnectionInfo *ci) { - PRUint32 count = 0; + PRUint8 count = 0; nsHttpConnection *conn = 0; LOG(("nsHttpHandler::CountActiveConnections [host=%s:%d]\n", @@ -792,14 +791,14 @@ nsHttpHandler::CountActiveConnections(nsHttpConnectionInfo *ci) count++; } - LOG(("found count=%u\n", count)); + LOG(("found count=%u\n", (PRUintn) count)); return count; } -PRUint32 +PRUint8 nsHttpHandler::CountIdleConnections(nsHttpConnectionInfo *ci) { - PRUint32 count = 0; + PRUint8 count = 0; nsHttpConnection *conn = 0; if (!ci) @@ -824,7 +823,7 @@ nsHttpHandler::CountIdleConnections(nsHttpConnectionInfo *ci) } } - LOG(("found count=%u\n", count)); + LOG(("found count=%u\n", (PRUintn) count)); return count; } @@ -1049,18 +1048,51 @@ nsHttpHandler::PrefsChanged(const char *pref) } nsresult rv = NS_OK; + PRInt32 val; - if (bChangedAll || PL_strcmp(pref, "network.http.keep-alive.timeout") == 0) - mPrefs->GetIntPref("network.http.keep-alive.timeout", &mIdleTimeout); + if (bChangedAll || PL_strcmp(pref, "network.http.keep-alive.timeout") == 0) { + rv = mPrefs->GetIntPref("network.http.keep-alive.timeout", &val); + if (NS_SUCCEEDED(rv)) + mIdleTimeout = (PRUint16) CLAMP(val, 1, 0xffff); + } - if (bChangedAll || PL_strcmp(pref, "network.http.max-connections") == 0) - mPrefs->GetIntPref("network.http.max-connections", &mMaxConnections); + if (bChangedAll || PL_strcmp(pref, "network.http.request.max-attempts") == 0) { + rv = mPrefs->GetIntPref("network.http.request.max-attempts", &val); + if (NS_SUCCEEDED(rv)) + mMaxRequestAttempts = (PRUint16) CLAMP(val, 1, 0xffff); + } - if (bChangedAll || PL_strcmp(pref, "network.http.max-connections-per-server") == 0) - mPrefs->GetIntPref("network.http.max-connections-per-server", &mMaxConnectionsPerServer); + if (bChangedAll || PL_strcmp(pref, "network.http.max-connections") == 0) { + rv = mPrefs->GetIntPref("network.http.max-connections", &val); + if (NS_SUCCEEDED(rv)) + mMaxConnections = (PRUint16) CLAMP(val, 1, 0xffff); + } - if (bChangedAll || PL_strcmp(pref, "network.http.sendRefererHeader") == 0) - mPrefs->GetIntPref("network.http.sendRefererHeader", (PRInt32 *) &mReferrerLevel); + if (bChangedAll || PL_strcmp(pref, "network.http.max-connections-per-server") == 0) { + rv = mPrefs->GetIntPref("network.http.max-connections-per-server", &val); + if (NS_SUCCEEDED(rv)) + mMaxConnectionsPerServer = (PRUint8) CLAMP(val, 1, 0xff); + } + + /* + if (bChangedAll || PL_strcmp(pref, "network.http.keep-alive.max-connections") == 0) { + rv = mPrefs->GetIntPref("network.http.keep-alive.max-connections", &val); + if (NS_SUCCEEDED(rv)) + mMaxIdleConnections = (PRUint16) CLAMP(val, 1, 0xffff); + } + */ + + if (bChangedAll || PL_strcmp(pref, "network.http.keep-alive.max-connections-per-server") == 0) { + rv = mPrefs->GetIntPref("network.http.keep-alive.max-connections-per-server", &val); + if (NS_SUCCEEDED(rv)) + mMaxIdleConnectionsPerServer = (PRUint8) CLAMP(val, 1, 0xff); + } + + if (bChangedAll || PL_strcmp(pref, "network.http.sendRefererHeader") == 0) { + rv = mPrefs->GetIntPref("network.http.sendRefererHeader", (PRInt32 *) &val); + if (NS_SUCCEEDED(rv)) + mReferrerLevel = (PRUint8) CLAMP(val, 0, 0xff); + } if (bChangedAll || PL_strcmp(pref, "network.http.version") == 0) { nsXPIDLCString httpVersion; @@ -1076,8 +1108,8 @@ nsHttpHandler::PrefsChanged(const char *pref) } if (mHttpVersion == NS_HTTP_VERSION_1_1) { - mCapabilities = ALLOW_KEEPALIVE; - mProxyCapabilities = ALLOW_KEEPALIVE; + mCapabilities = NS_HTTP_ALLOW_KEEPALIVE; + mProxyCapabilities = NS_HTTP_ALLOW_KEEPALIVE; } else { mCapabilities = 0; @@ -1091,9 +1123,9 @@ nsHttpHandler::PrefsChanged(const char *pref) rv = mPrefs->GetBoolPref("network.http.keep-alive", &cVar); if (NS_SUCCEEDED(rv)) { if (cVar) - mCapabilities |= ALLOW_KEEPALIVE; + mCapabilities |= NS_HTTP_ALLOW_KEEPALIVE; else - mCapabilities &= ~ALLOW_KEEPALIVE; + mCapabilities &= ~NS_HTTP_ALLOW_KEEPALIVE; } } @@ -1101,9 +1133,9 @@ nsHttpHandler::PrefsChanged(const char *pref) rv = mPrefs->GetBoolPref("network.http.proxy.keep-alive", &cVar); if (NS_SUCCEEDED(rv)) { if (cVar) - mProxyCapabilities |= ALLOW_KEEPALIVE; + mProxyCapabilities |= NS_HTTP_ALLOW_KEEPALIVE; else - mProxyCapabilities &= ~ALLOW_KEEPALIVE; + mProxyCapabilities &= ~NS_HTTP_ALLOW_KEEPALIVE; } } @@ -1111,9 +1143,9 @@ nsHttpHandler::PrefsChanged(const char *pref) rv = mPrefs->GetBoolPref("network.http.pipelining", &cVar); if (NS_SUCCEEDED(rv)) { if (cVar) - mCapabilities |= ALLOW_PIPELINING; + mCapabilities |= NS_HTTP_ALLOW_PIPELINING; else - mCapabilities &= ~ALLOW_PIPELINING; + mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING; } } @@ -1129,26 +1161,27 @@ nsHttpHandler::PrefsChanged(const char *pref) rv = mPrefs->GetBoolPref("network.http.proxy.pipelining", &cVar); if (NS_SUCCEEDED(rv)) { if (cVar) - mProxyCapabilities |= ALLOW_PIPELINING; + mProxyCapabilities |= NS_HTTP_ALLOW_PIPELINING; else - mProxyCapabilities &= ~ALLOW_PIPELINING; + mProxyCapabilities &= ~NS_HTTP_ALLOW_PIPELINING; } } - if (bChangedAll || PL_strcmp(pref, "network.http.proxy.ssl.connect") == 0) - mPrefs->GetBoolPref("network.http.proxy.ssl.connect", &mProxySSLConnectAllowed); + /* + if (bChangedAll || PL_strcmp(pref, "network.http.proxy.ssl.connect") == 0) { + rv = mPrefs->GetBoolPref("network.http.proxy.ssl.connect", &cVar); + if (NS_SUCCEEDED(rv)) + mProxySSLConnectAllowed = (cVar != 0); + } + */ + /* if (bChangedAll || PL_strcmp(pref, "network.http.connect.timeout") == 0) mPrefs->GetIntPref("network.http.connect.timeout", &mConnectTimeout); if (bChangedAll || PL_strcmp(pref, "network.http.request.timeout") == 0) mPrefs->GetIntPref("network.http.request.timeout", &mRequestTimeout); - - if (bChangedAll || PL_strcmp(pref, "network.http.keep-alive.max-connections") == 0) - mPrefs->GetIntPref("network.http.keep-alive.max-connections", &mMaxIdleConnections); - - if (bChangedAll || PL_strcmp(pref, "network.http.keep-alive.max-connections-per-server") == 0) - mPrefs->GetIntPref("network.http.keep-alive.max-connections-per-server", &mMaxIdleConnectionsPerServer); + */ if (bChangedAll || PL_strcmp(pref, INTL_ACCEPT_LANGUAGES) == 0) { nsXPIDLString acceptLanguages; @@ -1168,9 +1201,8 @@ nsHttpHandler::PrefsChanged(const char *pref) // general.useragent.override if (bChangedAll || PL_strcmp(pref, UA_PREF_PREFIX "override") == 0) { - char* temp = 0; - rv = mPrefs->CopyCharPref(UA_PREF_PREFIX "override", - &temp); + char *temp = 0; + rv = mPrefs->CopyCharPref(UA_PREF_PREFIX "override", &temp); if (NS_SUCCEEDED(rv)) { mUserAgentOverride.Adopt(temp); temp = 0; @@ -1589,7 +1621,6 @@ nsHttpHandler::NewChannel(nsIURI *uri, nsIChannel **result) } rv = NewProxyChannel(uri, - nsnull, -1, nsnull, @@ -1627,10 +1658,10 @@ nsHttpHandler::NewProxyChannel(nsIURI *uri, NS_ADDREF(httpChannel); nsresult rv = httpChannel->Init(uri, - mCapabilities, - proxyHost, - proxyPort, - proxyType); + mCapabilities, + proxyHost, + proxyPort, + proxyType); if (NS_SUCCEEDED(rv)) rv = httpChannel-> diff --git a/netwerk/protocol/http/src/nsHttpHandler.h b/netwerk/protocol/http/src/nsHttpHandler.h index 600b425e29e..4e5c819aa0a 100644 --- a/netwerk/protocol/http/src/nsHttpHandler.h +++ b/netwerk/protocol/http/src/nsHttpHandler.h @@ -64,11 +64,6 @@ public: NS_DECL_NSIHTTPPROTOCOLHANDLER NS_DECL_NSIOBSERVER - enum { - ALLOW_KEEPALIVE = 1 << 0, - ALLOW_PIPELINING = 1 << 1 - }; - nsHttpHandler(); virtual ~nsHttpHandler(); @@ -81,15 +76,15 @@ public: nsresult Init(); nsresult AddStandardRequestHeaders(nsHttpHeaderArray *, - PRUint32 capabilities, + PRUint8 capabilities, PRBool useProxy); PRBool IsAcceptableEncoding(const char *encoding); const char *UserAgent(); - nsHttpVersion DefaultVersion() { return (nsHttpVersion) mHttpVersion; } - PRUint32 ReferrerLevel() { return mReferrerLevel; } - - PRUint32 IdleTimeout() { return mIdleTimeout; } + nsHttpVersion DefaultVersion() { return mHttpVersion; } + PRUint8 ReferrerLevel() { return mReferrerLevel; } + PRUint16 IdleTimeout() { return mIdleTimeout; } + PRUint16 MaxRequestAttempts() { return mMaxRequestAttempts; } nsHttpAuthCache *AuthCache() { return mAuthCache; } @@ -173,8 +168,8 @@ private: nsresult RemovePendingTransaction(nsHttpTransaction *); - PRUint32 CountActiveConnections(nsHttpConnectionInfo *); - PRUint32 CountIdleConnections(nsHttpConnectionInfo *); + PRUint8 CountActiveConnections(nsHttpConnectionInfo *); + PRUint8 CountIdleConnections(nsHttpConnectionInfo *); void DropConnections(nsVoidArray &); @@ -213,20 +208,17 @@ private: // prefs // - PRUint32 mHttpVersion; - PRUint32 mReferrerLevel; - PRUint32 mCapabilities; - PRUint32 mProxyCapabilities; - PRBool mProxySSLConnectAllowed; + PRUint8 mHttpVersion; + PRUint8 mReferrerLevel; + PRUint8 mCapabilities; + PRUint8 mProxyCapabilities; - PRInt32 mConnectTimeout; - PRInt32 mRequestTimeout; - PRInt32 mIdleTimeout; + PRUint16 mIdleTimeout; + PRUint16 mMaxRequestAttempts; - PRInt32 mMaxConnections; - PRInt32 mMaxConnectionsPerServer; - PRInt32 mMaxIdleConnections; - PRInt32 mMaxIdleConnectionsPerServer; + PRUint16 mMaxConnections; + PRUint8 mMaxConnectionsPerServer; + PRUint8 mMaxIdleConnectionsPerServer; nsCString mAccept; nsCString mAcceptLanguages; diff --git a/netwerk/protocol/http/src/nsHttpResponseHead.cpp b/netwerk/protocol/http/src/nsHttpResponseHead.cpp index c82746b4738..ccc17a85f2e 100644 --- a/netwerk/protocol/http/src/nsHttpResponseHead.cpp +++ b/netwerk/protocol/http/src/nsHttpResponseHead.cpp @@ -57,7 +57,7 @@ nsHttpResponseHead::Flatten(nsACString &buf, PRBool pruneTransients) buf.Append("1.0 "); char b[32]; - PR_snprintf(b, sizeof(b), "%d", mStatus); + PR_snprintf(b, sizeof(b), "%u", PRUintn(mStatus)); buf.Append(b); buf.Append(' '); @@ -144,28 +144,26 @@ nsHttpResponseHead::ParseStatusLine(char *line) if ((mVersion == NS_HTTP_VERSION_0_9) || !(line = PL_strchr(line, ' '))) { mStatus = 200; mStatusText.Adopt(nsCRT::strdup("OK")); - LOG(("Have status line [version=%d status=%d statusText=%s]\n", - mVersion, mStatus, mStatusText.get())); - return; } - - // Status-Code - mStatus = atoi(++line); - if (mStatus == 0) { - LOG(("mal-formed response status; assuming status = 200\n")); - mStatus = 200; + else { + // Status-Code + mStatus = (PRUint16) atoi(++line); + if (mStatus == 0) { + LOG(("mal-formed response status; assuming status = 200\n")); + mStatus = 200; + } + + // Reason-Phrase is whatever is remaining of the line + if (!(line = PL_strchr(line, ' '))) { + LOG(("mal-formed response status line; assuming statusText = 'OK'\n")); + mStatusText.Adopt(nsCRT::strdup("OK")); + } + else + mStatusText.Adopt(nsCRT::strdup(++line)); } - // Reason-Phrase is whatever is remaining of the line - if (!(line = PL_strchr(line, ' '))) { - LOG(("mal-formed response status line; assuming statusText = 'OK'\n")); - mStatusText.Adopt(nsCRT::strdup("OK")); - } - else - mStatusText.Adopt(nsCRT::strdup(++line)); - - LOG(("Have status line [version=%d status=%d statusText=%s]\n", - mVersion, mStatus, mStatusText.get())); + LOG(("Have status line [version=%u status=%u statusText=%s]\n", + PRUintn(mVersion), PRUintn(mStatus), mStatusText.get())); } void diff --git a/netwerk/protocol/http/src/nsHttpResponseHead.h b/netwerk/protocol/http/src/nsHttpResponseHead.h index 23651d8355b..3c031ce1d9d 100644 --- a/netwerk/protocol/http/src/nsHttpResponseHead.h +++ b/netwerk/protocol/http/src/nsHttpResponseHead.h @@ -43,7 +43,7 @@ public: nsHttpHeaderArray &Headers() { return mHeaders; } nsHttpVersion Version() { return mVersion; } - PRUint32 Status() { return mStatus; } + PRUint16 Status() { return mStatus; } const char *StatusText() { return mStatusText; } PRInt32 ContentLength() { return mContentLength; } const char *ContentType() { return mContentType; } @@ -98,7 +98,7 @@ private: private: nsHttpHeaderArray mHeaders; nsHttpVersion mVersion; - PRUint32 mStatus; + PRUint16 mStatus; nsXPIDLCString mStatusText; PRInt32 mContentLength; nsXPIDLCString mContentType; diff --git a/netwerk/protocol/http/src/nsHttpTransaction.cpp b/netwerk/protocol/http/src/nsHttpTransaction.cpp index 1992df020d4..27b9091f0be 100644 --- a/netwerk/protocol/http/src/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/src/nsHttpTransaction.cpp @@ -48,6 +48,7 @@ nsHttpTransaction::nsHttpTransaction(nsIStreamListener *listener, , mChunkedDecoder(nsnull) , mTransactionDone(0) , mStatus(NS_OK) + , mRestartCount(0) , mHaveStatusLine(PR_FALSE) , mHaveAllHeaders(PR_FALSE) , mFiredOnStart(PR_FALSE) @@ -182,6 +183,12 @@ nsHttpTransaction::OnDataReadable(nsIInputStream *is) // check if this transaction needs to be restarted if (mPrematureEOF) { + // limit the number of restart attempts - bug 92224 + if (++mRestartCount >= nsHttpHandler::get()->MaxRequestAttempts()) { + LOG(("reached max request attempts, failing transaction @%x\n", this)); + return NS_BINDING_FAILED; + } + mPrematureEOF = PR_FALSE; LOG(("restarting transaction @%x\n", this)); @@ -474,8 +481,10 @@ nsHttpTransaction::HandleContent(char *buf, // headers. So, unless the connection is keep-alive, we must make // allowances for a possibly invalid Content-Length header. Thus, if // NOT keep-alive, we simply accept everything in |buf|. - if (mConnection->IsKeepAlive()) - *countRead = PR_MIN(count, mContentLength - mContentRead); + if (mConnection->IsKeepAlive()) { + *countRead = PRUint32(mContentLength) - mContentRead; + *countRead = PR_MIN(count, *countRead); + } else { *countRead = count; // mContentLength might need to be increased... diff --git a/netwerk/protocol/http/src/nsHttpTransaction.h b/netwerk/protocol/http/src/nsHttpTransaction.h index 25110aa24b8..68da1bd8fa0 100644 --- a/netwerk/protocol/http/src/nsHttpTransaction.h +++ b/netwerk/protocol/http/src/nsHttpTransaction.h @@ -126,10 +126,12 @@ private: PRInt32 mTransactionDone; // set atomically nsresult mStatus; + PRUint16 mRestartCount; // the number of times this transaction has been restarted + PRPackedBool mHaveStatusLine; PRPackedBool mHaveAllHeaders; PRPackedBool mFiredOnStart; - PRPackedBool mNoContent; // true if we're expecting an empty entity body + PRPackedBool mNoContent; // expecting an empty entity body? PRPackedBool mPrematureEOF; };