summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/test_cookiejars.js
blob: 1d78893f8cc360b1e45d8a2e6d994b4ff542ba85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* 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, false, 0),
  },
  {
    cookieName: "LCC_App0_BrowT_PrivF",
    originAttributes: new OriginAttributes(0, true, 0),
  },
  {
    cookieName: "LCC_App1_BrowF_PrivF",
    originAttributes: new OriginAttributes(1, false, 0),
  },
  {
    cookieName: "LCC_App1_BrowT_PrivF",
    originAttributes: new OriginAttributes(1, true, 0),
  },
];

// 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(request, data, context) {
  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, data, context) {
  // 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);
}