test_domain_eviction.js (5814B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 // Test that domain eviction occurs when the cookies per base domain limit is 5 // reached, and that expired cookies are evicted before live cookies. 6 7 "use strict"; 8 9 var test_generator = do_run_test(); 10 11 function run_test() { 12 do_test_pending(); 13 do_run_generator(test_generator); 14 } 15 16 function continue_test() { 17 do_run_generator(test_generator); 18 } 19 20 function* do_run_test() { 21 // Set quotaPerHost to maxPerHost, so there is only one cookie 22 // will be evicted everytime. 23 Services.prefs.setIntPref("network.cookie.quotaPerHost", 50); 24 // Set the base domain limit to 50 so we have a known value. 25 Services.prefs.setIntPref("network.cookie.maxPerHost", 50); 26 27 let futureExpiry = Date.now() + 1000 * 1000; 28 29 // test eviction under the 50 cookies per base domain limit. this means 30 // that cookies for foo.com and bar.foo.com should count toward this limit, 31 // while cookies for baz.com should not. there are several tests we perform 32 // to make sure the base domain logic is working correctly. 33 34 // 1) simplest case: set 100 cookies for "foo.bar" and make sure 50 survive. 35 setCookies("foo.bar", 100, futureExpiry); 36 Assert.equal(countCookies("foo.bar", "foo.bar"), 50); 37 38 // 2) set cookies for different subdomains of "foo.baz", and an unrelated 39 // domain, and make sure all 50 within the "foo.baz" base domain are counted. 40 setCookies("foo.baz", 10, futureExpiry); 41 setCookies(".foo.baz", 10, futureExpiry); 42 setCookies("bar.foo.baz", 10, futureExpiry); 43 setCookies("baz.bar.foo.baz", 10, futureExpiry); 44 setCookies("unrelated.domain", 50, futureExpiry); 45 Assert.equal(countCookies("foo.baz", "baz.bar.foo.baz"), 40); 46 setCookies("foo.baz", 20, futureExpiry); 47 Assert.equal(countCookies("foo.baz", "baz.bar.foo.baz"), 50); 48 49 // 3) ensure cookies are evicted by order of lastAccessed time, if the 50 // limit on cookies per base domain is reached. 51 setCookies("horse.radish", 10, futureExpiry); 52 53 // Wait a while, to make sure the first batch of cookies is older than 54 // the second (timer resolution varies on different platforms). 55 do_timeout(100, continue_test); 56 yield; 57 58 setCookies("tasty.horse.radish", 50, futureExpiry); 59 Assert.equal(countCookies("horse.radish", "horse.radish"), 50); 60 61 for (let cookie of Services.cookies.cookies) { 62 if (cookie.host == "horse.radish") { 63 do_throw("cookies not evicted by lastAccessed order"); 64 } 65 } 66 67 // Test that expired cookies for a domain are evicted before live ones. 68 let shortExpiry = Date.now() + 1000 * 2; 69 setCookies("captchart.com", 49, futureExpiry); 70 let cv = Services.cookies.add( 71 "captchart.com", 72 "", 73 "test100", 74 "eviction", 75 false, 76 false, 77 false, 78 shortExpiry, 79 {}, 80 Ci.nsICookie.SAMESITE_UNSET, 81 Ci.nsICookie.SCHEME_HTTPS 82 ); 83 Assert.equal(cv.result, Ci.nsICookieValidation.eOK, "Valid cookie"); 84 85 do_timeout(2100, continue_test); 86 yield; 87 88 Assert.equal(countCookies("captchart.com", "captchart.com"), 50); 89 cv = Services.cookies.add( 90 "captchart.com", 91 "", 92 "test200", 93 "eviction", 94 false, 95 false, 96 false, 97 futureExpiry, 98 {}, 99 Ci.nsICookie.SAMESITE_UNSET, 100 Ci.nsICookie.SCHEME_HTTPS 101 ); 102 Assert.equal(cv.result, Ci.nsICookieValidation.eOK, "Valid cookie"); 103 104 Assert.equal(countCookies("captchart.com", "captchart.com"), 50); 105 106 for (let cookie of Services.cookies.getCookiesFromHost("captchart.com", {})) { 107 Assert.equal(cookie.expiry, futureExpiry); 108 } 109 110 do_finish_generator_test(test_generator); 111 } 112 113 // set 'aNumber' cookies with host 'aHost', with distinct names. 114 function setCookies(aHost, aNumber, aExpiry) { 115 for (let i = 0; i < aNumber; ++i) { 116 const cv = Services.cookies.add( 117 aHost, 118 "", 119 "test" + i, 120 "eviction", 121 false, 122 false, 123 false, 124 aExpiry, 125 {}, 126 Ci.nsICookie.SAMESITE_UNSET, 127 Ci.nsICookie.SCHEME_HTTPS 128 ); 129 Assert.equal(cv.result, Ci.nsICookieValidation.eOK, "Valid cookie"); 130 } 131 } 132 133 // count how many cookies are within domain 'aBaseDomain', using three 134 // independent interface methods on nsICookieManager: 135 // 1) 'cookies', an array of all cookies; 136 // 2) 'countCookiesFromHost', which returns the number of cookies within the 137 // base domain of 'aHost', 138 // 3) 'getCookiesFromHost', which returns an array of 2). 139 function countCookies(aBaseDomain, aHost) { 140 // count how many cookies are within domain 'aBaseDomain' using the cookies 141 // array. 142 let cookies = []; 143 for (let cookie of Services.cookies.cookies) { 144 if ( 145 cookie.host.length >= aBaseDomain.length && 146 cookie.host.slice(cookie.host.length - aBaseDomain.length) == aBaseDomain 147 ) { 148 cookies.push(cookie); 149 } 150 } 151 152 // confirm the count using countCookiesFromHost and getCookiesFromHost. 153 let result = cookies.length; 154 Assert.equal( 155 Services.cookies.countCookiesFromHost(aBaseDomain), 156 cookies.length 157 ); 158 Assert.equal(Services.cookies.countCookiesFromHost(aHost), cookies.length); 159 160 for (let cookie of Services.cookies.getCookiesFromHost(aHost, {})) { 161 if ( 162 cookie.host.length >= aBaseDomain.length && 163 cookie.host.slice(cookie.host.length - aBaseDomain.length) == aBaseDomain 164 ) { 165 let found = false; 166 for (let i = 0; i < cookies.length; ++i) { 167 if (cookies[i].host == cookie.host && cookies[i].name == cookie.name) { 168 found = true; 169 cookies.splice(i, 1); 170 break; 171 } 172 } 173 174 if (!found) { 175 do_throw("cookie " + cookie.name + " not found in master cookies"); 176 } 177 } else { 178 do_throw( 179 "cookie host " + cookie.host + " not within domain " + aBaseDomain 180 ); 181 } 182 } 183 184 Assert.equal(cookies.length, 0); 185 186 return result; 187 }