--- a/build/pgo/automation.py.in
+++ b/build/pgo/automation.py.in
@@ -307,16 +307,17 @@ user_pref("shell.checkDefaultClient", fa
user_pref("browser.warnOnQuit", false);
user_pref("accessibility.typeaheadfind.autostart", false);
user_pref("javascript.options.showInConsole", true);
user_pref("layout.debug.enable_data_xbl", true);
user_pref("browser.EULA.override", true);
user_pref("javascript.options.jit.content", true);
user_pref("gfx.color_management.force_srgb", true);
user_pref("security.default_personal_cert", "Select Automatically"); // Need to client auth test be w/o any dialogs
+user_pref("network.http.prompt-temp-redirect", false);
user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others
"""
prefs.append(part)
# Increase the max script run time 10-fold for debug builds
if (IS_DEBUG_BUILD):
prefs.append("""\
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -52,16 +52,39 @@
#include "nsGkAtoms.h"
#include "nsWhitespaceTokenizer.h"
#include "nsIChannelEventSink.h"
#include "nsCommaSeparatedTokenizer.h"
#include "nsXMLHttpRequest.h"
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
+class nsChannelCanceller
+{
+public:
+ nsChannelCanceller(nsIChannel* aChannel)
+ : mChannel(aChannel)
+ {
+ }
+ ~nsChannelCanceller()
+ {
+ if (mChannel) {
+ mChannel->Cancel(NS_ERROR_DOM_BAD_URI);
+ }
+ }
+
+ void DontCancel()
+ {
+ mChannel = nsnull;
+ }
+
+private:
+ nsIChannel* mChannel;
+};
+
NS_IMPL_ISUPPORTS4(nsCrossSiteListenerProxy, nsIStreamListener,
nsIRequestObserver, nsIChannelEventSink,
nsIInterfaceRequestor)
nsCrossSiteListenerProxy::nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
@@ -312,16 +335,17 @@ nsCrossSiteListenerProxy::GetInterface(c
NS_ERROR_NO_INTERFACE;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags)
{
+ nsChannelCanceller canceller(aOldChannel);
nsresult rv;
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
rv = CheckRequestApproved(aOldChannel, PR_TRUE);
if (NS_FAILED(rv)) {
if (nsXMLHttpRequest::sAccessControlCache) {
nsCOMPtr<nsIURI> oldURI;
aOldChannel->GetURI(getter_AddRefs(oldURI));
if (oldURI) {
@@ -335,17 +359,22 @@ nsCrossSiteListenerProxy::OnChannelRedir
nsCOMPtr<nsIChannelEventSink> outer =
do_GetInterface(mOuterNotificationCallbacks);
if (outer) {
rv = outer->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
NS_ENSURE_SUCCESS(rv, rv);
}
- return UpdateChannel(aNewChannel);
+ rv = UpdateChannel(aNewChannel);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ canceller.DontCancel();
+
+ return NS_OK;
}
nsresult
nsCrossSiteListenerProxy::UpdateChannel(nsIChannel* aChannel)
{
nsCOMPtr<nsIURI> uri, originalURI;
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsCrossSiteListenerProxy.h
+++ b/content/base/src/nsCrossSiteListenerProxy.h
@@ -30,16 +30,19 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifndef nsCrossSiteListenerProxy_h__
+#define nsCrossSiteListenerProxy_h__
+
#include "nsIStreamListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIURI.h"
#include "nsTArray.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
@@ -84,8 +87,10 @@ private:
nsCOMPtr<nsIInterfaceRequestor> mOuterNotificationCallbacks;
PRBool mWithCredentials;
PRBool mRequestApproved;
PRBool mHasBeenCrossSite;
PRBool mIsPreflight;
nsCString mPreflightMethod;
nsTArray<nsCString> mPreflightHeaders;
};
+
+#endif
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1770,26 +1770,57 @@ CheckMayLoad(nsIPrincipal* aPrincipal, n
rv = aPrincipal->CheckMayLoad(originalURI, PR_FALSE);
}
return NS_SUCCEEDED(rv);
}
nsresult
nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
{
+ nsresult rv;
+
// First check if this is a same-origin request, or if cross-site requests
// are enabled.
if ((mState & XML_HTTP_REQUEST_XSITEENABLED) ||
CheckMayLoad(mPrincipal, aChannel)) {
return NS_OK;
}
// This is a cross-site request
mState |= XML_HTTP_REQUEST_USE_XSITE_AC;
+ // Check if we need to do a preflight request.
+ nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
+ NS_ENSURE_TRUE(httpChannel, NS_ERROR_DOM_BAD_URI);
+
+ nsCAutoString method;
+ httpChannel->GetRequestMethod(method);
+ if (!mACUnsafeHeaders.IsEmpty() ||
+ HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)) ||
+ (mUpload && mUpload->HasListeners())) {
+ mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
+ }
+ else if (method.LowerCaseEqualsLiteral("post")) {
+ nsCAutoString contentTypeHeader;
+ httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("Content-Type"),
+ contentTypeHeader);
+
+ nsCAutoString contentType, charset;
+ rv = NS_ParseContentType(contentTypeHeader, contentType, charset);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!contentType.LowerCaseEqualsLiteral("text/plain")) {
+ mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
+ }
+ }
+ else if (!method.LowerCaseEqualsLiteral("get") &&
+ !method.LowerCaseEqualsLiteral("head")) {
+ mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
+ }
+
return NS_OK;
}
/* noscript void openRequest (in AUTF8String method, in AUTF8String url, in boolean async, in AString user, in AString password); */
NS_IMETHODIMP
nsXMLHttpRequest::OpenRequest(const nsACString& method,
const nsACString& url,
PRBool async,
@@ -1911,16 +1942,19 @@ nsXMLHttpRequest::OpenRequest(const nsAC
if (NS_FAILED(rv)) return rv;
// Check if we're doing a cross-origin request.
if (IsSystemPrincipal(mPrincipal)) {
// Chrome callers are always allowed to read from different origins.
mState |= XML_HTTP_REQUEST_XSITEENABLED;
}
+ mState &= ~(XML_HTTP_REQUEST_USE_XSITE_AC |
+ XML_HTTP_REQUEST_NEED_AC_PREFLIGHT);
+
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (httpChannel) {
rv = httpChannel->SetRequestMethod(method);
NS_ENSURE_SUCCESS(rv, rv);
}
ChangeState(XML_HTTP_REQUEST_OPENED);
@@ -2624,78 +2658,48 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
// Reset responseXML
mResponseXML = nsnull;
rv = CheckChannelForCrossSiteRequest(mChannel);
NS_ENSURE_SUCCESS(rv, rv);
PRBool withCredentials = !!(mState & XML_HTTP_REQUEST_AC_WITH_CREDENTIALS);
- if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
- // Check if we need to do a preflight request.
- NS_ENSURE_TRUE(httpChannel, NS_ERROR_DOM_BAD_URI);
-
- nsCAutoString method;
- httpChannel->GetRequestMethod(method);
- if (!mACUnsafeHeaders.IsEmpty() ||
- HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)) ||
- (mUpload && mUpload->HasListeners())) {
- mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
- }
- else if (method.LowerCaseEqualsLiteral("post")) {
- nsCAutoString contentTypeHeader;
- httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("Content-Type"),
- contentTypeHeader);
-
- nsCAutoString contentType, charset;
- NS_ParseContentType(contentTypeHeader, contentType, charset);
-
+ // If so, set up the preflight
+ if (mState & XML_HTTP_REQUEST_NEED_AC_PREFLIGHT) {
+ // Check to see if this initial OPTIONS request has already been cached
+ // in our special Access Control Cache.
+ nsCOMPtr<nsIURI> uri;
+ rv = mChannel->GetURI(getter_AddRefs(uri));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAccessControlLRUCache::CacheEntry* entry =
+ sAccessControlCache ?
+ sAccessControlCache->GetEntry(uri, mPrincipal, withCredentials, PR_FALSE) :
+ nsnull;
+
+ if (!entry || !entry->CheckRequest(method, mACUnsafeHeaders)) {
+ // Either it wasn't cached or the cached result has expired. Build a
+ // channel for the OPTIONS request.
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ GetLoadGroup(getter_AddRefs(loadGroup));
+
+ nsLoadFlags loadFlags;
+ rv = mChannel->GetLoadFlags(&loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
- if (!contentType.LowerCaseEqualsLiteral("text/plain")) {
- mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
- }
- }
- else if (!method.LowerCaseEqualsLiteral("get") &&
- !method.LowerCaseEqualsLiteral("head")) {
- mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
- }
-
- // If so, set up the preflight
- if (mState & XML_HTTP_REQUEST_NEED_AC_PREFLIGHT) {
- // Check to see if this initial OPTIONS request has already been cached
- // in our special Access Control Cache.
- nsCOMPtr<nsIURI> uri;
- rv = mChannel->GetURI(getter_AddRefs(uri));
+
+ rv = NS_NewChannel(getter_AddRefs(mACGetChannel), uri, nsnull,
+ loadGroup, nsnull, loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
- nsAccessControlLRUCache::CacheEntry* entry =
- sAccessControlCache ?
- sAccessControlCache->GetEntry(uri, mPrincipal, withCredentials, PR_FALSE) :
- nsnull;
-
- if (!entry || !entry->CheckRequest(method, mACUnsafeHeaders)) {
- // Either it wasn't cached or the cached result has expired. Build a
- // channel for the OPTIONS request.
- nsCOMPtr<nsILoadGroup> loadGroup;
- GetLoadGroup(getter_AddRefs(loadGroup));
-
- nsLoadFlags loadFlags;
- rv = mChannel->GetLoadFlags(&loadFlags);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = NS_NewChannel(getter_AddRefs(mACGetChannel), uri, nsnull,
- loadGroup, nsnull, loadFlags);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIHttpChannel> acHttp = do_QueryInterface(mACGetChannel);
- NS_ASSERTION(acHttp, "Failed to QI to nsIHttpChannel!");
-
- rv = acHttp->SetRequestMethod(NS_LITERAL_CSTRING("OPTIONS"));
- NS_ENSURE_SUCCESS(rv, rv);
- }
+ nsCOMPtr<nsIHttpChannel> acHttp = do_QueryInterface(mACGetChannel);
+ NS_ASSERTION(acHttp, "Failed to QI to nsIHttpChannel!");
+
+ rv = acHttp->SetRequestMethod(NS_LITERAL_CSTRING("OPTIONS"));
+ NS_ENSURE_SUCCESS(rv, rv);
}
}
// Hook us up to listen to redirects and the like
mChannel->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
mChannel->SetNotificationCallbacks(this);
// Create our listener
--- a/content/base/test/file_CrossSiteXHR_server.sjs
+++ b/content/base/test/file_CrossSiteXHR_server.sjs
@@ -93,16 +93,17 @@ function handleRequest(request, response
}
// Send response
if (query.hop) {
query.hop = parseInt(query.hop, 10);
hops = eval(query.hops);
query.allowOrigin = hops[query.hop-1].allowOrigin;
+ query.allowHeaders = hops[query.hop-1].allowHeaders;
}
if (query.allowOrigin && (!isPreflight || !query.noAllowPreflight))
response.setHeader("Access-Control-Allow-Origin", query.allowOrigin);
if (query.allowCred)
response.setHeader("Access-Control-Allow-Credentials", "true");
@@ -116,17 +117,17 @@ function handleRequest(request, response
if (query.allowMethods)
response.setHeader("Access-Control-Allow-Methods", query.allowMethods);
}
if (query.hop && query.hop < hops.length) {
newURL = hops[query.hop].server +
"/tests/content/base/test/file_CrossSiteXHR_server.sjs?" +
"hop=" + (query.hop + 1) + "&hops=" + query.hops;
- response.setStatusLine(null, 302, "redirect");
+ response.setStatusLine(null, 307, "redirect");
response.setHeader("Location", newURL);
return;
}
// Send response body
if (!isPreflight && request.method != "HEAD") {
response.setHeader("Content-Type", "application/xml", false);
--- a/content/base/test/test_CrossSiteXHR.html
+++ b/content/base/test/test_CrossSiteXHR.html
@@ -12,16 +12,21 @@
<iframe id=loader></iframe>
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.8">
+const runOriginTests = 1;
+const runPreflightTests = 1;
+const runCookieTests = 1;
+const runRedirectTests = 1;
+
SimpleTest.waitForExplicitFinish();
var origins =
[{ server: 'http://example.org' },
{ server: 'http://example.org:80',
origin: 'http://example.org'
},
{ server: 'http://sub1.test1.example.org' },
@@ -59,16 +64,21 @@ gen = runTest();
function runTest() {
var loader = document.getElementById('loader');
var loaderWindow = loader.contentWindow;
loader.onload = function () { gen.next() };
// Test preflight-less requests
basePath = "/tests/content/base/test/file_CrossSiteXHR_server.sjs?"
baseURL = "http://localhost:8888" + basePath;
+
+ if (!runOriginTests) {
+ origins = [];
+ }
+
for each(originEntry in origins) {
origin = originEntry.origin || originEntry.server;
loader.src = originEntry.file ||
(originEntry.server + "/tests/content/base/test/file_CrossSiteXHR_inner.html");
yield;
var isNullOrigin = origin == "null";
@@ -424,16 +434,20 @@ function runTest() {
{ method: "POST",
body: "hi there",
headers: { "Content-Type": "text/plain" },
noAllowPreflight: 1,
uploadProgress: "progress",
},
];
+ if (!runPreflightTests) {
+ passTests = failTests = [];
+ }
+
for each(test in passTests) {
req = {
url: baseURL + "&allowOrigin=" + escape(origin) +
"&origin=" + escape(origin) +
"&requestMethod=" + test.method,
method: test.method,
headers: test.headers,
uploadProgress: test.uploadProgress,
@@ -451,16 +465,19 @@ function runTest() {
name != "Accept" &&
name != "Accept-Language").join(","));
req.url += reqHeaders ? "&requestHeaders=" + reqHeaders : "";
}
if ("allowHeaders" in test)
req.url += "&allowHeaders=" + escape(test.allowHeaders);
if ("allowMethods" in test)
req.url += "&allowMethods=" + escape(test.allowMethods);
+ if (test.body)
+ req.url += "&body=" + escape(test.body);
+
loaderWindow.postMessage(req.toSource(), origin);
res = eval(yield);
is(res.didFail, false,
"shouldn't have failed in test for " + test.toSource());
is(res.status, 200, "wrong status in test for " + test.toSource());
if (test.method !== "HEAD") {
@@ -487,20 +504,16 @@ function runTest() {
req = {
url: baseURL + "allowOrigin=" + escape(origin),
method: test.method,
headers: test.headers,
uploadProgress: test.uploadProgress,
body: test.body,
};
- if (test.body) {
- req.url += "&body=" + escape(test.body);
- }
-
if (test.noAllowPreflight)
req.url += "&noAllowPreflight";
if ("allowHeaders" in test)
req.url += "&allowHeaders=" + escape(test.allowHeaders);
if ("allowMethods" in test)
req.url += "&allowMethods=" + escape(test.allowMethods);
@@ -590,16 +603,20 @@ function runTest() {
{ pass: 1,
method: "GET",
cookie: "a=2",
withCred: 1,
allowCred: 1,
},
];
+ if (!runCookieTests) {
+ tests = [];
+ }
+
for each(test in tests) {
req = {
url: baseURL + "allowOrigin=" + escape(test.origin || origin),
method: test.method,
headers: test.headers,
withCred: test.withCred,
};
@@ -761,25 +778,135 @@ function runTest() {
},
{ server: "http://sub2.xn--lt-uia.example.org",
allowOrigin: "*"
},
{ server: "http://sub1.test1.example.org",
},
],
},
+ { pass: 1,
+ method: "POST",
+ body: "hi there",
+ headers: { "Content-Type": "text/plain" },
+ hops: [{ server: "http://example.org",
+ },
+ { server: "http://example.com",
+ allowOrigin: origin,
+ },
+ ],
+ },
+ { pass: 0,
+ method: "POST",
+ body: "hi there",
+ headers: { "Content-Type": "text/plain",
+ "my-header": "myValue",
+ },
+ hops: [{ server: "http://example.org",
+ },
+ { server: "http://example.com",
+ allowOrigin: origin,
+ allowHeaders: "my-header",
+ },
+ ],
+ },
+ { pass: 0,
+ method: "DELETE",
+ hops: [{ server: "http://example.org",
+ },
+ { server: "http://example.com",
+ allowOrigin: origin,
+ },
+ ],
+ },
+ { pass: 0,
+ method: "POST",
+ body: "hi there",
+ headers: { "Content-Type": "text/plain",
+ "my-header": "myValue",
+ },
+ hops: [{ server: "http://example.com",
+ allowOrigin: origin,
+ },
+ { server: "http://sub1.test1.example.org",
+ allowOrigin: origin,
+ },
+ ],
+ },
+ { pass: 0,
+ method: "DELETE",
+ hops: [{ server: "http://example.com",
+ allowOrigin: origin,
+ },
+ { server: "http://sub1.test1.example.org",
+ allowOrigin: origin,
+ },
+ ],
+ },
+ { pass: 0,
+ method: "POST",
+ body: "hi there",
+ headers: { "Content-Type": "text/plain",
+ "my-header": "myValue",
+ },
+ hops: [{ server: "http://example.com",
+ },
+ { server: "http://sub1.test1.example.org",
+ allowOrigin: origin,
+ allowHeaders: "my-header",
+ },
+ ],
+ },
+ { pass: 1,
+ method: "POST",
+ body: "hi there",
+ headers: { "Content-Type": "text/plain" },
+ hops: [{ server: "http://example.org",
+ },
+ { server: "http://example.com",
+ allowOrigin: origin,
+ },
+ ],
+ },
+ { pass: 0,
+ method: "POST",
+ body: "hi there",
+ headers: { "Content-Type": "text/plain",
+ "my-header": "myValue",
+ },
+ hops: [{ server: "http://example.com",
+ allowOrigin: origin,
+ allowHeaders: "my-header",
+ },
+ { server: "http://example.org",
+ allowOrigin: origin,
+ allowHeaders: "my-header",
+ },
+ ],
+ },
];
+ if (!runRedirectTests) {
+ tests = [];
+ }
+
for each(test in tests) {
req = {
url: test.hops[0].server + basePath + "hop=1&hops=" +
escape(test.hops.toSource()),
method: test.method,
+ headers: test.headers,
+ body: test.body,
};
+ if (test.pass) {
+ if (test.body)
+ req.url += "&body=" + escape(test.body);
+ }
+
loaderWindow.postMessage(req.toSource(), origin);
res = eval(yield);
if (test.pass) {
is(res.didFail, false,
"shouldn't have failed in test for " + test.toSource());
is(res.status, 200, "wrong status in test for " + test.toSource());
is(res.responseXML, "<res>hello pass</res>",
@@ -797,17 +924,17 @@ function runTest() {
is(res.responseXML, null,
"wrong responseXML in test for " + test.toSource());
is(res.responseText, "",
"wrong responseText in test for " + test.toSource());
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
"wrong events in test for " + test.toSource());
is(res.progressEvents, 0,
- "wrong events in test for " + test.toSource());
+ "wrong progressevents in test for " + test.toSource());
}
}
SimpleTest.finish();
yield;
}
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -645,16 +645,19 @@ pref("network.http.accept-encoding" ,"gz
pref("network.http.pipelining" , false);
pref("network.http.pipelining.ssl" , false); // disable pipelining over SSL
pref("network.http.proxy.pipelining", false);
// Max number of requests in the pipeline
pref("network.http.pipelining.maxrequests" , 4);
+// Prompt for 307 redirects
+pref("network.http.prompt-temp-redirect", true);
+
// </http>
// If false, remote JAR files that are served with a content type other than
// application/java-archive or application/x-jar will not be opened
// by the jar channel.
pref("network.jar.open-unsafe-types", false);
// This preference controls whether or not internationalized domain names (IDN)
--- a/netwerk/protocol/http/src/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/src/nsHttpChannel.cpp
@@ -1040,16 +1040,19 @@ nsHttpChannel::ProcessNormal()
}
return rv;
}
nsresult
nsHttpChannel::PromptTempRedirect()
{
+ if (!gHttpHandler->PromptTempRedirect()) {
+ return NS_OK;
+ }
nsresult rv;
nsCOMPtr<nsIStringBundleService> bundleService =
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStringBundle> stringBundle;
rv = bundleService->CreateBundle(NECKO_MSGS_URL, getter_AddRefs(stringBundle));
if (NS_FAILED(rv)) return rv;
--- a/netwerk/protocol/http/src/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/src/nsHttpHandler.cpp
@@ -169,16 +169,17 @@ nsHttpHandler::nsHttpHandler()
, mRedirectionLimit(10)
, mPhishyUserPassLength(1)
, mPipeliningOverSSL(PR_FALSE)
, mLastUniqueID(NowInSeconds())
, mSessionStartTime(0)
, mProduct("Gecko")
, mUserAgentIsDirty(PR_TRUE)
, mUseCache(PR_TRUE)
+ , mPromptTempRedirect(PR_TRUE)
, mSendSecureXSiteReferrer(PR_TRUE)
, mEnablePersistentHttpsCaching(PR_FALSE)
{
#if defined(PR_LOGGING)
gHttpLog = PR_NewLogModule("nsHttp");
#endif
LOG(("Creating nsHttpHandler [this=%x].\n", this));
@@ -1084,16 +1085,23 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
// OK, this looks like a valid socket provider.
mDefaultSocketType.Assign(sval);
}
}
}
}
}
+ if (PREF_CHANGED(HTTP_PREF("prompt-temp-redirect"))) {
+ rv = prefs->GetBoolPref(HTTP_PREF("prompt-temp-redirect"), &cVar);
+ if (NS_SUCCEEDED(rv)) {
+ mPromptTempRedirect = cVar;
+ }
+ }
+
// enable Persistent caching for HTTPS - bug#205921
if (PREF_CHANGED(BROWSER_PREF("disk_cache_ssl"))) {
cVar = PR_FALSE;
rv = prefs->GetBoolPref(BROWSER_PREF("disk_cache_ssl"), &cVar);
if (NS_SUCCEEDED(rv))
mEnablePersistentHttpsCaching = cVar;
}
--- a/netwerk/protocol/http/src/nsHttpHandler.h
+++ b/netwerk/protocol/http/src/nsHttpHandler.h
@@ -103,16 +103,18 @@ public:
PRUint16 IdleTimeout() { return mIdleTimeout; }
PRUint16 MaxRequestAttempts() { return mMaxRequestAttempts; }
const char *DefaultSocketType() { return mDefaultSocketType.get(); /* ok to return null */ }
nsIIDNService *IDNConverter() { return mIDNConverter; }
PRUint32 PhishyUserPassLength() { return mPhishyUserPassLength; }
PRBool CanCacheAllSSLContent() { return mEnablePersistentHttpsCaching; }
+ PRBool PromptTempRedirect() { return mPromptTempRedirect; }
+
nsHttpAuthCache *AuthCache() { return &mAuthCache; }
nsHttpConnectionMgr *ConnMgr() { return mConnMgr; }
// cache support
nsresult GetCacheSession(nsCacheStoragePolicy, nsICacheSession **);
PRUint32 GenerateUniqueID() { return ++mLastUniqueID; }
PRUint32 SessionStartTime() { return mSessionStartTime; }
@@ -288,16 +290,18 @@ private:
nsXPIDLCString mProductComment;
nsCString mExtraUA;
nsCString mUserAgent;
nsXPIDLCString mUserAgentOverride;
PRPackedBool mUserAgentIsDirty; // true if mUserAgent should be rebuilt
PRPackedBool mUseCache;
+
+ PRPackedBool mPromptTempRedirect;
// mSendSecureXSiteReferrer: default is false,
// if true allow referrer headers between secure non-matching hosts
PRPackedBool mSendSecureXSiteReferrer;
// Persistent HTTPS caching flag
PRPackedBool mEnablePersistentHttpsCaching;
};