tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_cacheflags.js (11014B)


      1 "use strict";
      2 
      3 const { HttpServer } = ChromeUtils.importESModule(
      4  "resource://testing-common/httpd.sys.mjs"
      5 );
      6 
      7 var httpserver = new HttpServer();
      8 httpserver.start(-1);
      9 
     10 // Need to randomize, because apparently no one clears our cache
     11 var suffix = Math.random();
     12 var httpBase = "http://localhost:" + httpserver.identity.primaryPort;
     13 var shortexpPath = "/shortexp" + suffix;
     14 var longexpPath = "/longexp/" + suffix;
     15 var longexp2Path = "/longexp/2/" + suffix;
     16 var nocachePath = "/nocache" + suffix;
     17 var nostorePath = "/nostore" + suffix;
     18 var test410Path = "/test410" + suffix;
     19 var test404Path = "/test404" + suffix;
     20 
     21 var PrivateBrowsingLoadContext = Cu.createPrivateLoadContext();
     22 
     23 function make_channel(url, flags, usePrivateBrowsing) {
     24  var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL;
     25 
     26  var uri = Services.io.newURI(url);
     27  var principal = Services.scriptSecurityManager.createContentPrincipal(uri, {
     28    privateBrowsingId: usePrivateBrowsing ? 1 : 0,
     29  });
     30 
     31  var req = NetUtil.newChannel({
     32    uri,
     33    loadingPrincipal: principal,
     34    securityFlags,
     35    contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
     36  });
     37 
     38  req.loadFlags = flags;
     39  if (usePrivateBrowsing) {
     40    req.notificationCallbacks = PrivateBrowsingLoadContext;
     41  }
     42  return req;
     43 }
     44 
     45 function Test(
     46  path,
     47  flags,
     48  expectSuccess,
     49  readFromCache,
     50  hitServer,
     51  usePrivateBrowsing /* defaults to false */
     52 ) {
     53  this.path = path;
     54  this.flags = flags;
     55  this.expectSuccess = expectSuccess;
     56  this.readFromCache = readFromCache;
     57  this.hitServer = hitServer;
     58  this.usePrivateBrowsing = usePrivateBrowsing;
     59 }
     60 
     61 Test.prototype = {
     62  flags: 0,
     63  expectSuccess: true,
     64  readFromCache: false,
     65  hitServer: true,
     66  usePrivateBrowsing: false,
     67  _buffer: "",
     68  _isFromCache: false,
     69 
     70  QueryInterface: ChromeUtils.generateQI([
     71    "nsIStreamListener",
     72    "nsIRequestObserver",
     73  ]),
     74 
     75  onStartRequest(request) {
     76    var cachingChannel = request.QueryInterface(Ci.nsICacheInfoChannel);
     77    this._isFromCache = request.isPending() && cachingChannel.isFromCache();
     78  },
     79 
     80  onDataAvailable(request, stream, offset, count) {
     81    this._buffer = this._buffer.concat(read_stream(stream, count));
     82  },
     83 
     84  onStopRequest(request, status) {
     85    Assert.equal(Components.isSuccessCode(status), this.expectSuccess);
     86    Assert.equal(this._isFromCache, this.readFromCache);
     87    Assert.equal(gHitServer, this.hitServer);
     88 
     89    do_timeout(0, run_next_test);
     90  },
     91 
     92  run() {
     93    dump(
     94      "Running:" +
     95        "\n  " +
     96        this.path +
     97        "\n  " +
     98        this.flags +
     99        "\n  " +
    100        this.expectSuccess +
    101        "\n  " +
    102        this.readFromCache +
    103        "\n  " +
    104        this.hitServer +
    105        "\n"
    106    );
    107    gHitServer = false;
    108    var channel = make_channel(this.path, this.flags, this.usePrivateBrowsing);
    109    channel.asyncOpen(this);
    110  },
    111 };
    112 
    113 var gHitServer = false;
    114 
    115 var gTests = [
    116  new Test(
    117    httpBase + shortexpPath,
    118    0,
    119    true, // expect success
    120    false, // read from cache
    121    true, // hit server
    122    true
    123  ), // USE PRIVATE BROWSING, so not cached for later requests
    124  new Test(
    125    httpBase + shortexpPath,
    126    0,
    127    true, // expect success
    128    false, // read from cache
    129    true
    130  ), // hit server
    131  new Test(
    132    httpBase + shortexpPath,
    133    0,
    134    true, // expect success
    135    true, // read from cache
    136    true
    137  ), // hit server
    138  new Test(
    139    httpBase + shortexpPath,
    140    Ci.nsIRequest.LOAD_BYPASS_CACHE,
    141    true, // expect success
    142    false, // read from cache
    143    true
    144  ), // hit server
    145  new Test(
    146    httpBase + shortexpPath,
    147    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE,
    148    false, // expect success
    149    false, // read from cache
    150    false
    151  ), // hit server
    152  new Test(
    153    httpBase + shortexpPath,
    154    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_NEVER,
    155    true, // expect success
    156    true, // read from cache
    157    false
    158  ), // hit server
    159  new Test(
    160    httpBase + shortexpPath,
    161    Ci.nsIRequest.LOAD_FROM_CACHE,
    162    true, // expect success
    163    true, // read from cache
    164    false
    165  ), // hit server
    166 
    167  new Test(
    168    httpBase + longexpPath,
    169    0,
    170    true, // expect success
    171    false, // read from cache
    172    true
    173  ), // hit server
    174  new Test(
    175    httpBase + longexpPath,
    176    0,
    177    true, // expect success
    178    true, // read from cache
    179    false
    180  ), // hit server
    181  new Test(
    182    httpBase + longexpPath,
    183    Ci.nsIRequest.LOAD_BYPASS_CACHE,
    184    true, // expect success
    185    false, // read from cache
    186    true
    187  ), // hit server
    188  new Test(
    189    httpBase + longexpPath,
    190    Ci.nsIRequest.VALIDATE_ALWAYS,
    191    true, // expect success
    192    true, // read from cache
    193    true
    194  ), // hit server
    195  new Test(
    196    httpBase + longexpPath,
    197    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE,
    198    true, // expect success
    199    true, // read from cache
    200    false
    201  ), // hit server
    202  new Test(
    203    httpBase + longexpPath,
    204    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_NEVER,
    205    true, // expect success
    206    true, // read from cache
    207    false
    208  ), // hit server
    209  new Test(
    210    httpBase + longexpPath,
    211    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_ALWAYS,
    212    false, // expect success
    213    false, // read from cache
    214    false
    215  ), // hit server
    216  new Test(
    217    httpBase + longexpPath,
    218    Ci.nsIRequest.LOAD_FROM_CACHE,
    219    true, // expect success
    220    true, // read from cache
    221    false
    222  ), // hit server
    223 
    224  new Test(
    225    httpBase + longexp2Path,
    226    0,
    227    true, // expect success
    228    false, // read from cache
    229    true
    230  ), // hit server
    231  new Test(
    232    httpBase + longexp2Path,
    233    0,
    234    true, // expect success
    235    true, // read from cache
    236    false
    237  ), // hit server
    238 
    239  new Test(
    240    httpBase + nocachePath,
    241    0,
    242    true, // expect success
    243    false, // read from cache
    244    true
    245  ), // hit server
    246  new Test(
    247    httpBase + nocachePath,
    248    0,
    249    true, // expect success
    250    true, // read from cache
    251    true
    252  ), // hit server
    253  new Test(
    254    httpBase + nocachePath,
    255    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE,
    256    false, // expect success
    257    false, // read from cache
    258    false
    259  ), // hit server
    260 
    261  // CACHE2: mayhemer - entry is doomed... I think the logic is wrong, we should not doom them
    262  // as they are not valid, but take them as they need to reval
    263  /*
    264  new Test(httpBase + nocachePath, Ci.nsIRequest.LOAD_FROM_CACHE,
    265           true,   // expect success
    266           true,   // read from cache
    267           false), // hit server
    268  */
    269 
    270  // LOAD_ONLY_FROM_CACHE would normally fail (because no-cache forces
    271  // a validation), but VALIDATE_NEVER should override that.
    272  new Test(
    273    httpBase + nocachePath,
    274    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_NEVER,
    275    true, // expect success
    276    true, // read from cache
    277    false
    278  ), // hit server
    279 
    280  // ... however, no-cache over ssl should act like no-store and force
    281  // a validation (and therefore failure) even if VALIDATE_NEVER is
    282  // set.
    283  /* XXX bug 466524: We can't currently start an ssl server in xpcshell tests,
    284                     so this test is currently disabled.
    285  new Test(httpsBase + nocachePath,
    286           Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE |
    287           Ci.nsIRequest.VALIDATE_NEVER,
    288           false,  // expect success
    289           false,  // read from cache
    290           false)  // hit server
    291  */
    292 
    293  new Test(
    294    httpBase + nostorePath,
    295    0,
    296    true, // expect success
    297    false, // read from cache
    298    true
    299  ), // hit server
    300  new Test(
    301    httpBase + nostorePath,
    302    0,
    303    true, // expect success
    304    false, // read from cache
    305    true
    306  ), // hit server
    307  new Test(
    308    httpBase + nostorePath,
    309    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE,
    310    false, // expect success
    311    false, // read from cache
    312    false
    313  ), // hit server
    314  new Test(
    315    httpBase + nostorePath,
    316    Ci.nsIRequest.LOAD_FROM_CACHE,
    317    true, // expect success
    318    true, // read from cache
    319    false
    320  ), // hit server
    321  // no-store should force the validation (and therefore failure, with
    322  // LOAD_ONLY_FROM_CACHE) even if VALIDATE_NEVER is set.
    323  new Test(
    324    httpBase + nostorePath,
    325    Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | Ci.nsIRequest.VALIDATE_NEVER,
    326    false, // expect success
    327    false, // read from cache
    328    false
    329  ), // hit server
    330 
    331  new Test(
    332    httpBase + test410Path,
    333    0,
    334    true, // expect success
    335    false, // read from cache
    336    true
    337  ), // hit server
    338  new Test(
    339    httpBase + test410Path,
    340    0,
    341    true, // expect success
    342    true, // read from cache
    343    false
    344  ), // hit server
    345 
    346  new Test(
    347    httpBase + test404Path,
    348    0,
    349    true, // expect success
    350    false, // read from cache
    351    true
    352  ), // hit server
    353  new Test(
    354    httpBase + test404Path,
    355    0,
    356    true, // expect success
    357    false, // read from cache
    358    true
    359  ), // hit server
    360 ];
    361 
    362 function run_next_test() {
    363  if (!gTests.length) {
    364    httpserver.stop(do_test_finished);
    365    return;
    366  }
    367 
    368  var test = gTests.shift();
    369  test.run();
    370 }
    371 
    372 function handler(httpStatus, metadata, response) {
    373  gHitServer = true;
    374  let etag;
    375  try {
    376    etag = metadata.getHeader("If-None-Match");
    377  } catch (ex) {
    378    etag = "";
    379  }
    380  if (etag == "testtag") {
    381    // Allow using the cached data
    382    response.setStatusLine(metadata.httpVersion, 304, "Not Modified");
    383  } else {
    384    response.setStatusLine(metadata.httpVersion, httpStatus, "Useless Phrase");
    385    response.setHeader("Content-Type", "text/plain", false);
    386    response.setHeader("ETag", "testtag", false);
    387    const body = "data";
    388    response.bodyOutputStream.write(body, body.length);
    389  }
    390 }
    391 
    392 function nocache_handler(metadata, response) {
    393  response.setHeader("Cache-Control", "no-cache", false);
    394  handler(200, metadata, response);
    395 }
    396 
    397 function nostore_handler(metadata, response) {
    398  response.setHeader("Cache-Control", "no-store", false);
    399  handler(200, metadata, response);
    400 }
    401 
    402 function test410_handler(metadata, response) {
    403  handler(410, metadata, response);
    404 }
    405 
    406 function test404_handler(metadata, response) {
    407  handler(404, metadata, response);
    408 }
    409 
    410 function shortexp_handler(metadata, response) {
    411  response.setHeader("Cache-Control", "max-age=0", false);
    412  handler(200, metadata, response);
    413 }
    414 
    415 function longexp_handler(metadata, response) {
    416  response.setHeader("Cache-Control", "max-age=10000", false);
    417  handler(200, metadata, response);
    418 }
    419 
    420 // test spaces around max-age value token
    421 function longexp2_handler(metadata, response) {
    422  response.setHeader("Cache-Control", "max-age = 10000", false);
    423  handler(200, metadata, response);
    424 }
    425 
    426 function run_test() {
    427  httpserver.registerPathHandler(shortexpPath, shortexp_handler);
    428  httpserver.registerPathHandler(longexpPath, longexp_handler);
    429  httpserver.registerPathHandler(longexp2Path, longexp2_handler);
    430  httpserver.registerPathHandler(nocachePath, nocache_handler);
    431  httpserver.registerPathHandler(nostorePath, nostore_handler);
    432  httpserver.registerPathHandler(test410Path, test410_handler);
    433  httpserver.registerPathHandler(test404Path, test404_handler);
    434 
    435  run_next_test();
    436  do_test_pending();
    437 }