fixes bug 83471 "Redirection loops"
r=bbaetz@cs.mcgill.ca sr=rpotts@netscape.com
This commit is contained in:
Родитель
5312502a94
Коммит
45989119b4
|
@ -23,6 +23,7 @@ dnsNotFound=%s could not be found. Please check the name and try again.
|
|||
protocolNotFound=%s is not a registered protocol.
|
||||
connectionFailure=The connection was refused when attempting to contact %s.
|
||||
netTimeout=The operation timed out when attempting to contact %s.
|
||||
redirectLoop=Redirection limit for this URL exceeded. Loading aborted.
|
||||
repost=The page you are trying to view contains POSTDATA that has expired from cache. If you resend the data, any action the form carried out (such as a search or online purchase) will be repeated. To resend the data, click OK. Otherwise, click Cancel.
|
||||
repostConfirm=The page you are trying to view contains POSTDATA. If you resend the data, any action the form carried out (such as a search or online purchase) will be repeated. To resend the data, click OK. Otherwise, click Cancel.
|
||||
fileNotFound=%s does not exist or could not be accessed. Please check the file path and try again.
|
||||
|
|
|
@ -1218,6 +1218,26 @@ nsresult nsWebShell::EndPageLoad(nsIWebProgress *aProgress,
|
|||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Doc failed to load because the server generated too many redirects
|
||||
//
|
||||
else if (aStatus == NS_ERROR_REDIRECT_LOOP) {
|
||||
nsCOMPtr<nsIPrompt> prompter;
|
||||
nsCOMPtr<nsIStringBundle> stringBundle;
|
||||
|
||||
rv = GetPromptAndStringBundle(getter_AddRefs(prompter),
|
||||
getter_AddRefs(stringBundle));
|
||||
if (!stringBundle) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsXPIDLString messageStr;
|
||||
rv = stringBundle->GetStringFromName(NS_LITERAL_STRING("redirectLoop").get(),
|
||||
getter_Copies(messageStr));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
prompter->Alert(nsnull, messageStr);
|
||||
}
|
||||
} // if we have a host
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -43,6 +43,7 @@ pref("network.search.url","http://cgi.netscape.com/cgi-bin/url_search.cgi?search
|
|||
pref("keyword.URL", "http://keyword.netscape.com/keyword/");
|
||||
pref("keyword.enabled", false);
|
||||
pref("general.useragent.locale", "chrome://navigator/locale/navigator.properties");
|
||||
pref("general.useragent.override", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.5+) Gecko/20011010 Netscape6/6.1b1");
|
||||
pref("general.useragent.misc", "rv:0.9.6+");
|
||||
|
||||
pref("general.startup.browser", true);
|
||||
|
@ -369,6 +370,9 @@ pref("network.http.accept.default", "text/xml, application/xml, application/xhtm
|
|||
|
||||
pref("network.http.sendRefererHeader", 2); // 0=don't send any, 1=send only on clicks, 2=send on image requests as well
|
||||
|
||||
// Maximum number of consecutive redirects before aborting.
|
||||
pref("network.http.redirection-limit", 10);
|
||||
|
||||
// Enable http compression: comment this out in case of problems with 1.1
|
||||
pref("network.http.accept-encoding" ,"gzip, deflate, compress;q=0.9");
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@
|
|||
#define NS_ERROR_PORT_ACCESS_NOT_ALLOWED \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 19)
|
||||
|
||||
#define NS_ERROR_REDIRECT_LOOP \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 31)
|
||||
|
||||
#undef NS_NET
|
||||
#ifdef _IMPL_NS_NET
|
||||
#if defined(XP_PC) && !defined(XP_OS2)
|
||||
|
|
|
@ -91,6 +91,13 @@ interface nsIHttpChannel : nsIChannel
|
|||
* by default.
|
||||
*/
|
||||
attribute boolean applyConversion;
|
||||
|
||||
/**
|
||||
* This attribute specifies the number of redirects this channel is allowed
|
||||
* to make. If zero, the channel will fail to redirect and will generate
|
||||
* a NS_ERROR_REDIRECT_LOOP failure status.
|
||||
*/
|
||||
attribute unsigned long redirectionLimit;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,6 +62,7 @@ nsHttpChannel::nsHttpChannel()
|
|||
, mCacheAccess(0)
|
||||
, mPostID(0)
|
||||
, mRequestTime(0)
|
||||
, mRedirectionLimit(nsHttpHandler::get()->RedirectionLimit())
|
||||
, mIsPending(PR_FALSE)
|
||||
, mApplyConversion(PR_TRUE)
|
||||
, mFromCacheOnly(PR_FALSE)
|
||||
|
@ -351,8 +352,18 @@ nsHttpChannel::HandleAsyncRedirect()
|
|||
// in processing the redirect.
|
||||
if (NS_SUCCEEDED(mStatus)) {
|
||||
rv = ProcessRedirection(mResponseHead->Status());
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
// If ProcessRedirection fails, then we have to send out the
|
||||
// OnStart/OnStop notifications.
|
||||
LOG(("ProcessRedirection failed [rv=%x]\n", rv));
|
||||
mStatus = rv;
|
||||
if (mListener) {
|
||||
mListener->OnStartRequest(this, mListenerContext);
|
||||
mListener->OnStopRequest(this, mListenerContext, mStatus);
|
||||
mListener = 0;
|
||||
mListenerContext = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close the cache entry... blow it away if we couldn't process
|
||||
|
@ -463,7 +474,7 @@ nsHttpChannel::ApplyContentConversions()
|
|||
nsresult
|
||||
nsHttpChannel::ProcessResponse()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsresult rv;
|
||||
PRUint32 httpStatus = mResponseHead->Status();
|
||||
|
||||
LOG(("nsHttpChannel::ProcessResponse [this=%x httpStatus=%u]\n",
|
||||
|
@ -478,6 +489,7 @@ nsHttpChannel::ProcessResponse()
|
|||
case 200:
|
||||
case 203:
|
||||
case 206:
|
||||
// these can normally be cached
|
||||
rv = ProcessNormal();
|
||||
break;
|
||||
case 300:
|
||||
|
@ -485,19 +497,9 @@ nsHttpChannel::ProcessResponse()
|
|||
case 302:
|
||||
case 307:
|
||||
// these redirects can be cached (don't store the response body)
|
||||
if (mCacheEntry) {
|
||||
rv = InitCacheEntry();
|
||||
if (NS_SUCCEEDED(rv) && mCacheEntry) {
|
||||
// XXX we must open an output stream to force the cache service to
|
||||
// select a cache device for our entry -- bad cache service!!
|
||||
rv = mCacheEntry->GetTransport(getter_AddRefs(mCacheTransport));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIOutputStream> out;
|
||||
rv = mCacheTransport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(out));
|
||||
}
|
||||
}
|
||||
CloseCacheEntry(rv);
|
||||
}
|
||||
if (mCacheEntry)
|
||||
CloseCacheEntry(InitCacheEntry());
|
||||
|
||||
rv = ProcessRedirection(httpStatus);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("ProcessRedirection failed [rv=%x]\n", rv));
|
||||
|
@ -508,6 +510,7 @@ nsHttpChannel::ProcessResponse()
|
|||
case 305:
|
||||
// these redirects cannot be cached
|
||||
CloseCacheEntry(NS_ERROR_ABORT);
|
||||
|
||||
rv = ProcessRedirection(httpStatus);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("ProcessRedirection failed [rv=%x]\n", rv));
|
||||
|
@ -951,6 +954,7 @@ nsHttpChannel::ReadFromCache()
|
|||
// server to validate at this time, so just mark the cache entry as
|
||||
// valid in order to allow others access to this cache entry.
|
||||
mCacheEntry->MarkValid();
|
||||
mCacheAccess = nsICache::ACCESS_READ;
|
||||
}
|
||||
|
||||
// if this is a cached redirect, we must process the redirect asynchronously
|
||||
|
@ -1140,7 +1144,15 @@ nsHttpChannel::ProcessRedirection(PRUint32 redirectType)
|
|||
if (!location)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LOG(("redirecting to: %s\n", location));
|
||||
if (mRedirectionLimit == 0) {
|
||||
LOG(("redirection limit reached!\n"));
|
||||
// this error code is fatal, and should be conveyed to our listener.
|
||||
Cancel(NS_ERROR_REDIRECT_LOOP);
|
||||
return NS_ERROR_REDIRECT_LOOP;
|
||||
}
|
||||
|
||||
LOG(("redirecting to: %s [redirection-limit=%u]\n",
|
||||
location, PRUint32(mRedirectionLimit)));
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
|
@ -1210,6 +1222,8 @@ nsHttpChannel::ProcessRedirection(PRUint32 redirectType)
|
|||
httpChannel->SetReferrer(mReferrer, mReferrerType);
|
||||
// convey the mApplyConversion flag (bug 91862)
|
||||
httpChannel->SetApplyConversion(mApplyConversion);
|
||||
// convey the new redirection limit
|
||||
httpChannel->SetRedirectionLimit(mRedirectionLimit - 1);
|
||||
}
|
||||
|
||||
// call out to the event sink to notify it of this redirection.
|
||||
|
@ -1694,16 +1708,16 @@ nsHttpChannel::GetCurrentPath(char **path)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS10(nsHttpChannel,
|
||||
nsIRequest,
|
||||
nsIChannel,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListener,
|
||||
nsIHttpChannel,
|
||||
nsIInterfaceRequestor,
|
||||
nsIProgressEventSink,
|
||||
nsICachingChannel,
|
||||
nsIUploadChannel,
|
||||
nsICacheListener)
|
||||
nsIRequest,
|
||||
nsIChannel,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListener,
|
||||
nsIHttpChannel,
|
||||
nsIInterfaceRequestor,
|
||||
nsIProgressEventSink,
|
||||
nsICachingChannel,
|
||||
nsIUploadChannel,
|
||||
nsICacheListener)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel::nsIRequest
|
||||
|
@ -2279,6 +2293,21 @@ nsHttpChannel::SetApplyConversion(PRBool value)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::GetRedirectionLimit(PRUint32 *value)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(value);
|
||||
*value = PRUint32(mRedirectionLimit);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::SetRedirectionLimit(PRUint32 value)
|
||||
{
|
||||
mRedirectionLimit = CLAMP(value, 0, 0xff);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -163,6 +163,9 @@ private:
|
|||
nsXPIDLString mProxyUser;
|
||||
nsXPIDLString mProxyPass;
|
||||
|
||||
// redirection specific data.
|
||||
PRUint8 mRedirectionLimit;
|
||||
|
||||
PRPackedBool mIsPending;
|
||||
PRPackedBool mApplyConversion;
|
||||
PRPackedBool mFromCacheOnly;
|
||||
|
|
|
@ -111,6 +111,7 @@ nsHttpHandler::nsHttpHandler()
|
|||
, mMaxConnectionsPerServer(8)
|
||||
, mMaxPersistentConnectionsPerServer(2)
|
||||
, mMaxPersistentConnectionsPerProxy(4)
|
||||
, mRedirectionLimit(10)
|
||||
, mLastUniqueID(NowInSeconds())
|
||||
, mSessionStartTime(0)
|
||||
, mActiveConnections(0)
|
||||
|
@ -1234,11 +1235,17 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
|
|||
}
|
||||
|
||||
if (PREF_CHANGED(HTTP_PREF("sendRefererHeader"))) {
|
||||
rv = prefs->GetIntPref(HTTP_PREF("sendRefererHeader"), (PRInt32 *) &val);
|
||||
rv = prefs->GetIntPref(HTTP_PREF("sendRefererHeader"), &val);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mReferrerLevel = (PRUint8) CLAMP(val, 0, 0xff);
|
||||
}
|
||||
|
||||
if (PREF_CHANGED(HTTP_PREF("redirection-limit"))) {
|
||||
rv = prefs->GetIntPref(HTTP_PREF("redirection-limit"), &val);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mRedirectionLimit = (PRUint8) CLAMP(val, 0, 0xff);
|
||||
}
|
||||
|
||||
if (PREF_CHANGED(HTTP_PREF("version"))) {
|
||||
nsXPIDLCString httpVersion;
|
||||
prefs->GetCharPref(HTTP_PREF("version"), getter_Copies(httpVersion));
|
||||
|
|
|
@ -86,6 +86,7 @@ public:
|
|||
const char *UserAgent();
|
||||
nsHttpVersion DefaultVersion() { return mHttpVersion; }
|
||||
PRUint8 ReferrerLevel() { return mReferrerLevel; }
|
||||
PRUint8 RedirectionLimit() { return mRedirectionLimit; }
|
||||
PRUint16 IdleTimeout() { return mIdleTimeout; }
|
||||
PRUint16 MaxRequestAttempts() { return mMaxRequestAttempts; }
|
||||
nsIIDNService *IDNConverter() { return mIDNConverter; }
|
||||
|
@ -229,6 +230,8 @@ private:
|
|||
PRUint8 mMaxPersistentConnectionsPerServer;
|
||||
PRUint8 mMaxPersistentConnectionsPerProxy;
|
||||
|
||||
PRUint8 mRedirectionLimit;
|
||||
|
||||
nsCString mAccept;
|
||||
nsCString mAcceptLanguages;
|
||||
nsCString mAcceptEncodings;
|
||||
|
|
Загрузка…
Ссылка в новой задаче