Bug 1122258 - Fetch API: Set anonymous flag on channel if no credentials are to be passed.

--HG--
extra : rebase_source : d61f26886eda2c0495b75b00cdb66a997ad8de59
This commit is contained in:
Nikhil Marathe 2015-01-15 14:28:14 -08:00
Родитель 23d15b0403
Коммит ee8771017b
2 изменённых файлов: 164 добавлений и 50 удалений

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

@ -316,30 +316,6 @@ FetchDriver::HttpFetch(bool aCORSFlag, bool aCORSPreflightFlag, bool aAuthentica
// FIXME(nsm): Bug 1119026: The channel's skip service worker flag should be
// set based on the Request's flag.
// From here on we create a channel and set its properties with the
// information from the InternalRequest. This is an implementation detail.
MOZ_ASSERT(mLoadGroup);
nsCOMPtr<nsIChannel> chan;
rv = NS_NewChannel(getter_AddRefs(chan),
uri,
mPrincipal,
nsILoadInfo::SEC_NORMAL,
mRequest->GetContext(),
mLoadGroup,
nullptr, /* aCallbacks */
nsIRequest::LOAD_NORMAL,
ios);
mLoadGroup = nullptr;
if (NS_WARN_IF(NS_FAILED(rv))) {
FailWithNetworkError();
return rv;
}
// Insert ourselves into the notification callbacks chain so we can handle
// cross-origin redirects.
chan->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
chan->SetNotificationCallbacks(this);
// Step 3.1 "If the CORS preflight flag is set and one of these conditions is
// true..." is handled by the CORS proxy.
//
@ -360,6 +336,36 @@ FetchDriver::HttpFetch(bool aCORSFlag, bool aCORSPreflightFlag, bool aAuthentica
useCredentials = true;
}
// This is effectivetly the opposite of the use credentials flag in "HTTP
// network or cache fetch" in the spec and decides whether to transmit
// cookies and other identifying information. LOAD_ANONYMOUS also prevents
// new cookies sent by the server from being stored.
const nsLoadFlags credentialsFlag = useCredentials ? 0 : nsIRequest::LOAD_ANONYMOUS;
// From here on we create a channel and set its properties with the
// information from the InternalRequest. This is an implementation detail.
MOZ_ASSERT(mLoadGroup);
nsCOMPtr<nsIChannel> chan;
rv = NS_NewChannel(getter_AddRefs(chan),
uri,
mPrincipal,
nsILoadInfo::SEC_NORMAL,
mRequest->GetContext(),
mLoadGroup,
nullptr, /* aCallbacks */
nsIRequest::LOAD_NORMAL | credentialsFlag,
ios);
mLoadGroup = nullptr;
if (NS_WARN_IF(NS_FAILED(rv))) {
FailWithNetworkError();
return rv;
}
// Insert ourselves into the notification callbacks chain so we can handle
// cross-origin redirects.
chan->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
chan->SetNotificationCallbacks(this);
// FIXME(nsm): Bug 1120715.
// Step 3.4 "If request's cache mode is default and request's header list
// contains a header named `If-Modified-Since`, `If-None-Match`,

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

@ -12,10 +12,6 @@ if (typeof is !== "function") {
var path = "/tests/dom/base/test/";
function isNetworkError(response) {
return response.type == "error" && response.status === 0 && response.statusText === "";
}
function isOpaqueResponse(response) {
return response.type == "opaque" && response.status === 0 && response.statusText === "";
}
@ -68,6 +64,101 @@ function testModeNoCors() {
});
}
function testSameOriginCredentials() {
var cookieStr = "type=chocolatechip";
var tests = [
{
// Initialize by setting a cookie.
pass: 1,
setCookie: cookieStr,
withCred: "same-origin",
},
{
// Default mode is "omit".
pass: 1,
noCookie: 1,
},
{
pass: 1,
noCookie: 1,
withCred: "omit",
},
{
pass: 1,
cookie: cookieStr,
withCred: "same-origin",
},
{
pass: 1,
cookie: cookieStr,
withCred: "include",
},
];
var finalPromiseResolve, finalPromiseReject;
var finalPromise = new Promise(function(res, rej) {
finalPromiseResolve = res;
finalPromiseReject = rej;
});
function makeRequest(test) {
req = {
// Add a default query param just to make formatting the actual params
// easier.
url: corsServerPath + "a=b",
method: test.method,
headers: test.headers,
withCred: test.withCred,
};
if (test.setCookie)
req.url += "&setCookie=" + escape(test.setCookie);
if (test.cookie)
req.url += "&cookie=" + escape(test.cookie);
if (test.noCookie)
req.url += "&noCookie";
return new Request(req.url, { method: req.method,
headers: req.headers,
credentials: req.withCred });
}
function testResponse(res, test) {
ok(test.pass, "Expected test to pass " + test.toSource());
is(res.status, 200, "wrong status in test for " + test.toSource());
is(res.statusText, "OK", "wrong status text for " + test.toSource());
return res.text().then(function(v) {
is(v, "<res>hello pass</res>\n",
"wrong text in test for " + test.toSource());
});
}
function runATest(tests, i) {
var test = tests[i];
var request = makeRequest(test);
console.log(request.url);
fetch(request).then(function(res) {
testResponse(res, test);
if (i < tests.length-1) {
runATest(tests, i+1);
} else {
finalPromiseResolve();
}
}, function(e) {
ok(!test.pass, "Expected test to fail " + test.toSource());
ok(e instanceof TypeError, "Test should fail " + test.toSource());
if (i < tests.length-1) {
runATest(tests, i+1);
} else {
finalPromiseResolve();
}
});
}
runATest(tests, 0);
return finalPromise;
}
function testModeCors() {
var tests = [// Plain request
{ pass: 1,
@ -706,80 +797,98 @@ function testModeCors() {
return Promise.all(fetches);
}
function testCredentials() {
function testCrossOriginCredentials() {
var tests = [
{ pass: 1,
method: "GET",
withCred: 1,
withCred: "include",
allowCred: 1,
},
{ pass: 0,
method: "GET",
withCred: 1,
withCred: "include",
allowCred: 0,
},
{ pass: 0,
method: "GET",
withCred: 1,
withCred: "include",
allowCred: 1,
origin: "*",
},
{ pass: 1,
method: "GET",
withCred: 0,
withCred: "omit",
allowCred: 1,
origin: "*",
},
{ pass: 1,
method: "GET",
setCookie: "a=1",
withCred: 1,
withCred: "include",
allowCred: 1,
},
{ pass: 1,
method: "GET",
cookie: "a=1",
withCred: 1,
withCred: "include",
allowCred: 1,
},
{ pass: 1,
method: "GET",
noCookie: 1,
withCred: 0,
withCred: "omit",
allowCred: 1,
},
{ pass: 0,
method: "GET",
noCookie: 1,
withCred: 1,
withCred: "include",
allowCred: 1,
},
{ pass: 1,
method: "GET",
setCookie: "a=2",
withCred: 0,
withCred: "omit",
allowCred: 1,
},
{ pass: 1,
method: "GET",
cookie: "a=1",
withCred: 1,
withCred: "include",
allowCred: 1,
},
{ pass: 1,
method: "GET",
setCookie: "a=2",
withCred: 1,
withCred: "include",
allowCred: 1,
},
{ pass: 1,
method: "GET",
cookie: "a=2",
withCred: 1,
withCred: "include",
allowCred: 1,
},
{
// When credentials mode is same-origin, but mode is cors, no
// cookie should be sent cross origin.
pass: 0,
method: "GET",
cookie: "a=2",
withCred: "same-origin",
allowCred: 1,
},
{
// When credentials mode is same-origin, but mode is cors, no
// cookie should be sent cross origin. This test checks the same
// thing as above, but uses the noCookie check on the server
// instead, and expects a valid response.
pass: 1,
method: "GET",
noCookie: 1,
withCred: "same-origin",
},
];
// FIXME(nsm): Add "same-origin" credentials test
var baseURL = "http://example.org" + corsServerPath;
var origin = "http://mochi.test:8888";
@ -815,7 +924,7 @@ function testCredentials() {
return new Request(req.url, { method: req.method,
headers: req.headers,
credentials: req.withCred ? "include" : "omit" });
credentials: req.withCred });
}
function testResponse(res, test) {
@ -828,13 +937,13 @@ function testCredentials() {
});
}
function runATest(i) {
function runATest(tests, i) {
var test = tests[i];
var request = makeRequest(test);
fetch(request).then(function(res) {
testResponse(res, test);
if (i < tests.length-1) {
runATest(i+1);
runATest(tests, i+1);
} else {
finalPromiseResolve();
}
@ -842,14 +951,14 @@ function testCredentials() {
ok(!test.pass, "Expected test failure for " + test.toSource());
ok(e instanceof TypeError, "Exception should be TypeError for " + test.toSource());
if (i < tests.length-1) {
runATest(i+1);
runATest(tests, i+1);
} else {
finalPromiseResolve();
}
});
}
runATest(0);
runATest(tests, 0);
return finalPromise;
}
@ -1134,8 +1243,6 @@ function testRedirects() {
fetches.push((function(request, test) {
return fetch(request).then(function(res) {
ok(test.pass, "Expected test to pass for " + test.toSource());
is(isNetworkError(res), false,
"shouldn't have failed in test for " + test.toSource());
is(res.status, 200, "wrong status in test for " + test.toSource());
is(res.statusText, "OK", "wrong status text for " + test.toSource());
is((new URL(res.url)).host, (new URL(test.hops[test.hops.length-1].server)).host, "Response URL should be redirected URL");
@ -1168,7 +1275,8 @@ function runTest() {
.then(testModeSameOrigin)
.then(testModeNoCors)
.then(testModeCors)
.then(testCredentials)
.then(testSameOriginCredentials)
.then(testCrossOriginCredentials)
.then(testRedirects)
// Put more promise based tests here.
.then(done)