summaryrefslogtreecommitdiffstats
path: root/browser/components/sessionstore/test/browser_cookies.js
blob: cc5b41e4b426630a4fd2530fb4a76e9ff1a558f4 (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
"use strict";

const PATH = "/browser/browser/components/sessionstore/test/";

/**
 * Remove all cookies to start off a clean slate.
 */
add_task(function* test_setup() {
  requestLongerTimeout(2);
  Services.cookies.removeAll();
});

/**
 * Test multiple scenarios with different Set-Cookie header domain= params.
 */
add_task(function* test_run() {
  // Set-Cookie: foobar=random()
  // The domain of the cookie should be the request domain (www.example.com).
  // We should collect data only for the request domain, no parent or subdomains.
  yield testCookieCollection({
    host: "http://www.example.com",
    cookieHost: "www.example.com",
    cookieURIs: ["http://www.example.com" + PATH],
    noCookieURIs: ["http://example.com/" + PATH]
  });

  // Set-Cookie: foobar=random()
  // The domain of the cookie should be the request domain (example.com).
  // We should collect data only for the request domain, no parent or subdomains.
  yield testCookieCollection({
    host: "http://example.com",
    cookieHost: "example.com",
    cookieURIs: ["http://example.com" + PATH],
    noCookieURIs: ["http://www.example.com/" + PATH]
  });

  // Set-Cookie: foobar=random(); Domain=example.com
  // The domain of the cookie should be the given one (.example.com).
  // We should collect data for the given domain and its subdomains.
  yield testCookieCollection({
    host: "http://example.com",
    domain: "example.com",
    cookieHost: ".example.com",
    cookieURIs: ["http://example.com" + PATH, "http://www.example.com/" + PATH],
    noCookieURIs: ["about:robots"]
  });

  // Set-Cookie: foobar=random(); Domain=.example.com
  // The domain of the cookie should be the given one (.example.com).
  // We should collect data for the given domain and its subdomains.
  yield testCookieCollection({
    host: "http://example.com",
    domain: ".example.com",
    cookieHost: ".example.com",
    cookieURIs: ["http://example.com" + PATH, "http://www.example.com/" + PATH],
    noCookieURIs: ["about:robots"]
  });

  // Set-Cookie: foobar=random(); Domain=www.example.com
  // The domain of the cookie should be the given one (.www.example.com).
  // We should collect data for the given domain and its subdomains.
  yield testCookieCollection({
    host: "http://www.example.com",
    domain: "www.example.com",
    cookieHost: ".www.example.com",
    cookieURIs: ["http://www.example.com/" + PATH],
    noCookieURIs: ["http://example.com"]
  });

  // Set-Cookie: foobar=random(); Domain=.www.example.com
  // The domain of the cookie should be the given one (.www.example.com).
  // We should collect data for the given domain and its subdomains.
  yield testCookieCollection({
    host: "http://www.example.com",
    domain: ".www.example.com",
    cookieHost: ".www.example.com",
    cookieURIs: ["http://www.example.com/" + PATH],
    noCookieURIs: ["http://example.com"]
  });
});

/**
 * Generic test function to check sessionstore's cookie collection module with
 * different cookie domains given in the Set-Cookie header. See above for some
 * usage examples.
 */
var testCookieCollection = Task.async(function (params) {
  let tab = gBrowser.addTab("about:blank");
  let browser = tab.linkedBrowser;

  let urlParams = new URLSearchParams();
  let value = Math.random();
  urlParams.append("value", value);

  if (params.domain) {
    urlParams.append("domain", params.domain);
  }

  // Construct request URI.
  let uri = `${params.host}${PATH}browser_cookies.sjs?${urlParams}`;

  // Wait for the browser to load and the cookie to be set.
  // These two events can probably happen in no particular order,
  // so let's wait for them in parallel.
  yield Promise.all([
    waitForNewCookie(),
    replaceCurrentURI(browser, uri)
  ]);

  // Check all URIs for which the cookie should be collected.
  for (let uri of params.cookieURIs || []) {
    yield replaceCurrentURI(browser, uri);

    // Check the cookie.
    let cookie = getCookie();
    is(cookie.host, params.cookieHost, "cookie host is correct");
    is(cookie.path, PATH, "cookie path is correct");
    is(cookie.name, "foobar", "cookie name is correct");
    is(cookie.value, value, "cookie value is correct");
  }

  // Check all URIs for which the cookie should NOT be collected.
  for (let uri of params.noCookieURIs || []) {
    yield replaceCurrentURI(browser, uri);

    // Cookie should be ignored.
    ok(!getCookie(), "no cookie collected");
  }

  // Clean up.
  gBrowser.removeTab(tab);
  Services.cookies.removeAll();
});

/**
 * Replace the current URI of the given browser by loading a new URI. The
 * browser's session history will be completely replaced. This function ensures
 * that the parent process has the lastest shistory data before resolving.
 */
var replaceCurrentURI = Task.async(function* (browser, uri) {
  // Replace the tab's current URI with the parent domain.
  let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
  browser.loadURIWithFlags(uri, flags);
  yield promiseBrowserLoaded(browser);

  // Ensure the tab's session history is up-to-date.
  yield TabStateFlusher.flush(browser);
});

/**
 * Waits for a new "*example.com" cookie to be added.
 */
function waitForNewCookie() {
  return new Promise(resolve => {
    Services.obs.addObserver(function observer(subj, topic, data) {
      let cookie = subj.QueryInterface(Ci.nsICookie2);
      if (data == "added" && cookie.host.endsWith("example.com")) {
        Services.obs.removeObserver(observer, topic);
        resolve();
      }
    }, "cookie-changed", false);
  });
}

/**
 * Retrieves the first cookie in the first window from the current sessionstore
 * state.
 */
function getCookie() {
  let state = JSON.parse(ss.getWindowState(window));
  let cookies = state.windows[0].cookies || [];
  return cookies[0] || null;
}