summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/test_cacheflags.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/unit/test_cacheflags.js')
-rw-r--r--netwerk/test/unit/test_cacheflags.js437
1 files changed, 437 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_cacheflags.js b/netwerk/test/unit/test_cacheflags.js
new file mode 100644
index 0000000000..614f420a5e
--- /dev/null
+++ b/netwerk/test/unit/test_cacheflags.js
@@ -0,0 +1,437 @@
+"use strict";
+
+const { HttpServer } = ChromeUtils.importESModule(
+ "resource://testing-common/httpd.sys.mjs"
+);
+
+var httpserver = new HttpServer();
+httpserver.start(-1);
+
+// Need to randomize, because apparently no one clears our cache
+var suffix = Math.random();
+var httpBase = "http://localhost:" + httpserver.identity.primaryPort;
+var shortexpPath = "/shortexp" + suffix;
+var longexpPath = "/longexp/" + suffix;
+var longexp2Path = "/longexp/2/" + suffix;
+var nocachePath = "/nocache" + suffix;
+var nostorePath = "/nostore" + suffix;
+var test410Path = "/test410" + suffix;
+var test404Path = "/test404" + suffix;
+
+var PrivateBrowsingLoadContext = Cu.createPrivateLoadContext();
+
+function make_channel(url, flags, usePrivateBrowsing) {
+ var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL;
+
+ var uri = Services.io.newURI(url);
+ var principal = Services.scriptSecurityManager.createContentPrincipal(uri, {
+ privateBrowsingId: usePrivateBrowsing ? 1 : 0,
+ });
+
+ var req = NetUtil.newChannel({
+ uri,
+ loadingPrincipal: principal,
+ securityFlags,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
+ });
+
+ req.loadFlags = flags;
+ if (usePrivateBrowsing) {
+ req.notificationCallbacks = PrivateBrowsingLoadContext;
+ }
+ return req;
+}
+
+function Test(
+ path,
+ flags,
+ expectSuccess,
+ readFromCache,
+ hitServer,
+ usePrivateBrowsing /* defaults to false */
+) {
+ this.path = path;
+ this.flags = flags;
+ this.expectSuccess = expectSuccess;
+ this.readFromCache = readFromCache;
+ this.hitServer = hitServer;
+ this.usePrivateBrowsing = usePrivateBrowsing;
+}
+
+Test.prototype = {
+ flags: 0,
+ expectSuccess: true,
+ readFromCache: false,
+ hitServer: true,
+ usePrivateBrowsing: false,
+ _buffer: "",
+ _isFromCache: false,
+
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIStreamListener",
+ "nsIRequestObserver",
+ ]),
+
+ onStartRequest(request) {
+ var cachingChannel = request.QueryInterface(Ci.nsICacheInfoChannel);
+ this._isFromCache = request.isPending() && cachingChannel.isFromCache();
+ },
+
+ onDataAvailable(request, stream, offset, count) {
+ this._buffer = this._buffer.concat(read_stream(stream, count));
+ },
+
+ onStopRequest(request, status) {
+ Assert.equal(Components.isSuccessCode(status), this.expectSuccess);
+ Assert.equal(this._isFromCache, this.readFromCache);
+ Assert.equal(gHitServer, this.hitServer);
+
+ do_timeout(0, run_next_test);
+ },
+
+ run() {
+ dump(
+ "Running:" +
+ "\n " +
+ this.path +
+ "\n " +
+ this.flags +
+ "\n " +
+ this.expectSuccess +
+ "\n " +
+ this.readFromCache +
+ "\n " +
+ this.hitServer +
+ "\n"
+ );
+ gHitServer = false;
+ var channel = make_channel(this.path, this.flags, this.usePrivateBrowsing);
+ channel.asyncOpen(this);
+ },
+};
+
+var gHitServer = false;
+
+var gTests = [
+ new Test(
+ httpBase + shortexpPath,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true, // hit server
+ true
+ ), // USE PRIVATE BROWSING, so not cached for later requests
+ new Test(
+ httpBase + shortexpPath,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + shortexpPath,
+ 0,
+ true, // expect success
+ true, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + shortexpPath,
+ Ci.nsIRequest.LOAD_BYPASS_CACHE,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + shortexpPath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE,
+ false, // expect success
+ false, // read from cache
+ false
+ ), // hit server
+ new Test(
+ httpBase + shortexpPath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_NEVER,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+ new Test(
+ httpBase + shortexpPath,
+ Ci.nsIRequest.LOAD_FROM_CACHE,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+
+ new Test(
+ httpBase + longexpPath,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + longexpPath,
+ 0,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+ new Test(
+ httpBase + longexpPath,
+ Ci.nsIRequest.LOAD_BYPASS_CACHE,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + longexpPath,
+ Ci.nsIRequest.VALIDATE_ALWAYS,
+ true, // expect success
+ true, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + longexpPath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+ new Test(
+ httpBase + longexpPath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_NEVER,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+ new Test(
+ httpBase + longexpPath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_ALWAYS,
+ false, // expect success
+ false, // read from cache
+ false
+ ), // hit server
+ new Test(
+ httpBase + longexpPath,
+ Ci.nsIRequest.LOAD_FROM_CACHE,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+
+ new Test(
+ httpBase + longexp2Path,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + longexp2Path,
+ 0,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+
+ new Test(
+ httpBase + nocachePath,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + nocachePath,
+ 0,
+ true, // expect success
+ true, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + nocachePath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE,
+ false, // expect success
+ false, // read from cache
+ false
+ ), // hit server
+
+ // CACHE2: mayhemer - entry is doomed... I think the logic is wrong, we should not doom them
+ // as they are not valid, but take them as they need to reval
+ /*
+ new Test(httpBase + nocachePath, Ci.nsIRequest.LOAD_FROM_CACHE,
+ true, // expect success
+ true, // read from cache
+ false), // hit server
+ */
+
+ // LOAD_ONLY_FROM_CACHE would normally fail (because no-cache forces
+ // a validation), but VALIDATE_NEVER should override that.
+ new Test(
+ httpBase + nocachePath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_NEVER,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+
+ // ... however, no-cache over ssl should act like no-store and force
+ // a validation (and therefore failure) even if VALIDATE_NEVER is
+ // set.
+ /* XXX bug 466524: We can't currently start an ssl server in xpcshell tests,
+ so this test is currently disabled.
+ new Test(httpsBase + nocachePath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE |
+ Ci.nsIRequest.VALIDATE_NEVER,
+ false, // expect success
+ false, // read from cache
+ false) // hit server
+ */
+
+ new Test(
+ httpBase + nostorePath,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + nostorePath,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + nostorePath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE,
+ false, // expect success
+ false, // read from cache
+ false
+ ), // hit server
+ new Test(
+ httpBase + nostorePath,
+ Ci.nsIRequest.LOAD_FROM_CACHE,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+ // no-store should force the validation (and therefore failure, with
+ // LOAD_ONLY_FROM_CACHE) even if VALIDATE_NEVER is set.
+ new Test(
+ httpBase + nostorePath,
+ Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_NEVER,
+ false, // expect success
+ false, // read from cache
+ false
+ ), // hit server
+
+ new Test(
+ httpBase + test410Path,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + test410Path,
+ 0,
+ true, // expect success
+ true, // read from cache
+ false
+ ), // hit server
+
+ new Test(
+ httpBase + test404Path,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+ new Test(
+ httpBase + test404Path,
+ 0,
+ true, // expect success
+ false, // read from cache
+ true
+ ), // hit server
+];
+
+function run_next_test() {
+ if (!gTests.length) {
+ httpserver.stop(do_test_finished);
+ return;
+ }
+
+ var test = gTests.shift();
+ test.run();
+}
+
+function handler(httpStatus, metadata, response) {
+ gHitServer = true;
+ let etag;
+ try {
+ etag = metadata.getHeader("If-None-Match");
+ } catch (ex) {
+ etag = "";
+ }
+ if (etag == "testtag") {
+ // Allow using the cached data
+ response.setStatusLine(metadata.httpVersion, 304, "Not Modified");
+ } else {
+ response.setStatusLine(metadata.httpVersion, httpStatus, "Useless Phrase");
+ response.setHeader("Content-Type", "text/plain", false);
+ response.setHeader("ETag", "testtag", false);
+ const body = "data";
+ response.bodyOutputStream.write(body, body.length);
+ }
+}
+
+function nocache_handler(metadata, response) {
+ response.setHeader("Cache-Control", "no-cache", false);
+ handler(200, metadata, response);
+}
+
+function nostore_handler(metadata, response) {
+ response.setHeader("Cache-Control", "no-store", false);
+ handler(200, metadata, response);
+}
+
+function test410_handler(metadata, response) {
+ handler(410, metadata, response);
+}
+
+function test404_handler(metadata, response) {
+ handler(404, metadata, response);
+}
+
+function shortexp_handler(metadata, response) {
+ response.setHeader("Cache-Control", "max-age=0", false);
+ handler(200, metadata, response);
+}
+
+function longexp_handler(metadata, response) {
+ response.setHeader("Cache-Control", "max-age=10000", false);
+ handler(200, metadata, response);
+}
+
+// test spaces around max-age value token
+function longexp2_handler(metadata, response) {
+ response.setHeader("Cache-Control", "max-age = 10000", false);
+ handler(200, metadata, response);
+}
+
+function run_test() {
+ httpserver.registerPathHandler(shortexpPath, shortexp_handler);
+ httpserver.registerPathHandler(longexpPath, longexp_handler);
+ httpserver.registerPathHandler(longexp2Path, longexp2_handler);
+ httpserver.registerPathHandler(nocachePath, nocache_handler);
+ httpserver.registerPathHandler(nostorePath, nostore_handler);
+ httpserver.registerPathHandler(test410Path, test410_handler);
+ httpserver.registerPathHandler(test404Path, test404_handler);
+
+ run_next_test();
+ do_test_pending();
+}