3 Tests the Cache-control: stale-while-revalidate response directive.
5 Purpose is to check we perform the background revalidation when max-age=0 but
6 the window is set and we hit it.
9 - response is from the server and version=1
10 - max-age=0, stale-while-revalidate=9999
11 * Switch version of the data on the server and prolong the max-age to not let req #3
12 do a bck reval at the end of the test (prevent leaks/shutdown races.)
13 * Make request #2 in 2 seconds (entry should be expired by that time, but fall into
15 - response is from the cache, version=1
16 - a new background request should be made for the data
17 * Wait for "http-on-background-revalidation" notifying finish of the background reval.
19 - response is from the cache, version=2
26 const { HttpServer } = ChromeUtils.importESModule(
27 "resource://testing-common/httpd.sys.mjs"
32 let generate_response = ver => `response version=${ver}`;
34 function test_handler(metadata, response) {
35 const originalBody = generate_response(version);
36 response.setHeader("Content-Type", "text/html", false);
39 `max-age=${max_age}, stale-while-revalidate=9999`,
42 response.setStatusLine(metadata.httpVersion, 200, "OK");
43 response.bodyOutputStream.write(originalBody, originalBody.length);
46 function make_channel(url) {
47 return NetUtil.newChannel({
49 loadUsingSystemPrincipal: true,
50 }).QueryInterface(Ci.nsIHttpChannel);
53 async function get_response(channel, fromCache) {
54 return new Promise(resolve => {
56 new ChannelListener((request, buffer, ctx, isFromCache) => {
57 ok(fromCache == isFromCache, `got response from cache = ${fromCache}`);
64 async function sleep(time) {
65 return new Promise(resolve => {
66 do_timeout(time * 1000, resolve);
70 async function stop_server(httpserver) {
71 return new Promise(resolve => {
72 httpserver.stop(resolve);
76 async function background_reval_promise() {
77 return new Promise(resolve => {
78 Services.obs.addObserver(resolve, "http-on-background-revalidation");
82 add_task(async function () {
83 let httpserver = new HttpServer();
84 httpserver.registerPathHandler("/testdir", test_handler);
86 const PORT = httpserver.identity.primaryPort;
87 const URI = `http://localhost:${PORT}/testdir`;
93 response = await get_response(make_channel(URI), false);
94 ok(response == generate_response(1), "got response ver 1");
98 // must specifically wait for the internal channel to finish the reval to make
99 // the test race-free.
100 let reval_done = background_reval_promise();
104 response = await get_response(make_channel(URI), true);
105 ok(response == generate_response(1), "got response ver 1");
109 response = await get_response(make_channel(URI), true);
110 ok(response == generate_response(2), "got response ver 2");
112 await stop_server(httpserver);