diff options
Diffstat (limited to 'netwerk/test/unit/test_cacheflags.js')
-rw-r--r-- | netwerk/test/unit/test_cacheflags.js | 437 |
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(); +} |