tor-browser

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

test_bug1830022.js (5260B)


      1 "use strict";
      2 
      3 const { HttpServer } = ChromeUtils.importESModule(
      4  "resource://testing-common/httpd.sys.mjs"
      5 );
      6 
      7 function makeChannel(url) {
      8  return NetUtil.newChannel({
      9    uri: url,
     10    loadUsingSystemPrincipal: true,
     11  }).QueryInterface(Ci.nsIHttpChannel);
     12 }
     13 
     14 ChromeUtils.defineLazyGetter(this, "URL", function () {
     15  return "http://localhost:" + httpServer.identity.primaryPort;
     16 });
     17 
     18 let httpServer = null;
     19 
     20 function pathHandler(metadata, response) {
     21  var body;
     22  if (metadata.hasHeader("Idempotency-Key")) {
     23    response.setStatusLine(metadata.httpVersion, 200, "OK");
     24    // echo back the header for further validation
     25    let IDK = metadata.getHeader("Idempotency-Key");
     26    response.setHeader("Idempotency-Key", IDK, false);
     27    body = "success";
     28  } else {
     29    response.setStatusLine(
     30      metadata.httpVersion,
     31      500,
     32      "missing Idempotency-Key"
     33    );
     34    body = "failed";
     35  }
     36  response.bodyOutputStream.write(body, body.length);
     37 }
     38 
     39 // Helper-method to validate that the "Idempotency-Key" value that we
     40 // generate matches the expected format and is the same in the response.
     41 // Meant to be called inside of a test that's been added via add_task.
     42 function validateAutomaticallyAddedHeaderVal(chan) {
     43  let valueFromRequest = chan.getRequestHeader("Idempotency-Key");
     44  let valueFromResponse = chan.getResponseHeader("Idempotency-Key");
     45 
     46  // Validate that the header's got a nonempty value, and that the
     47  // response matches the request:
     48  Assert.notEqual(valueFromRequest, "");
     49  Assert.notEqual(valueFromResponse, "");
     50  Assert.equal(valueFromRequest, valueFromResponse);
     51 
     52  // Further validation on the value (just focusing on valueFromRequest,
     53  // since at this point we know that valueFromResponse is equal to it):
     54  // * We expect the value to be formatted as a nonempy double-quoted string,
     55  // (i.e. length must be at least 3), as part of the "sf-string" syntax:
     56  Assert.greaterOrEqual(valueFromRequest.length, 3);
     57  Assert.ok(valueFromRequest.startsWith('"'));
     58  Assert.ok(valueFromRequest.endsWith('"'));
     59 
     60  // * Inside the double-quotes, we expect the value to be formatted as an
     61  // unsigned integer. The spec doesn't require this, but that's the
     62  // representation we use for now, so let's be sure we don't inadvertently
     63  // stray from that format (except as a deliberate choice, which would
     64  // involve an update to this test's expectations).
     65  let quotedPortion = valueFromRequest.slice(1, -1);
     66  let parsedInteger = Number.parseInt(quotedPortion);
     67  Assert.ok(!Number.isNaN(parsedInteger));
     68  Assert.greaterOrEqual(parsedInteger, 0);
     69 }
     70 
     71 add_setup(async () => {
     72  httpServer = new HttpServer();
     73  httpServer.registerPathHandler("/test_bug1830022", pathHandler);
     74  httpServer.start(-1);
     75  registerCleanupFunction(async () => await httpServer.stop());
     76 });
     77 
     78 // tests if we add the header for the POST request
     79 add_task(async function idempotency_key_addition_for_post() {
     80  let chan = makeChannel(URL + "/test_bug1830022");
     81  chan.requestMethod = "POST";
     82  await new Promise(resolve => {
     83    chan.asyncOpen(new ChannelListener(resolve));
     84  });
     85  validateAutomaticallyAddedHeaderVal(chan);
     86 });
     87 
     88 // tests if we add the header for the PATCH request
     89 add_task(async function idempotency_key_addition_for_patch() {
     90  let chan = makeChannel(URL + "/test_bug1830022");
     91  chan.requestMethod = "PATCH";
     92  await new Promise(resolve => {
     93    chan.asyncOpen(new ChannelListener(resolve));
     94  });
     95  validateAutomaticallyAddedHeaderVal(chan);
     96 });
     97 
     98 // tests Idempotency key's uniqueness
     99 add_task(async function idempotency_key_uniqueness() {
    100  let chan = makeChannel(URL + "/test_bug1830022");
    101  chan.requestMethod = "POST";
    102  await new Promise(resolve => {
    103    chan.asyncOpen(new ChannelListener(resolve));
    104  });
    105 
    106  let chan2 = makeChannel(URL + "/test_bug1830022");
    107  chan2.requestMethod = "POST";
    108  await new Promise(resolve => {
    109    chan2.asyncOpen(new ChannelListener(resolve));
    110  });
    111 
    112  Assert.notEqual(
    113    chan.getRequestHeader("Idempotency-Key"),
    114    chan2.getRequestHeader("Idempotency-Key")
    115  );
    116 
    117  // tests if the Idempotency key is same for reposts
    118  let chan3 = makeChannel(URL + "/test_bug1830022");
    119  chan3.requestMethod = "POST";
    120  await new Promise(resolve => {
    121    chan3.asyncOpen(new ChannelListener(resolve));
    122  });
    123 
    124  let cachekey = chan3.QueryInterface(Ci.nsICacheInfoChannel).cacheKey;
    125 
    126  let chan4 = makeChannel(URL + "/test_bug1830022");
    127  chan4.requestMethod = "POST";
    128  chan4.QueryInterface(Ci.nsICacheInfoChannel).cacheKey = cachekey;
    129  await new Promise(resolve => {
    130    chan4.asyncOpen(new ChannelListener(resolve));
    131  });
    132 
    133  Assert.equal(
    134    chan3.getRequestHeader("Idempotency-Key"),
    135    chan4.getRequestHeader("Idempotency-Key")
    136  );
    137 });
    138 
    139 // tests if we do not overwrite the header that is set before opening the channel
    140 add_task(async function idempotency_key_addition_for_post() {
    141  // construct the channel
    142  let chan = makeChannel(URL + "/test_bug1830022");
    143  chan.setRequestHeader("Idempotency-Key", "U-V-W-X-Y-Z", false);
    144  chan.requestMethod = "POST";
    145  await new Promise(resolve => {
    146    chan.asyncOpen(new ChannelListener(resolve));
    147  });
    148  Assert.equal(chan.getRequestHeader("Idempotency-Key"), "U-V-W-X-Y-Z");
    149  Assert.equal(chan.getResponseHeader("Idempotency-Key"), "U-V-W-X-Y-Z");
    150 });