michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: // Test that domain eviction occurs when the cookies per base domain limit is michael@0: // reached, and that expired cookies are evicted before live cookies. michael@0: michael@0: let test_generator = do_run_test(); michael@0: michael@0: function run_test() michael@0: { michael@0: do_test_pending(); michael@0: do_run_generator(test_generator); michael@0: } michael@0: michael@0: function continue_test() michael@0: { michael@0: do_run_generator(test_generator); michael@0: } michael@0: michael@0: function do_run_test() michael@0: { michael@0: // Set the base domain limit to 50 so we have a known value. michael@0: Services.prefs.setIntPref("network.cookie.maxPerHost", 50); michael@0: michael@0: let futureExpiry = Math.floor(Date.now() / 1000 + 1000); michael@0: michael@0: // test eviction under the 50 cookies per base domain limit. this means michael@0: // that cookies for foo.com and bar.foo.com should count toward this limit, michael@0: // while cookies for baz.com should not. there are several tests we perform michael@0: // to make sure the base domain logic is working correctly. michael@0: michael@0: // 1) simplest case: set 100 cookies for "foo.bar" and make sure 50 survive. michael@0: setCookies("foo.bar", 100, futureExpiry); michael@0: do_check_eq(countCookies("foo.bar", "foo.bar"), 50); michael@0: michael@0: // 2) set cookies for different subdomains of "foo.baz", and an unrelated michael@0: // domain, and make sure all 50 within the "foo.baz" base domain are counted. michael@0: setCookies("foo.baz", 10, futureExpiry); michael@0: setCookies(".foo.baz", 10, futureExpiry); michael@0: setCookies("bar.foo.baz", 10, futureExpiry); michael@0: setCookies("baz.bar.foo.baz", 10, futureExpiry); michael@0: setCookies("unrelated.domain", 50, futureExpiry); michael@0: do_check_eq(countCookies("foo.baz", "baz.bar.foo.baz"), 40); michael@0: setCookies("foo.baz", 20, futureExpiry); michael@0: do_check_eq(countCookies("foo.baz", "baz.bar.foo.baz"), 50); michael@0: michael@0: // 3) ensure cookies are evicted by order of lastAccessed time, if the michael@0: // limit on cookies per base domain is reached. michael@0: setCookies("horse.radish", 10, futureExpiry); michael@0: michael@0: // Wait a while, to make sure the first batch of cookies is older than michael@0: // the second (timer resolution varies on different platforms). michael@0: do_timeout(100, continue_test); michael@0: yield; michael@0: michael@0: setCookies("tasty.horse.radish", 50, futureExpiry); michael@0: do_check_eq(countCookies("horse.radish", "horse.radish"), 50); michael@0: michael@0: let enumerator = Services.cookiemgr.enumerator; michael@0: while (enumerator.hasMoreElements()) { michael@0: let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); michael@0: michael@0: if (cookie.host == "horse.radish") michael@0: do_throw("cookies not evicted by lastAccessed order"); michael@0: } michael@0: michael@0: // Test that expired cookies for a domain are evicted before live ones. michael@0: let shortExpiry = Math.floor(Date.now() / 1000 + 2); michael@0: setCookies("captchart.com", 49, futureExpiry); michael@0: Services.cookiemgr.add("captchart.com", "", "test100", "eviction", michael@0: false, false, false, shortExpiry); michael@0: do_timeout(2100, continue_test); michael@0: yield; michael@0: michael@0: do_check_eq(countCookies("captchart.com", "captchart.com"), 50); michael@0: Services.cookiemgr.add("captchart.com", "", "test200", "eviction", michael@0: false, false, false, futureExpiry); michael@0: do_check_eq(countCookies("captchart.com", "captchart.com"), 50); michael@0: michael@0: let enumerator = Services.cookiemgr.getCookiesFromHost("captchart.com"); michael@0: while (enumerator.hasMoreElements()) { michael@0: let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); michael@0: do_check_true(cookie.expiry == futureExpiry); michael@0: } michael@0: michael@0: do_finish_generator_test(test_generator); michael@0: } michael@0: michael@0: // set 'aNumber' cookies with host 'aHost', with distinct names. michael@0: function michael@0: setCookies(aHost, aNumber, aExpiry) michael@0: { michael@0: for (let i = 0; i < aNumber; ++i) michael@0: Services.cookiemgr.add(aHost, "", "test" + i, "eviction", michael@0: false, false, false, aExpiry); michael@0: } michael@0: michael@0: // count how many cookies are within domain 'aBaseDomain', using three michael@0: // independent interface methods on nsICookieManager2: michael@0: // 1) 'enumerator', an enumerator of all cookies; michael@0: // 2) 'countCookiesFromHost', which returns the number of cookies within the michael@0: // base domain of 'aHost', michael@0: // 3) 'getCookiesFromHost', which returns an enumerator of 2). michael@0: function michael@0: countCookies(aBaseDomain, aHost) michael@0: { michael@0: let enumerator = Services.cookiemgr.enumerator; michael@0: michael@0: // count how many cookies are within domain 'aBaseDomain' using the cookie michael@0: // enumerator. michael@0: let cookies = []; michael@0: while (enumerator.hasMoreElements()) { michael@0: let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); michael@0: michael@0: if (cookie.host.length >= aBaseDomain.length && michael@0: cookie.host.slice(cookie.host.length - aBaseDomain.length) == aBaseDomain) michael@0: cookies.push(cookie); michael@0: } michael@0: michael@0: // confirm the count using countCookiesFromHost and getCookiesFromHost. michael@0: let result = cookies.length; michael@0: do_check_eq(Services.cookiemgr.countCookiesFromHost(aBaseDomain), michael@0: cookies.length); michael@0: do_check_eq(Services.cookiemgr.countCookiesFromHost(aHost), cookies.length); michael@0: michael@0: enumerator = Services.cookiemgr.getCookiesFromHost(aHost); michael@0: while (enumerator.hasMoreElements()) { michael@0: let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); michael@0: michael@0: if (cookie.host.length >= aBaseDomain.length && michael@0: cookie.host.slice(cookie.host.length - aBaseDomain.length) == aBaseDomain) { michael@0: let found = false; michael@0: for (let i = 0; i < cookies.length; ++i) { michael@0: if (cookies[i].host == cookie.host && cookies[i].name == cookie.name) { michael@0: found = true; michael@0: cookies.splice(i, 1); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: if (!found) michael@0: do_throw("cookie " + cookie.name + " not found in master enumerator"); michael@0: michael@0: } else { michael@0: do_throw("cookie host " + cookie.host + " not within domain " + aBaseDomain); michael@0: } michael@0: } michael@0: michael@0: do_check_eq(cookies.length, 0); michael@0: michael@0: return result; michael@0: } michael@0: