tor-browser

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

test_cache_match_vary.js (16802B)


      1 /* global context testDone:true */
      2 
      3 var requestURL =
      4  "//mochi.test:8888/tests/dom/cache/test/mochitest/vary.sjs?" + context;
      5 var name = "match-vary" + context;
      6 
      7 function checkResponse(r, response, responseText) {
      8  ok(r !== response, "The objects should not be the same");
      9  is(
     10    r.url,
     11    response.url.replace("#fragment", ""),
     12    "The URLs should be the same"
     13  );
     14  is(r.status, response.status, "The status codes should be the same");
     15  is(r.type, response.type, "The response types should be the same");
     16  is(r.ok, response.ok, "Both responses should have succeeded");
     17  is(
     18    r.statusText,
     19    response.statusText,
     20    "Both responses should have the same status text"
     21  );
     22  is(
     23    r.headers.get("Vary"),
     24    response.headers.get("Vary"),
     25    "Both responses should have the same Vary header"
     26  );
     27  return r.text().then(function (text) {
     28    is(text, responseText, "The response body should be correct");
     29  });
     30 }
     31 
     32 // Returns a Promise that will be resolved to an object with the following
     33 // properties:
     34 // * cache: A Cache object that contains one entry fetched with headers.
     35 // * response: A Response object which is the result of fetching a request
     36 //             with the specified headers.
     37 // * responseText: The body of the above response object.
     38 function setupTest(headers) {
     39  return setupTestMultipleEntries([headers]).then(function (test) {
     40    return {
     41      response: test.response[0],
     42      responseText: test.responseText[0],
     43      cache: test.cache,
     44    };
     45  });
     46 }
     47 function setupTestMultipleEntries(headers) {
     48  ok(Array.isArray(headers), "headers should be an array");
     49  return new Promise(function (resolve, reject) {
     50    var response, responseText, cache;
     51    Promise.all(
     52      headers.map(function (h) {
     53        return fetch(requestURL, { headers: h });
     54      })
     55    )
     56      .then(function (res) {
     57        response = res;
     58        return Promise.all(
     59          response.map(function (r) {
     60            return r.text();
     61          })
     62        );
     63      })
     64      .then(function (text) {
     65        responseText = text;
     66        return caches.open(name);
     67      })
     68      .then(function (c) {
     69        cache = c;
     70        return Promise.all(
     71          headers.map(function (h) {
     72            return c.add(new Request(requestURL, { headers: h }));
     73          })
     74        );
     75      })
     76      .then(function () {
     77        resolve({ response, responseText, cache });
     78      })
     79      .catch(function (err) {
     80        reject(err);
     81      });
     82  });
     83 }
     84 
     85 function testBasics() {
     86  var test;
     87  return setupTest({ WhatToVary: "Custom" })
     88    .then(function (t) {
     89      test = t;
     90      // Ensure that searching without specifying a Custom header succeeds.
     91      return test.cache.match(requestURL);
     92    })
     93    .then(function (r) {
     94      return checkResponse(r, test.response, test.responseText);
     95    })
     96    .then(function () {
     97      // Ensure that searching with a non-matching value for the Custom header fails.
     98      return test.cache.match(
     99        new Request(requestURL, { headers: { Custom: "foo=bar" } })
    100      );
    101    })
    102    .then(function (r) {
    103      is(
    104        typeof r,
    105        "undefined",
    106        "Searching for a request with an unknown Vary header should not succeed"
    107      );
    108      // Ensure that searching with a non-matching value for the Custom header but with ignoreVary set succeeds.
    109      return test.cache.match(
    110        new Request(requestURL, { headers: { Custom: "foo=bar" } }),
    111        { ignoreVary: true }
    112      );
    113    })
    114    .then(function (r) {
    115      return checkResponse(r, test.response, test.responseText);
    116    });
    117 }
    118 
    119 function testBasicKeys() {
    120  function checkRequest(reqs) {
    121    is(reqs.length, 1, "One request expected");
    122    ok(reqs[0].url.includes(requestURL), "The correct request expected");
    123    ok(
    124      reqs[0].headers.get("WhatToVary"),
    125      "Custom",
    126      "The correct request headers expected"
    127    );
    128  }
    129  var test;
    130  return setupTest({ WhatToVary: "Custom" })
    131    .then(function (t) {
    132      test = t;
    133      // Ensure that searching without specifying a Custom header succeeds.
    134      return test.cache.keys(requestURL);
    135    })
    136    .then(function (r) {
    137      return checkRequest(r);
    138    })
    139    .then(function () {
    140      // Ensure that searching with a non-matching value for the Custom header fails.
    141      return test.cache.keys(
    142        new Request(requestURL, { headers: { Custom: "foo=bar" } })
    143      );
    144    })
    145    .then(function (r) {
    146      is(
    147        r.length,
    148        0,
    149        "Searching for a request with an unknown Vary header should not succeed"
    150      );
    151      // Ensure that searching with a non-matching value for the Custom header but with ignoreVary set succeeds.
    152      return test.cache.keys(
    153        new Request(requestURL, { headers: { Custom: "foo=bar" } }),
    154        { ignoreVary: true }
    155      );
    156    })
    157    .then(function (r) {
    158      return checkRequest(r);
    159    });
    160 }
    161 
    162 function testStar() {
    163  function ensurePromiseRejected(promise) {
    164    return promise.then(
    165      function () {
    166        ok(false, "Promise should be rejected");
    167      },
    168      function (err) {
    169        is(
    170          err.name,
    171          "TypeError",
    172          "Attempting to store a Response with a Vary:* header must fail"
    173        );
    174      }
    175    );
    176  }
    177  return new Promise(function (resolve, reject) {
    178    var cache;
    179    caches.open(name).then(function (c) {
    180      cache = c;
    181      Promise.all([
    182        ensurePromiseRejected(
    183          cache.add(
    184            new Request(requestURL + "1", { headers: { WhatToVary: "*" } })
    185          )
    186        ),
    187        ensurePromiseRejected(
    188          cache.addAll([
    189            new Request(requestURL + "2", { headers: { WhatToVary: "*" } }),
    190            requestURL + "3",
    191          ])
    192        ),
    193        ensurePromiseRejected(
    194          fetch(
    195            new Request(requestURL + "4", { headers: { WhatToVary: "*" } })
    196          ).then(function (response) {
    197            return cache.put(requestURL + "4", response);
    198          })
    199        ),
    200        ensurePromiseRejected(
    201          cache.add(
    202            new Request(requestURL + "5", {
    203              headers: { WhatToVary: "*,User-Agent" },
    204            })
    205          )
    206        ),
    207        ensurePromiseRejected(
    208          cache.addAll([
    209            new Request(requestURL + "6", {
    210              headers: { WhatToVary: "*,User-Agent" },
    211            }),
    212            requestURL + "7",
    213          ])
    214        ),
    215        ensurePromiseRejected(
    216          fetch(
    217            new Request(requestURL + "8", {
    218              headers: { WhatToVary: "*,User-Agent" },
    219            })
    220          ).then(function (response) {
    221            return cache.put(requestURL + "8", response);
    222          })
    223        ),
    224        ensurePromiseRejected(
    225          cache.add(
    226            new Request(requestURL + "9", {
    227              headers: { WhatToVary: "User-Agent,*" },
    228            })
    229          )
    230        ),
    231        ensurePromiseRejected(
    232          cache.addAll([
    233            new Request(requestURL + "10", {
    234              headers: { WhatToVary: "User-Agent,*" },
    235            }),
    236            requestURL + "10",
    237          ])
    238        ),
    239        ensurePromiseRejected(
    240          fetch(
    241            new Request(requestURL + "11", {
    242              headers: { WhatToVary: "User-Agent,*" },
    243            })
    244          ).then(function (response) {
    245            return cache.put(requestURL + "11", response);
    246          })
    247        ),
    248      ]).then(reject, resolve);
    249    });
    250  });
    251 }
    252 
    253 function testMatch() {
    254  var test;
    255  return setupTest({ WhatToVary: "Custom", Custom: "foo=bar" })
    256    .then(function (t) {
    257      test = t;
    258      // Ensure that searching with a different Custom header fails.
    259      return test.cache.match(
    260        new Request(requestURL, { headers: { Custom: "bar=baz" } })
    261      );
    262    })
    263    .then(function (r) {
    264      is(
    265        typeof r,
    266        "undefined",
    267        "Searching for a request with a non-matching Custom header should not succeed"
    268      );
    269      // Ensure that searching with the same Custom header succeeds.
    270      return test.cache.match(
    271        new Request(requestURL, { headers: { Custom: "foo=bar" } })
    272      );
    273    })
    274    .then(function (r) {
    275      return checkResponse(r, test.response, test.responseText);
    276    });
    277 }
    278 
    279 function testInvalidHeaderName() {
    280  var test;
    281  return setupTest({ WhatToVary: "Foo/Bar, Custom-User-Agent" })
    282    .then(function (t) {
    283      test = t;
    284      // Ensure that searching with a different User-Agent header fails.
    285      return test.cache.match(
    286        new Request(requestURL, { headers: { "Custom-User-Agent": "MyUA" } })
    287      );
    288    })
    289    .then(function (r) {
    290      is(
    291        typeof r,
    292        "undefined",
    293        "Searching for a request with a non-matching Custom-User-Agent header should not succeed"
    294      );
    295      // Ensure that searching with a different Custom-User-Agent header but with ignoreVary succeeds.
    296      return test.cache.match(
    297        new Request(requestURL, { headers: { "Custom-User-Agent": "MyUA" } }),
    298        { ignoreVary: true }
    299      );
    300    })
    301    .then(function (r) {
    302      return checkResponse(r, test.response, test.responseText);
    303    })
    304    .then(function () {
    305      // Ensure that we do not mistakenly recognize the tokens in the invalid header name.
    306      return test.cache.match(
    307        new Request(requestURL, { headers: { Foo: "foobar" } })
    308      );
    309    })
    310    .then(function (r) {
    311      return checkResponse(r, test.response, test.responseText);
    312    });
    313 }
    314 
    315 function testMultipleHeaders() {
    316  var test;
    317  return setupTest({ WhatToVary: "Custom-Referer,\tCustom-Accept-Encoding" })
    318    .then(function (t) {
    319      test = t;
    320      // Ensure that searching with a different Referer header fails.
    321      return test.cache.match(
    322        new Request(requestURL, {
    323          headers: { "Custom-Referer": "https://somesite.com/" },
    324        })
    325      );
    326    })
    327    .then(function (r) {
    328      is(
    329        typeof r,
    330        "undefined",
    331        "Searching for a request with a non-matching Custom-Referer header should not succeed"
    332      );
    333      // Ensure that searching with a different Custom-Referer header but with ignoreVary succeeds.
    334      return test.cache.match(
    335        new Request(requestURL, {
    336          headers: { "Custom-Referer": "https://somesite.com/" },
    337        }),
    338        { ignoreVary: true }
    339      );
    340    })
    341    .then(function (r) {
    342      return checkResponse(r, test.response, test.responseText);
    343    })
    344    .then(function () {
    345      // Ensure that searching with a different Custom-Accept-Encoding header fails.
    346      return test.cache.match(
    347        new Request(requestURL, {
    348          headers: { "Custom-Accept-Encoding": "myencoding" },
    349        })
    350      );
    351    })
    352    .then(function (r) {
    353      is(
    354        typeof r,
    355        "undefined",
    356        "Searching for a request with a non-matching Custom-Accept-Encoding header should not succeed"
    357      );
    358      // Ensure that searching with a different Custom-Accept-Encoding header but with ignoreVary succeeds.
    359      return test.cache.match(
    360        new Request(requestURL, {
    361          headers: { "Custom-Accept-Encoding": "myencoding" },
    362        }),
    363        { ignoreVary: true }
    364      );
    365    })
    366    .then(function (r) {
    367      return checkResponse(r, test.response, test.responseText);
    368    })
    369    .then(function () {
    370      // Ensure that searching with an empty Custom-Referer header succeeds.
    371      return test.cache.match(
    372        new Request(requestURL, { headers: { "Custom-Referer": "" } })
    373      );
    374    })
    375    .then(function (r) {
    376      return checkResponse(r, test.response, test.responseText);
    377    })
    378    .then(function () {
    379      // Ensure that searching with an empty Custom-Accept-Encoding header succeeds.
    380      return test.cache.match(
    381        new Request(requestURL, { headers: { "Custom-Accept-Encoding": "" } })
    382      );
    383    })
    384    .then(function (r) {
    385      return checkResponse(r, test.response, test.responseText);
    386    })
    387    .then(function () {
    388      // Ensure that searching with an empty Custom-Referer header but with a different Custom-Accept-Encoding header fails.
    389      return test.cache.match(
    390        new Request(requestURL, {
    391          headers: {
    392            "Custom-Referer": "",
    393            "Custom-Accept-Encoding": "myencoding",
    394          },
    395        })
    396      );
    397    })
    398    .then(function (r) {
    399      is(
    400        typeof r,
    401        "undefined",
    402        "Searching for a request with a non-matching Custom-Accept-Encoding header should not succeed"
    403      );
    404      // Ensure that searching with an empty Custom-Referer header but with a different Custom-Accept-Encoding header and ignoreVary succeeds.
    405      return test.cache.match(
    406        new Request(requestURL, {
    407          headers: {
    408            "Custom-Referer": "",
    409            "Custom-Accept-Encoding": "myencoding",
    410          },
    411        }),
    412        { ignoreVary: true }
    413      );
    414    })
    415    .then(function (r) {
    416      return checkResponse(r, test.response, test.responseText);
    417    });
    418 }
    419 
    420 function testMultipleCacheEntries() {
    421  var test;
    422  return setupTestMultipleEntries([
    423    { WhatToVary: "Accept-Language", "Accept-Language": "en-US" },
    424    { WhatToVary: "Accept-Language", "Accept-Language": "en-US, fa-IR" },
    425  ])
    426    .then(function (t) {
    427      test = t;
    428      return test.cache.matchAll();
    429    })
    430    .then(function (r) {
    431      is(r.length, 2, "Two cache entries should be stored in the DB");
    432      // Ensure that searching without specifying an Accept-Language header fails.
    433      return test.cache.matchAll(requestURL);
    434    })
    435    .then(function (r) {
    436      is(
    437        r.length,
    438        0,
    439        "Searching for a request without specifying an Accept-Language header should not succeed"
    440      );
    441      // Ensure that searching without specifying an Accept-Language header but with ignoreVary succeeds.
    442      return test.cache.matchAll(requestURL, { ignoreVary: true });
    443    })
    444    .then(function (r) {
    445      return Promise.all([
    446        checkResponse(r[0], test.response[0], test.responseText[0]),
    447        checkResponse(r[1], test.response[1], test.responseText[1]),
    448      ]);
    449    })
    450    .then(function () {
    451      // Ensure that searching with Accept-Language: en-US succeeds.
    452      return test.cache.matchAll(
    453        new Request(requestURL, { headers: { "Accept-Language": "en-US" } })
    454      );
    455    })
    456    .then(function (r) {
    457      is(r.length, 1, "One cache entry should be found");
    458      return checkResponse(r[0], test.response[0], test.responseText[0]);
    459    })
    460    .then(function () {
    461      // Ensure that searching with Accept-Language: en-US,fa-IR succeeds.
    462      return test.cache.matchAll(
    463        new Request(requestURL, {
    464          headers: { "Accept-Language": "en-US, fa-IR" },
    465        })
    466      );
    467    })
    468    .then(function (r) {
    469      is(r.length, 1, "One cache entry should be found");
    470      return checkResponse(r[0], test.response[1], test.responseText[1]);
    471    })
    472    .then(function () {
    473      // Ensure that searching with a valid Accept-Language header but with ignoreVary returns both entries.
    474      return test.cache.matchAll(
    475        new Request(requestURL, { headers: { "Accept-Language": "en-US" } }),
    476        { ignoreVary: true }
    477      );
    478    })
    479    .then(function (r) {
    480      return Promise.all([
    481        checkResponse(r[0], test.response[0], test.responseText[0]),
    482        checkResponse(r[1], test.response[1], test.responseText[1]),
    483      ]);
    484    })
    485    .then(function () {
    486      // Ensure that searching with Accept-Language: fa-IR fails.
    487      return test.cache.matchAll(
    488        new Request(requestURL, { headers: { "Accept-Language": "fa-IR" } })
    489      );
    490    })
    491    .then(function (r) {
    492      is(
    493        r.length,
    494        0,
    495        "Searching for a request with a different Accept-Language header should not succeed"
    496      );
    497      // Ensure that searching with Accept-Language: fa-IR but with ignoreVary should succeed.
    498      return test.cache.matchAll(
    499        new Request(requestURL, { headers: { "Accept-Language": "fa-IR" } }),
    500        { ignoreVary: true }
    501      );
    502    })
    503    .then(function (r) {
    504      is(r.length, 2, "Two cache entries should be found");
    505      return Promise.all([
    506        checkResponse(r[0], test.response[0], test.responseText[0]),
    507        checkResponse(r[1], test.response[1], test.responseText[1]),
    508      ]);
    509    });
    510 }
    511 
    512 // Make sure to clean up after each test step.
    513 function step(testPromise) {
    514  return testPromise.then(
    515    function () {
    516      caches.delete(name);
    517    },
    518    function () {
    519      caches.delete(name);
    520    }
    521  );
    522 }
    523 
    524 step(testBasics())
    525  .then(function () {
    526    return step(testBasicKeys());
    527  })
    528  .then(function () {
    529    return step(testStar());
    530  })
    531  .then(function () {
    532    return step(testMatch());
    533  })
    534  .then(function () {
    535    return step(testInvalidHeaderName());
    536  })
    537  .then(function () {
    538    return step(testMultipleHeaders());
    539  })
    540  .then(function () {
    541    return step(testMultipleCacheEntries());
    542  })
    543  .then(function () {
    544    testDone();
    545  });