|
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/. */ |
|
4 |
|
5 Cu.import("resource://testing-common/httpd.js"); |
|
6 Cu.import("resource://gre/modules/Services.jsm"); |
|
7 |
|
8 var httpserver; |
|
9 |
|
10 function inChildProcess() { |
|
11 return Cc["@mozilla.org/xre/app-info;1"] |
|
12 .getService(Ci.nsIXULRuntime) |
|
13 .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; |
|
14 } |
|
15 function makeChan(path) { |
|
16 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); |
|
17 var chan = ios.newChannel("http://localhost:" + httpserver.identity.primaryPort + "/" + path, null, null) |
|
18 .QueryInterface(Ci.nsIHttpChannel); |
|
19 return chan; |
|
20 } |
|
21 |
|
22 function setup_chan(path, isPrivate, callback) { |
|
23 var chan = makeChan(path); |
|
24 chan.QueryInterface(Ci.nsIPrivateBrowsingChannel).setPrivate(isPrivate); |
|
25 chan.asyncOpen(new ChannelListener(callback), null); |
|
26 } |
|
27 |
|
28 function set_cookie(value, callback) { |
|
29 return setup_chan('set?cookie=' + value, false, callback); |
|
30 } |
|
31 |
|
32 function set_private_cookie(value, callback) { |
|
33 return setup_chan('set?cookie=' + value, true, callback); |
|
34 } |
|
35 |
|
36 function check_cookie_presence(value, isPrivate, expected, callback) { |
|
37 var chan = setup_chan('present?cookie=' + value.replace('=','|'), isPrivate, function(req) { |
|
38 req.QueryInterface(Ci.nsIHttpChannel); |
|
39 do_check_eq(req.responseStatus, expected ? 200 : 404); |
|
40 callback(req); |
|
41 }); |
|
42 } |
|
43 |
|
44 function presentHandler(metadata, response) { |
|
45 var present = false; |
|
46 var match = /cookie=([^&]*)/.exec(metadata.queryString); |
|
47 if (match) { |
|
48 try { |
|
49 present = metadata.getHeader("Cookie").indexOf(match[1].replace("|","=")) != -1; |
|
50 } catch (x) { |
|
51 } |
|
52 } |
|
53 response.setStatusLine("1.0", present ? 200 : 404, ""); |
|
54 } |
|
55 |
|
56 function setHandler(metadata, response) { |
|
57 response.setStatusLine("1.0", 200, "Cookie set"); |
|
58 var match = /cookie=([^&]*)/.exec(metadata.queryString); |
|
59 if (match) { |
|
60 response.setHeader("Set-Cookie", match[1]); |
|
61 } |
|
62 } |
|
63 |
|
64 function run_test() { |
|
65 // Allow all cookies if the pref service is available in this process. |
|
66 if (!inChildProcess()) |
|
67 Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); |
|
68 |
|
69 httpserver = new HttpServer(); |
|
70 httpserver.registerPathHandler("/set", setHandler); |
|
71 httpserver.registerPathHandler("/present", presentHandler); |
|
72 httpserver.start(-1); |
|
73 |
|
74 do_test_pending(); |
|
75 |
|
76 function check_cookie(req) { |
|
77 req.QueryInterface(Ci.nsIHttpChannel); |
|
78 do_check_eq(req.responseStatus, 200); |
|
79 try { |
|
80 do_check_true(req.getResponseHeader("Set-Cookie") != "", "expected a Set-Cookie header"); |
|
81 } catch (x) { |
|
82 do_throw("missing Set-Cookie header"); |
|
83 } |
|
84 |
|
85 runNextTest(); |
|
86 } |
|
87 |
|
88 let tests = []; |
|
89 |
|
90 function runNextTest() { |
|
91 do_execute_soon(tests.shift()); |
|
92 } |
|
93 |
|
94 tests.push(function() { |
|
95 set_cookie("C1=V1", check_cookie); |
|
96 }); |
|
97 tests.push(function() { |
|
98 set_private_cookie("C2=V2", check_cookie); |
|
99 }); |
|
100 tests.push(function() { |
|
101 // Check that the first cookie is present in a non-private request |
|
102 check_cookie_presence("C1=V1", false, true, runNextTest); |
|
103 }); |
|
104 tests.push(function() { |
|
105 // Check that the second cookie is present in a private request |
|
106 check_cookie_presence("C2=V2", true, true, runNextTest); |
|
107 }); |
|
108 tests.push(function() { |
|
109 // Check that the first cookie is not present in a private request |
|
110 check_cookie_presence("C1=V1", true, false, runNextTest); |
|
111 }); |
|
112 tests.push(function() { |
|
113 // Check that the second cookie is not present in a non-private request |
|
114 check_cookie_presence("C2=V2", false, false, runNextTest); |
|
115 }); |
|
116 |
|
117 // The following test only works in a non-e10s situation at the moment, |
|
118 // since the notification needs to run in the parent process but there is |
|
119 // no existing mechanism to make that happen. |
|
120 if (!inChildProcess()) { |
|
121 tests.push(function() { |
|
122 // Simulate all private browsing instances being closed |
|
123 var obsvc = Cc["@mozilla.org/observer-service;1"]. |
|
124 getService(Ci.nsIObserverService); |
|
125 obsvc.notifyObservers(null, "last-pb-context-exited", null); |
|
126 // Check that all private cookies are now unavailable in new private requests |
|
127 check_cookie_presence("C2=V2", true, false, runNextTest); |
|
128 }); |
|
129 } |
|
130 |
|
131 tests.push(function() { httpserver.stop(do_test_finished); }); |
|
132 |
|
133 runNextTest(); |
|
134 } |