Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /*
6 * Test that channels with different
7 * AppIds/inBrowserElements/usePrivateBrowsing (from nsILoadContext callback)
8 * are stored in separate namespaces ("cookie jars")
9 */
11 XPCOMUtils.defineLazyGetter(this, "URL", function() {
12 return "http://localhost:" + httpserver.identity.primaryPort;
13 });
15 Cu.import("resource://testing-common/httpd.js");
16 Cu.import("resource://gre/modules/Services.jsm");
17 var httpserver = new HttpServer();
19 var cookieSetPath = "/setcookie";
20 var cookieCheckPath = "/checkcookie";
22 function inChildProcess() {
23 return Cc["@mozilla.org/xre/app-info;1"]
24 .getService(Ci.nsIXULRuntime)
25 .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
26 }
28 // Test array:
29 // - element 0: name for cookie, used both to set and later to check
30 // - element 1: loadContext (determines cookie namespace)
31 //
32 // TODO: bug 722850: make private browsing work per-app, and add tests. For now
33 // all values are 'false' for PB.
35 var tests = [
36 { cookieName: 'LCC_App0_BrowF_PrivF',
37 loadContext: new LoadContextCallback(0, false, false, 1) },
38 { cookieName: 'LCC_App0_BrowT_PrivF',
39 loadContext: new LoadContextCallback(0, true, false, 1) },
40 { cookieName: 'LCC_App1_BrowF_PrivF',
41 loadContext: new LoadContextCallback(1, false, false, 1) },
42 { cookieName: 'LCC_App1_BrowT_PrivF',
43 loadContext: new LoadContextCallback(1, true, false, 1) },
44 ];
46 // test number: index into 'tests' array
47 var i = 0;
49 function setupChannel(path)
50 {
51 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
52 var chan = ios.newChannel(URL + path, "", null);
53 chan.notificationCallbacks = tests[i].loadContext;
54 chan.QueryInterface(Ci.nsIHttpChannel);
55 return chan;
56 }
58 function setCookie() {
59 var channel = setupChannel(cookieSetPath);
60 channel.setRequestHeader("foo-set-cookie", tests[i].cookieName, false);
61 channel.asyncOpen(new ChannelListener(setNextCookie, null), null);
62 }
64 function setNextCookie(request, data, context)
65 {
66 if (++i == tests.length) {
67 // all cookies set: switch to checking them
68 i = 0;
69 checkCookie();
70 } else {
71 do_print("setNextCookie:i=" + i);
72 setCookie();
73 }
74 }
76 // Open channel that should send one and only one correct Cookie: header to
77 // server, corresponding to it's namespace
78 function checkCookie()
79 {
80 var channel = setupChannel(cookieCheckPath);
81 channel.asyncOpen(new ChannelListener(completeCheckCookie, null), null);
82 }
84 function completeCheckCookie(request, data, context) {
85 // Look for all cookies in what the server saw: fail if we see any besides the
86 // one expected cookie for each namespace;
87 var expectedCookie = tests[i].cookieName;
88 request.QueryInterface(Ci.nsIHttpChannel);
89 var cookiesSeen = request.getResponseHeader("foo-saw-cookies");
91 var j;
92 for (j = 0; j < tests.length; j++) {
93 var cookieToCheck = tests[j].cookieName;
94 found = (cookiesSeen.indexOf(cookieToCheck) != -1);
95 if (found && expectedCookie != cookieToCheck) {
96 do_throw("test index " + i + ": found unexpected cookie '"
97 + cookieToCheck + "': in '" + cookiesSeen + "'");
98 } else if (!found && expectedCookie == cookieToCheck) {
99 do_throw("test index " + i + ": missing expected cookie '"
100 + expectedCookie + "': in '" + cookiesSeen + "'");
101 }
102 }
103 // If we get here we're good.
104 do_print("Saw only correct cookie '" + expectedCookie + "'");
105 do_check_true(true);
108 if (++i == tests.length) {
109 // end of tests
110 httpserver.stop(do_test_finished);
111 } else {
112 checkCookie();
113 }
114 }
116 function run_test()
117 {
118 // Allow all cookies if the pref service is available in this process.
119 if (!inChildProcess())
120 Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
122 httpserver.registerPathHandler(cookieSetPath, cookieSetHandler);
123 httpserver.registerPathHandler(cookieCheckPath, cookieCheckHandler);
124 httpserver.start(-1);
126 setCookie();
127 do_test_pending();
128 }
130 function cookieSetHandler(metadata, response)
131 {
132 var cookieName = metadata.getHeader("foo-set-cookie");
134 response.setStatusLine(metadata.httpVersion, 200, "Ok");
135 response.setHeader("Set-Cookie", cookieName + "=1; Path=/", false);
136 response.setHeader("Content-Type", "text/plain");
137 response.bodyOutputStream.write("Ok", "Ok".length);
138 }
140 function cookieCheckHandler(metadata, response)
141 {
142 var cookies = metadata.getHeader("Cookie");
144 response.setStatusLine(metadata.httpVersion, 200, "Ok");
145 response.setHeader("foo-saw-cookies", cookies, false);
146 response.setHeader("Content-Type", "text/plain");
147 response.bodyOutputStream.write("Ok", "Ok".length);
148 }