test_eviction.js (5599B)
1 const { NetUtil } = ChromeUtils.importESModule( 2 "resource://gre/modules/NetUtil.sys.mjs" 3 ); 4 5 const BASE_HOST = "example.org"; 6 7 const { CookieXPCShellUtils } = ChromeUtils.importESModule( 8 "resource://testing-common/CookieXPCShellUtils.sys.mjs" 9 ); 10 11 CookieXPCShellUtils.init(this); 12 CookieXPCShellUtils.createServer({ hosts: ["example.org"] }); 13 14 add_task(async function test_basic_eviction() { 15 do_get_profile(); 16 17 Services.prefs.setIntPref("network.cookie.staleThreshold", 0); 18 Services.prefs.setIntPref("network.cookie.quotaPerHost", 3); 19 Services.prefs.setIntPref("network.cookie.maxPerHost", 5); 20 21 // We don't want to have CookieJarSettings blocking this test. 22 Services.prefs.setBoolPref( 23 "network.cookieJarSettings.unblocked_for_testing", 24 true 25 ); 26 27 const BASE_URI = Services.io.newURI("http://" + BASE_HOST); 28 const FOO_PATH = Services.io.newURI("http://" + BASE_HOST + "/foo/"); 29 const BAR_PATH = Services.io.newURI("http://" + BASE_HOST + "/bar/"); 30 31 await setCookie("session_foo_path_1", null, "/foo", null, FOO_PATH); 32 await setCookie("session_foo_path_2", null, "/foo", null, FOO_PATH); 33 await setCookie("session_foo_path_3", null, "/foo", null, FOO_PATH); 34 await setCookie("session_foo_path_4", null, "/foo", null, FOO_PATH); 35 await setCookie("session_foo_path_5", null, "/foo", null, FOO_PATH); 36 verifyCookies( 37 [ 38 "session_foo_path_1", 39 "session_foo_path_2", 40 "session_foo_path_3", 41 "session_foo_path_4", 42 "session_foo_path_5", 43 ], 44 BASE_URI 45 ); 46 47 // Check if cookies are evicted by creation time. 48 await setCookie("session_foo_path_6", null, "/foo", null, FOO_PATH); 49 verifyCookies( 50 ["session_foo_path_4", "session_foo_path_5", "session_foo_path_6"], 51 BASE_URI 52 ); 53 54 await setCookie("session_bar_path_1", null, "/bar", null, BAR_PATH); 55 await setCookie("session_bar_path_2", null, "/bar", null, BAR_PATH); 56 57 verifyCookies( 58 [ 59 "session_foo_path_4", 60 "session_foo_path_5", 61 "session_foo_path_6", 62 "session_bar_path_1", 63 "session_bar_path_2", 64 ], 65 BASE_URI 66 ); 67 68 // Check if cookies are evicted by last accessed time. 69 await CookieXPCShellUtils.getCookieStringFromDocument(FOO_PATH.spec); 70 71 await setCookie("session_foo_path_7", null, "/foo", null, FOO_PATH); 72 verifyCookies( 73 ["session_foo_path_5", "session_foo_path_6", "session_foo_path_7"], 74 BASE_URI 75 ); 76 77 const EXPIRED_TIME = 3; 78 79 await setCookie( 80 "non_session_expired_foo_path_1", 81 null, 82 "/foo", 83 EXPIRED_TIME, 84 FOO_PATH 85 ); 86 await setCookie( 87 "non_session_expired_foo_path_2", 88 null, 89 "/foo", 90 EXPIRED_TIME, 91 FOO_PATH 92 ); 93 verifyCookies( 94 [ 95 "session_foo_path_5", 96 "session_foo_path_6", 97 "session_foo_path_7", 98 "non_session_expired_foo_path_1", 99 "non_session_expired_foo_path_2", 100 ], 101 BASE_URI 102 ); 103 104 // Check if expired cookies are evicted first. 105 await new Promise(resolve => do_timeout(EXPIRED_TIME * 1000, resolve)); 106 await setCookie("session_foo_path_8", null, "/foo", null, FOO_PATH); 107 verifyCookies( 108 ["session_foo_path_6", "session_foo_path_7", "session_foo_path_8"], 109 BASE_URI 110 ); 111 112 Services.cookies.removeAll(); 113 }); 114 115 // Verify that the given cookie names exist, and are ordered from least to most recently accessed 116 function verifyCookies(names, uri) { 117 Assert.equal(Services.cookies.countCookiesFromHost(uri.host), names.length); 118 let actual_cookies = []; 119 for (let cookie of Services.cookies.getCookiesFromHost(uri.host, {})) { 120 actual_cookies.push(cookie); 121 } 122 if (names.length != actual_cookies.length) { 123 let left = names.filter(function (n) { 124 return ( 125 actual_cookies.findIndex(function (c) { 126 return c.name == n; 127 }) == -1 128 ); 129 }); 130 let right = actual_cookies 131 .filter(function (c) { 132 return ( 133 names.findIndex(function (n) { 134 return c.name == n; 135 }) == -1 136 ); 137 }) 138 .map(function (c) { 139 return c.name; 140 }); 141 if (left.length) { 142 info("unexpected cookies: " + left); 143 } 144 if (right.length) { 145 info("expected cookies: " + right); 146 } 147 } 148 Assert.equal(names.length, actual_cookies.length); 149 actual_cookies.sort(function (a, b) { 150 if (a.lastAccessed < b.lastAccessed) { 151 return -1; 152 } 153 if (a.lastAccessed > b.lastAccessed) { 154 return 1; 155 } 156 return 0; 157 }); 158 for (var i = 0; i < names.length; i++) { 159 Assert.equal(names[i], actual_cookies[i].name); 160 Assert.equal(names[i].startsWith("session"), actual_cookies[i].isSession); 161 } 162 } 163 164 var lastValue = 0; 165 function setCookie(name, domain, path, maxAge, url) { 166 let value = name + "=" + ++lastValue; 167 var s = "setting cookie " + value; 168 if (domain) { 169 value += "; Domain=" + domain; 170 s += " (d=" + domain + ")"; 171 } 172 if (path) { 173 value += "; Path=" + path; 174 s += " (p=" + path + ")"; 175 } 176 if (maxAge) { 177 value += "; Max-Age=" + maxAge; 178 s += " (non-session)"; 179 } else { 180 s += " (session)"; 181 } 182 s += " for " + url.spec; 183 info(s); 184 185 let channel = NetUtil.newChannel({ 186 uri: url, 187 loadUsingSystemPrincipal: true, 188 contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT, 189 }); 190 191 Services.cookies.setCookieStringFromHttp(url, value, channel); 192 193 return new Promise(function (resolve) { 194 // Windows XP has low precision timestamps that cause our cookie eviction 195 // algorithm to produce different results from other platforms. We work around 196 // this by ensuring that there's a clear gap between each cookie update. 197 do_timeout(10, resolve); 198 }); 199 }