tor-browser

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

test_bug203271.js (5958B)


      1 //
      2 // Tests if a response with an Expires-header in the past
      3 // and Cache-Control: max-age  in the future works as
      4 // specified in RFC 2616 section 14.9.3 by letting max-age
      5 // take precedence
      6 
      7 "use strict";
      8 
      9 const { HttpServer } = ChromeUtils.importESModule(
     10  "resource://testing-common/httpd.sys.mjs"
     11 );
     12 
     13 var httpserver = new HttpServer();
     14 var index = 0;
     15 var tests = [
     16  // original problem described in bug#203271
     17  {
     18    url: "/precedence",
     19    server: "0",
     20    expected: "0",
     21    responseheader: [
     22      "Expires: " + getDateString(-1),
     23      "Cache-Control: max-age=3600",
     24    ],
     25  },
     26 
     27  {
     28    url: "/precedence?0",
     29    server: "0",
     30    expected: "0",
     31    responseheader: [
     32      "Cache-Control: max-age=3600",
     33      "Expires: " + getDateString(-1),
     34    ],
     35  },
     36 
     37  // max-age=1s, expires=1 year from now
     38  {
     39    url: "/precedence?1",
     40    server: "0",
     41    expected: "0",
     42    responseheader: [
     43      "Expires: " + getDateString(1),
     44      "Cache-Control: max-age=1",
     45    ],
     46  },
     47 
     48  // expires=now
     49  {
     50    url: "/precedence?2",
     51    server: "0",
     52    expected: "0",
     53    responseheader: ["Expires: " + getDateString(0)],
     54  },
     55 
     56  // max-age=1s
     57  {
     58    url: "/precedence?3",
     59    server: "0",
     60    expected: "0",
     61    responseheader: ["Cache-Control: max-age=1"],
     62  },
     63 
     64  // The test below is the example from
     65  //
     66  //         https://bugzilla.mozilla.org/show_bug.cgi?id=203271#c27
     67  //
     68  //  max-age=2592000s (1 month), expires=1 year from now, date=1 year ago
     69  {
     70    url: "/precedence?4",
     71    server: "0",
     72    expected: "0",
     73    responseheader: [
     74      "Cache-Control: private, max-age=2592000",
     75      "Expires: " + getDateString(+1),
     76    ],
     77    explicitDate: getDateString(-1),
     78  },
     79 
     80  // The two tests below are also examples of clocks really out of synch
     81  // max-age=1s, date=1 year from now
     82  {
     83    url: "/precedence?5",
     84    server: "0",
     85    expected: "0",
     86    responseheader: ["Cache-Control: max-age=1"],
     87    explicitDate: getDateString(1),
     88  },
     89 
     90  // max-age=60s, date=1 year from now
     91  {
     92    url: "/precedence?6",
     93    server: "0",
     94    expected: "0",
     95    responseheader: ["Cache-Control: max-age=60"],
     96    explicitDate: getDateString(1),
     97  },
     98 
     99  // this is just to get a pause of 3s to allow cache-entries to expire
    100  { url: "/precedence?999", server: "0", expected: "0", delay: "3000" },
    101 
    102  // Below are the cases which actually matters
    103  { url: "/precedence", server: "1", expected: "0" }, // should be cached
    104 
    105  { url: "/precedence?0", server: "1", expected: "0" }, // should be cached
    106 
    107  { url: "/precedence?1", server: "1", expected: "1" }, // should have expired
    108 
    109  { url: "/precedence?2", server: "1", expected: "1" }, // should have expired
    110 
    111  { url: "/precedence?3", server: "1", expected: "1" }, // should have expired
    112 
    113  { url: "/precedence?4", server: "1", expected: "1" }, // should have expired
    114 
    115  { url: "/precedence?5", server: "1", expected: "1" }, // should have expired
    116 
    117  { url: "/precedence?6", server: "1", expected: "0" }, // should be cached
    118 ];
    119 
    120 function logit(i, data, ctx) {
    121  dump(
    122    "requested [" +
    123      tests[i].server +
    124      "] " +
    125      "got [" +
    126      data +
    127      "] " +
    128      "expected [" +
    129      tests[i].expected +
    130      "]"
    131  );
    132 
    133  if (tests[i].responseheader) {
    134    dump("\t[" + tests[i].responseheader + "]");
    135  }
    136  dump("\n");
    137  // Dump all response-headers
    138  dump("\n===================================\n");
    139  ctx.visitResponseHeaders({
    140    visitHeader(key, val) {
    141      dump("\t" + key + ":" + val + "\n");
    142    },
    143  });
    144  dump("===================================\n");
    145 }
    146 
    147 function setupChannel(suffix, value) {
    148  var chan = NetUtil.newChannel({
    149    uri: "http://localhost:" + httpserver.identity.primaryPort + suffix,
    150    loadUsingSystemPrincipal: true,
    151  });
    152  var httpChan = chan.QueryInterface(Ci.nsIHttpChannel);
    153  httpChan.requestMethod = "GET"; // default value, just being paranoid...
    154  httpChan.setRequestHeader("x-request", value, false);
    155  return httpChan;
    156 }
    157 
    158 function triggerNextTest() {
    159  var channel = setupChannel(tests[index].url, tests[index].server);
    160  channel.asyncOpen(new ChannelListener(checkValueAndTrigger, channel));
    161 }
    162 
    163 function checkValueAndTrigger(request, data, ctx) {
    164  logit(index, data, ctx);
    165  Assert.equal(tests[index].expected, data);
    166 
    167  if (index < tests.length - 1) {
    168    var delay = tests[index++].delay;
    169    if (delay) {
    170      do_timeout(delay, triggerNextTest);
    171    } else {
    172      triggerNextTest();
    173    }
    174  } else {
    175    httpserver.stop(do_test_finished);
    176  }
    177 }
    178 
    179 function run_test() {
    180  httpserver.registerPathHandler("/precedence", handler);
    181  httpserver.start(-1);
    182 
    183  // clear cache
    184  evict_cache_entries();
    185 
    186  triggerNextTest();
    187  do_test_pending();
    188 }
    189 
    190 function handler(metadata, response) {
    191  var body = metadata.getHeader("x-request");
    192  response.setHeader("Content-Type", "text/plain", false);
    193 
    194  var date = tests[index].explicitDate;
    195  if (date == undefined) {
    196    response.setHeader("Date", getDateString(0), false);
    197  } else {
    198    response.setHeader("Date", date, false);
    199  }
    200 
    201  var header = tests[index].responseheader;
    202  if (header == undefined) {
    203    response.setHeader("Last-Modified", getDateString(-1), false);
    204  } else {
    205    for (var i = 0; i < header.length; i++) {
    206      var splitHdr = header[i].split(": ");
    207      response.setHeader(splitHdr[0], splitHdr[1], false);
    208    }
    209  }
    210 
    211  response.setStatusLine(metadata.httpVersion, 200, "OK");
    212  response.bodyOutputStream.write(body, body.length);
    213 }
    214 
    215 function getDateString(yearDelta) {
    216  var months = [
    217    "Jan",
    218    "Feb",
    219    "Mar",
    220    "Apr",
    221    "May",
    222    "Jun",
    223    "Jul",
    224    "Aug",
    225    "Sep",
    226    "Oct",
    227    "Nov",
    228    "Dec",
    229  ];
    230  var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    231 
    232  var d = new Date();
    233  return (
    234    days[d.getUTCDay()] +
    235    ", " +
    236    d.getUTCDate() +
    237    " " +
    238    months[d.getUTCMonth()] +
    239    " " +
    240    (d.getUTCFullYear() + yearDelta) +
    241    " " +
    242    d.getUTCHours() +
    243    ":" +
    244    d.getUTCMinutes() +
    245    ":" +
    246    d.getUTCSeconds() +
    247    " UTC"
    248  );
    249 }