"use strict"; const { HttpServer } = ChromeUtils.importESModule( "resource://testing-common/httpd.sys.mjs" ); var response_code; var response_body; var request_time; var response_time; var cache_storage; var httpserver = new HttpServer(); httpserver.start(-1); var base_url = "http://localhost:" + httpserver.identity.primaryPort; var resource = "/resource"; var resource_url = base_url + resource; // Test flags var hit_server = false; function make_channel(aUrl) { // Reset test global status hit_server = false; var req = NetUtil.newChannel({ uri: aUrl, loadUsingSystemPrincipal: true }); req.QueryInterface(Ci.nsIHttpChannel); req.setRequestHeader("If-Modified-Since", request_time, false); return req; } function make_uri(aUrl) { return Services.io.newURI(aUrl); } function resource_handler(aMetadata, aResponse) { hit_server = true; Assert.ok(aMetadata.hasHeader("If-Modified-Since")); Assert.equal(aMetadata.getHeader("If-Modified-Since"), request_time); if (response_code == "200") { aResponse.setStatusLine(aMetadata.httpVersion, 200, "OK"); aResponse.setHeader("Content-Type", "text/plain", false); aResponse.setHeader("Last-Modified", response_time, false); aResponse.bodyOutputStream.write(response_body, response_body.length); } else if (response_code == "304") { aResponse.setStatusLine(aMetadata.httpVersion, 304, "Not Modified"); aResponse.setHeader("Returned-From-Handler", "1"); } } function check_cached_data(aCachedData, aCallback) { asyncOpenCacheEntry( resource_url, "disk", Ci.nsICacheStorage.OPEN_READONLY, null, function (aStatus, aEntry) { Assert.equal(aStatus, Cr.NS_OK); pumpReadStream(aEntry.openInputStream(0), function (aData) { Assert.equal(aData, aCachedData); aCallback(); }); } ); } function run_test() { do_get_profile(); evict_cache_entries(); do_test_pending(); cache_storage = getCacheStorage("disk"); httpserver.registerPathHandler(resource, resource_handler); wait_for_cache_index(run_next_test); } // 1. send custom conditional request when we don't have an entry // server returns 304 -> client receives 304 add_test(() => { response_code = "304"; response_body = ""; request_time = "Thu, 1 Jan 2009 00:00:00 GMT"; response_time = "Thu, 1 Jan 2009 00:00:00 GMT"; var ch = make_channel(resource_url); ch.asyncOpen( new ChannelListener(function (aRequest) { syncWithCacheIOThread(() => { Assert.ok(hit_server); Assert.equal( aRequest.QueryInterface(Ci.nsIHttpChannel).responseStatus, 304 ); Assert.ok(!cache_storage.exists(make_uri(resource_url), "")); Assert.equal(aRequest.getResponseHeader("Returned-From-Handler"), "1"); run_next_test(); }, true); }, null) ); }); // 2. send custom conditional request when we don't have an entry // server returns 200 -> result is cached add_test(() => { response_code = "200"; response_body = "content_body"; request_time = "Thu, 1 Jan 2009 00:00:00 GMT"; response_time = "Fri, 2 Jan 2009 00:00:00 GMT"; var ch = make_channel(resource_url); ch.asyncOpen( new ChannelListener(function (aRequest) { syncWithCacheIOThread(() => { Assert.ok(hit_server); Assert.equal( aRequest.QueryInterface(Ci.nsIHttpChannel).responseStatus, 200 ); Assert.ok(cache_storage.exists(make_uri(resource_url), "")); check_cached_data(response_body, run_next_test); }, true); }, null) ); }); // 3. send custom conditional request when we have an entry // server returns 304 -> client receives 304 and cached entry is unchanged add_test(() => { response_code = "304"; var cached_body = response_body; response_body = ""; request_time = "Fri, 2 Jan 2009 00:00:00 GMT"; response_time = "Fri, 2 Jan 2009 00:00:00 GMT"; var ch = make_channel(resource_url); ch.asyncOpen( new ChannelListener(function (aRequest, aData) { syncWithCacheIOThread(() => { Assert.ok(hit_server); Assert.equal( aRequest.QueryInterface(Ci.nsIHttpChannel).responseStatus, 304 ); Assert.ok(cache_storage.exists(make_uri(resource_url), "")); Assert.equal(aRequest.getResponseHeader("Returned-From-Handler"), "1"); Assert.equal(aData, ""); // Check the cache data is not changed check_cached_data(cached_body, run_next_test); }, true); }, null) ); }); // 4. send custom conditional request when we have an entry // server returns 200 -> result is cached add_test(() => { response_code = "200"; response_body = "updated_content_body"; request_time = "Fri, 2 Jan 2009 00:00:00 GMT"; response_time = "Sat, 3 Jan 2009 00:00:00 GMT"; var ch = make_channel(resource_url); ch.asyncOpen( new ChannelListener(function (aRequest) { syncWithCacheIOThread(() => { Assert.ok(hit_server); Assert.equal( aRequest.QueryInterface(Ci.nsIHttpChannel).responseStatus, 200 ); Assert.ok(cache_storage.exists(make_uri(resource_url), "")); // Check the cache data is updated check_cached_data(response_body, () => { run_next_test(); httpserver.stop(do_test_finished); }); }, true); }, null) ); });