tor-browser

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

test_mismatch_last-modified.js (4587B)


      1 "use strict";
      2 
      3 const BinaryInputStream = Components.Constructor(
      4  "@mozilla.org/binaryinputstream;1",
      5  "nsIBinaryInputStream",
      6  "setInputStream"
      7 );
      8 
      9 const { HttpServer } = ChromeUtils.importESModule(
     10  "resource://testing-common/httpd.sys.mjs"
     11 );
     12 var httpserver = new HttpServer();
     13 
     14 // Test the handling of a cache revalidation with mismatching last-modified
     15 // headers. If we get such a revalidation the cache entry should be purged.
     16 // see bug 717350
     17 
     18 // In this test the wrong data is from 11-16-1994 with a value of 'A',
     19 // and the right data is from 11-15-1994 with a value of 'B'.
     20 
     21 // the same URL is requested 3 times. the first time the wrong data comes
     22 // back, the second time that wrong data is revalidated with a 304 but
     23 // a L-M header of the right data (this triggers a cache purge), and
     24 // the third time the right data is returned.
     25 
     26 var listener_3 = {
     27  // this listener is used to process the the request made after
     28  // the cache invalidation. it expects to see the 'right data'
     29 
     30  QueryInterface: ChromeUtils.generateQI([
     31    "nsIStreamListener",
     32    "nsIRequestObserver",
     33  ]),
     34 
     35  onStartRequest: function test_onStartR() {},
     36 
     37  onDataAvailable: function test_ODA(request, inputStream, offset, count) {
     38    var data = new BinaryInputStream(inputStream).readByteArray(count);
     39 
     40    Assert.equal(data[0], "B".charCodeAt(0));
     41  },
     42 
     43  onStopRequest: function test_onStopR() {
     44    httpserver.stop(do_test_finished);
     45  },
     46 };
     47 
     48 ChromeUtils.defineLazyGetter(this, "listener_2", function () {
     49  return {
     50    // this listener is used to process the revalidation of the
     51    // corrupted cache entry. its revalidation prompts it to be cleaned
     52 
     53    QueryInterface: ChromeUtils.generateQI([
     54      "nsIStreamListener",
     55      "nsIRequestObserver",
     56    ]),
     57 
     58    onStartRequest: function test_onStartR() {},
     59 
     60    onDataAvailable: function test_ODA(request, inputStream, offset, count) {
     61      var data = new BinaryInputStream(inputStream).readByteArray(count);
     62 
     63      // This is 'A' from a cache revalidation, but that reval will clean the cache
     64      // because of mismatched last-modified response headers
     65 
     66      Assert.equal(data[0], "A".charCodeAt(0));
     67    },
     68 
     69    onStopRequest: function test_onStopR(request) {
     70      request.QueryInterface(Ci.nsIHttpChannel);
     71      var chan = NetUtil.newChannel({
     72        uri: "http://localhost:" + httpserver.identity.primaryPort + "/test1",
     73        loadUsingSystemPrincipal: true,
     74      });
     75      chan.asyncOpen(listener_3);
     76    },
     77  };
     78 });
     79 
     80 ChromeUtils.defineLazyGetter(this, "listener_1", function () {
     81  return {
     82    // this listener processes the initial request from a empty cache.
     83    // the server responds with the wrong data ('A')
     84 
     85    QueryInterface: ChromeUtils.generateQI([
     86      "nsIStreamListener",
     87      "nsIRequestObserver",
     88    ]),
     89 
     90    onStartRequest: function test_onStartR() {},
     91 
     92    onDataAvailable: function test_ODA(request, inputStream, offset, count) {
     93      var data = new BinaryInputStream(inputStream).readByteArray(count);
     94      Assert.equal(data[0], "A".charCodeAt(0));
     95    },
     96 
     97    onStopRequest: function test_onStopR(request) {
     98      request.QueryInterface(Ci.nsIHttpChannel);
     99      var chan = NetUtil.newChannel({
    100        uri: "http://localhost:" + httpserver.identity.primaryPort + "/test1",
    101        loadUsingSystemPrincipal: true,
    102      });
    103      chan.asyncOpen(listener_2);
    104    },
    105  };
    106 });
    107 
    108 function run_test() {
    109  do_get_profile();
    110 
    111  evict_cache_entries();
    112 
    113  httpserver.registerPathHandler("/test1", handler);
    114  httpserver.start(-1);
    115 
    116  var port = httpserver.identity.primaryPort;
    117  var chan = NetUtil.newChannel({
    118    uri: "http://localhost:" + port + "/test1",
    119    loadUsingSystemPrincipal: true,
    120  });
    121  chan.asyncOpen(listener_1);
    122 
    123  do_test_pending();
    124 }
    125 
    126 var iter = 0;
    127 function handler(metadata, response) {
    128  iter++;
    129  if (metadata.hasHeader("If-Modified-Since")) {
    130    response.setStatusLine(metadata.httpVersion, 304, "Not Modified");
    131    response.setHeader("Last-Modified", "Tue, 15 Nov 1994 12:45:26 GMT", false);
    132  } else {
    133    response.setStatusLine(metadata.httpVersion, 200, "OK");
    134    response.setHeader("Cache-Control", "max-age=0", false);
    135    if (iter == 1) {
    136      // simulated wrong response
    137      response.setHeader(
    138        "Last-Modified",
    139        "Wed, 16 Nov 1994 00:00:00 GMT",
    140        false
    141      );
    142      response.bodyOutputStream.write("A", 1);
    143    }
    144    if (iter == 3) {
    145      // 'correct' response
    146      response.setHeader(
    147        "Last-Modified",
    148        "Tue, 15 Nov 1994 12:45:26 GMT",
    149        false
    150      );
    151      response.bodyOutputStream.write("B", 1);
    152    }
    153  }
    154 }