/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Test that channels with different LoadInfo
* are stored in separate namespaces ("cookie jars")
*/
"use strict";
ChromeUtils.defineLazyGetter(
this,
"URL",
function () {
return "http://localhost:" + httpserver.identity.primaryPort;
});
const { HttpServer } = ChromeUtils.importESModule(
"resource://testing-common/httpd.sys.mjs"
);
var httpserver =
new HttpServer();
var cookieSetPath =
"/setcookie";
var cookieCheckPath =
"/checkcookie";
function inChildProcess() {
return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}
// Test array:
// - element 0: name for cookie, used both to set and later to check
// - element 1: loadInfo (determines cookie namespace)
//
// TODO: bug 722850: make private browsing work per-app, and add tests. For now
// all values are 'false' for PB.
var tests = [
{
cookieName:
"LCC_App0_BrowF_PrivF",
originAttributes:
new OriginAttributes(0),
},
{
cookieName:
"LCC_App1_BrowF_PrivF",
originAttributes:
new OriginAttributes(1),
},
];
// test number: index into 'tests' array
var i = 0;
function setupChannel(path) {
var chan = NetUtil.newChannel({
uri: URL + path,
loadUsingSystemPrincipal:
true,
});
chan.loadInfo.originAttributes = tests[i].originAttributes;
chan.QueryInterface(Ci.nsIHttpChannel);
let loadGroup = Cc[
"@mozilla.org/network/load-group;1"].createInstance(
Ci.nsILoadGroup
);
if (chan.loadInfo.originAttributes.privateBrowsingId == 0) {
loadGroup.notificationCallbacks = Cu.createLoadContext();
chan.loadGroup = loadGroup;
chan.notificationCallbacks = Cu.createLoadContext();
}
else {
loadGroup.notificationCallbacks = Cu.createPrivateLoadContext();
chan.loadGroup = loadGroup;
chan.notificationCallbacks = Cu.createPrivateLoadContext();
}
return chan;
}
function setCookie() {
var channel = setupChannel(cookieSetPath);
channel.setRequestHeader(
"foo-set-cookie", tests[i].cookieName,
false);
channel.asyncOpen(
new ChannelListener(setNextCookie,
null));
}
function setNextCookie() {
if (++i == tests.length) {
// all cookies set: switch to checking them
i = 0;
checkCookie();
}
else {
info(
"setNextCookie:i=" + i);
setCookie();
}
}
// Open channel that should send one and only one correct Cookie: header to
// server, corresponding to it's namespace
function checkCookie() {
var channel = setupChannel(cookieCheckPath);
channel.asyncOpen(
new ChannelListener(completeCheckCookie,
null));
}
function completeCheckCookie(request) {
// Look for all cookies in what the server saw: fail if we see any besides the
// one expected cookie for each namespace;
var expectedCookie = tests[i].cookieName;
request.QueryInterface(Ci.nsIHttpChannel);
var cookiesSeen = request.getResponseHeader(
"foo-saw-cookies");
var j;
for (j = 0; j < tests.length; j++) {
var cookieToCheck = tests[j].cookieName;
let found = cookiesSeen.includes(cookieToCheck);
if (found && expectedCookie != cookieToCheck) {
do_throw(
"test index " +
i +
": found unexpected cookie '" +
cookieToCheck +
"': in '" +
cookiesSeen +
"'"
);
}
else if (!found && expectedCookie == cookieToCheck) {
do_throw(
"test index " +
i +
": missing expected cookie '" +
expectedCookie +
"': in '" +
cookiesSeen +
"'"
);
}
}
// If we get here we're good.
info(
"Saw only correct cookie '" + expectedCookie +
"'");
Assert.ok(
true);
if (++i == tests.length) {
// end of tests
httpserver.stop(do_test_finished);
}
else {
checkCookie();
}
}
function run_test() {
// Allow all cookies if the pref service is available in this process.
if (!inChildProcess()) {
Services.prefs.setIntPref(
"network.cookie.cookieBehavior", 0);
Services.prefs.setBoolPref(
"network.cookieJarSettings.unblocked_for_testing",
true
);
}
httpserver.registerPathHandler(cookieSetPath, cookieSetHandler);
httpserver.registerPathHandler(cookieCheckPath, cookieCheckHandler);
httpserver.start(-1);
setCookie();
do_test_pending();
}
function cookieSetHandler(metadata, response) {
var cookieName = metadata.getHeader(
"foo-set-cookie");
response.setStatusLine(metadata.httpVersion, 200,
"Ok");
response.setHeader(
"Set-Cookie", cookieName +
"=1; Path=/",
false);
response.setHeader(
"Content-Type",
"text/plain");
response.bodyOutputStream.write(
"Ok",
"Ok".length);
}
function cookieCheckHandler(metadata, response) {
var cookies = metadata.getHeader(
"Cookie");
response.setStatusLine(metadata.httpVersion, 200,
"Ok");
response.setHeader(
"foo-saw-cookies", cookies,
false);
response.setHeader(
"Content-Type",
"text/plain");
response.bodyOutputStream.write(
"Ok",
"Ok".length);
}