tor-browser

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

cache-put.https.any.js (16193B)


      1 // META: title=Cache.put
      2 // META: global=window,worker
      3 // META: script=/common/get-host-info.sub.js
      4 // META: script=./resources/test-helpers.js
      5 // META: timeout=long
      6 
      7 var test_url = 'https://example.com/foo';
      8 var test_body = 'Hello world!';
      9 const { REMOTE_HOST } = get_host_info();
     10 
     11 cache_test(function(cache) {
     12    var request = new Request(test_url);
     13    var response = new Response(test_body);
     14    return cache.put(request, response)
     15      .then(function(result) {
     16          assert_equals(result, undefined,
     17                        'Cache.put should resolve with undefined on success.');
     18        });
     19  }, 'Cache.put called with simple Request and Response');
     20 
     21 cache_test(function(cache) {
     22    var test_url = new URL('./resources/simple.txt', location.href).href;
     23    var request = new Request(test_url);
     24    var response;
     25    return fetch(test_url)
     26      .then(function(fetch_result) {
     27          response = fetch_result.clone();
     28          return cache.put(request, fetch_result);
     29        })
     30      .then(function() {
     31          return cache.match(test_url);
     32        })
     33      .then(function(result) {
     34          assert_response_equals(result, response,
     35                                 'Cache.put should update the cache with ' +
     36                                 'new request and response.');
     37          return result.text();
     38        })
     39      .then(function(body) {
     40          assert_equals(body, 'a simple text file\n',
     41                        'Cache.put should store response body.');
     42        });
     43  }, 'Cache.put called with Request and Response from fetch()');
     44 
     45 cache_test(function(cache) {
     46    var request = new Request(test_url);
     47    var response = new Response(test_body);
     48    assert_false(request.bodyUsed,
     49                 '[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' +
     50                 'Request.bodyUsed should be initially false.');
     51    return cache.put(request, response)
     52      .then(function() {
     53        assert_false(request.bodyUsed,
     54                     'Cache.put should not mark empty request\'s body used');
     55      });
     56  }, 'Cache.put with Request without a body');
     57 
     58 cache_test(function(cache) {
     59    var request = new Request(test_url);
     60    var response = new Response();
     61    assert_false(response.bodyUsed,
     62                 '[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' +
     63                 'Response.bodyUsed should be initially false.');
     64    return cache.put(request, response)
     65      .then(function() {
     66        assert_false(response.bodyUsed,
     67                     'Cache.put should not mark empty response\'s body used');
     68      });
     69  }, 'Cache.put with Response without a body');
     70 
     71 cache_test(function(cache) {
     72    var request = new Request(test_url);
     73    var response = new Response(test_body);
     74    return cache.put(request, response.clone())
     75      .then(function() {
     76          return cache.match(test_url);
     77        })
     78      .then(function(result) {
     79          assert_response_equals(result, response,
     80                                 'Cache.put should update the cache with ' +
     81                                 'new Request and Response.');
     82        });
     83  }, 'Cache.put with a Response containing an empty URL');
     84 
     85 cache_test(function(cache) {
     86    var request = new Request(test_url);
     87    var response = new Response('', {
     88        status: 200,
     89        headers: [['Content-Type', 'text/plain']]
     90      });
     91    return cache.put(request, response)
     92      .then(function() {
     93          return cache.match(test_url);
     94        })
     95      .then(function(result) {
     96          assert_equals(result.status, 200, 'Cache.put should store status.');
     97          assert_equals(result.headers.get('Content-Type'), 'text/plain',
     98                        'Cache.put should store headers.');
     99          return result.text();
    100        })
    101      .then(function(body) {
    102          assert_equals(body, '',
    103                        'Cache.put should store response body.');
    104        });
    105  }, 'Cache.put with an empty response body');
    106 
    107 cache_test(function(cache, test) {
    108    var request = new Request(test_url);
    109    var response = new Response('', {
    110        status: 206,
    111        headers: [['Content-Type', 'text/plain']]
    112      });
    113 
    114    return promise_rejects_js(
    115      test,
    116      TypeError,
    117      cache.put(request, response),
    118      'Cache.put should reject 206 Responses with a TypeError.');
    119  }, 'Cache.put with synthetic 206 response');
    120 
    121 cache_test(function(cache, test) {
    122    var test_url = new URL('./resources/fetch-status.py?status=206', location.href).href;
    123    var request = new Request(test_url);
    124    var response;
    125    return fetch(test_url)
    126      .then(function(fetch_result) {
    127          assert_equals(fetch_result.status, 206,
    128                        'Test framework error: The status code should be 206.');
    129          response = fetch_result.clone();
    130          return promise_rejects_js(test, TypeError, cache.put(request, fetch_result));
    131        });
    132  }, 'Cache.put with HTTP 206 response');
    133 
    134 cache_test(function(cache, test) {
    135    // We need to jump through some hoops to allow the test to perform opaque
    136    // response filtering, but bypass the ORB safelist check. This is
    137    // done, by forcing the MIME type retrieval to fail and the
    138    // validation of partial first response to succeed.
    139    var pipe = "status(206)|header(Content-Type,)|header(Content-Range, bytes 0-1/41)|slice(null, 1)";
    140    var test_url = new URL(`./resources/blank.html?pipe=${pipe}`, location.href);
    141    test_url.hostname = REMOTE_HOST;
    142    var request = new Request(test_url.href, { mode: 'no-cors' });
    143    var response;
    144    return fetch(request)
    145      .then(function(fetch_result) {
    146          assert_equals(fetch_result.type, 'opaque',
    147              'Test framework error: The response type should be opaque.');
    148          assert_equals(fetch_result.status, 0,
    149              'Test framework error: The status code should be 0 for an ' +
    150              ' opaque-filtered response. This is actually HTTP 206.');
    151          response = fetch_result.clone();
    152          return cache.put(request, fetch_result);
    153        })
    154      .then(function() {
    155          return cache.match(test_url);
    156        })
    157      .then(function(result) {
    158          assert_not_equals(result, undefined,
    159              'Cache.put should store an entry for the opaque response');
    160        });
    161  }, 'Cache.put with opaque-filtered HTTP 206 response');
    162 
    163 cache_test(function(cache) {
    164    var test_url = new URL('./resources/fetch-status.py?status=500', location.href).href;
    165    var request = new Request(test_url);
    166    var response;
    167    return fetch(test_url)
    168      .then(function(fetch_result) {
    169          assert_equals(fetch_result.status, 500,
    170                        'Test framework error: The status code should be 500.');
    171          response = fetch_result.clone();
    172          return cache.put(request, fetch_result);
    173        })
    174      .then(function() {
    175          return cache.match(test_url);
    176        })
    177      .then(function(result) {
    178          assert_response_equals(result, response,
    179                                 'Cache.put should update the cache with ' +
    180                                 'new request and response.');
    181          return result.text();
    182        })
    183      .then(function(body) {
    184          assert_equals(body, '',
    185                        'Cache.put should store response body.');
    186        });
    187  }, 'Cache.put with HTTP 500 response');
    188 
    189 cache_test(function(cache) {
    190    var alternate_response_body = 'New body';
    191    var alternate_response = new Response(alternate_response_body,
    192                                          { statusText: 'New status' });
    193    return cache.put(new Request(test_url),
    194                     new Response('Old body', { statusText: 'Old status' }))
    195      .then(function() {
    196          return cache.put(new Request(test_url), alternate_response.clone());
    197        })
    198      .then(function() {
    199          return cache.match(test_url);
    200        })
    201      .then(function(result) {
    202          assert_response_equals(result, alternate_response,
    203                                 'Cache.put should replace existing ' +
    204                                 'response with new response.');
    205          return result.text();
    206        })
    207      .then(function(body) {
    208          assert_equals(body, alternate_response_body,
    209                        'Cache put should store new response body.');
    210        });
    211  }, 'Cache.put called twice with matching Requests and different Responses');
    212 
    213 cache_test(function(cache) {
    214    var first_url = test_url;
    215    var second_url = first_url + '#(O_o)';
    216    var third_url = first_url + '#fragment';
    217    var alternate_response_body = 'New body';
    218    var alternate_response = new Response(alternate_response_body,
    219                                          { statusText: 'New status' });
    220    return cache.put(new Request(first_url),
    221                     new Response('Old body', { statusText: 'Old status' }))
    222      .then(function() {
    223          return cache.put(new Request(second_url), alternate_response.clone());
    224        })
    225      .then(function() {
    226          return cache.match(test_url);
    227        })
    228      .then(function(result) {
    229          assert_response_equals(result, alternate_response,
    230                                 'Cache.put should replace existing ' +
    231                                 'response with new response.');
    232          return result.text();
    233        })
    234      .then(function(body) {
    235          assert_equals(body, alternate_response_body,
    236                        'Cache put should store new response body.');
    237        })
    238      .then(function() {
    239          return cache.put(new Request(third_url), alternate_response.clone());
    240        })
    241      .then(function() {
    242          return cache.keys();
    243        })
    244      .then(function(results) {
    245          // Should match urls (without fragments or with different ones) to the
    246          // same cache key. However, result.url should be the latest url used.
    247          assert_equals(results[0].url, third_url);
    248          return;
    249        });
    250 }, 'Cache.put called multiple times with request URLs that differ only by a fragment');
    251 
    252 cache_test(function(cache) {
    253    var url = 'http://example.com/foo';
    254    return cache.put(url, new Response('some body'))
    255      .then(function() { return cache.match(url); })
    256      .then(function(response) { return response.text(); })
    257      .then(function(body) {
    258          assert_equals(body, 'some body',
    259                        'Cache.put should accept a string as request.');
    260        });
    261  }, 'Cache.put with a string request');
    262 
    263 cache_test(function(cache, test) {
    264    return promise_rejects_js(
    265      test,
    266      TypeError,
    267      cache.put(new Request(test_url), 'Hello world!'),
    268      'Cache.put should only accept a Response object as the response.');
    269  }, 'Cache.put with an invalid response');
    270 
    271 cache_test(function(cache, test) {
    272    return promise_rejects_js(
    273      test,
    274      TypeError,
    275      cache.put(new Request('file:///etc/passwd'),
    276                new Response(test_body)),
    277      'Cache.put should reject non-HTTP/HTTPS requests with a TypeError.');
    278  }, 'Cache.put with a non-HTTP/HTTPS request');
    279 
    280 cache_test(function(cache) {
    281    var response = new Response(test_body);
    282    return cache.put(new Request('relative-url'), response.clone())
    283      .then(function() {
    284          return cache.match(new URL('relative-url', location.href).href);
    285        })
    286      .then(function(result) {
    287          assert_response_equals(result, response,
    288                                 'Cache.put should accept a relative URL ' +
    289                                 'as the request.');
    290        });
    291  }, 'Cache.put with a relative URL');
    292 
    293 cache_test(function(cache, test) {
    294    var request = new Request('http://example.com/foo', { method: 'HEAD' });
    295    return promise_rejects_js(
    296      test,
    297      TypeError,
    298      cache.put(request, new Response(test_body)),
    299      'Cache.put should throw a TypeError for non-GET requests.');
    300  }, 'Cache.put with a non-GET request');
    301 
    302 cache_test(function(cache, test) {
    303    return promise_rejects_js(
    304      test,
    305      TypeError,
    306      cache.put(new Request(test_url), null),
    307      'Cache.put should throw a TypeError for a null response.');
    308  }, 'Cache.put with a null response');
    309 
    310 cache_test(function(cache, test) {
    311    var request = new Request(test_url, {method: 'POST', body: test_body});
    312    return promise_rejects_js(
    313      test,
    314      TypeError,
    315      cache.put(request, new Response(test_body)),
    316      'Cache.put should throw a TypeError for a POST request.');
    317  }, 'Cache.put with a POST request');
    318 
    319 cache_test(function(cache) {
    320    var response = new Response(test_body);
    321    assert_false(response.bodyUsed,
    322                 '[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' +
    323                 'Response.bodyUsed should be initially false.');
    324    return response.text().then(function() {
    325      assert_true(
    326        response.bodyUsed,
    327        '[https://fetch.spec.whatwg.org/#concept-body-consume-body] ' +
    328          'The text() method should make the body disturbed.');
    329      var request = new Request(test_url);
    330      return cache.put(request, response).then(() => {
    331          assert_unreached('cache.put should be rejected');
    332        }, () => {});
    333    });
    334  }, 'Cache.put with a used response body');
    335 
    336 cache_test(function(cache) {
    337    var response = new Response(test_body);
    338    return cache.put(new Request(test_url), response)
    339      .then(function() {
    340          assert_throws_js(TypeError, () => response.body.getReader());
    341      });
    342  }, 'getReader() after Cache.put');
    343 
    344 cache_test(function(cache, test) {
    345    return promise_rejects_js(
    346      test,
    347      TypeError,
    348      cache.put(new Request(test_url),
    349                new Response(test_body, { headers: { VARY: '*' }})),
    350      'Cache.put should reject VARY:* Responses with a TypeError.');
    351  }, 'Cache.put with a VARY:* Response');
    352 
    353 cache_test(function(cache, test) {
    354    return promise_rejects_js(
    355      test,
    356      TypeError,
    357      cache.put(new Request(test_url),
    358                new Response(test_body,
    359                             { headers: { VARY: 'Accept-Language,*' }})),
    360      'Cache.put should reject Responses with an embedded VARY:* with a ' +
    361      'TypeError.');
    362  }, 'Cache.put with an embedded VARY:* Response');
    363 
    364 cache_test(async function(cache, test) {
    365    const url = new URL('./resources/vary.py?vary=*',
    366        get_host_info().HTTPS_REMOTE_ORIGIN + self.location.pathname);
    367    const request = new Request(url, { mode: 'no-cors' });
    368    const response = await fetch(request);
    369    assert_equals(response.type, 'opaque');
    370    await cache.put(request, response);
    371  }, 'Cache.put with a VARY:* opaque response should not reject');
    372 
    373 cache_test(function(cache) {
    374    var url = 'foo.html';
    375    var redirectURL = 'http://example.com/foo-bar.html';
    376    var redirectResponse = Response.redirect(redirectURL);
    377    assert_equals(redirectResponse.headers.get('Location'), redirectURL,
    378                  'Response.redirect() should set Location header.');
    379    return cache.put(url, redirectResponse.clone())
    380      .then(function() {
    381          return cache.match(url);
    382        })
    383      .then(function(response) {
    384          assert_response_equals(response, redirectResponse,
    385                                 'Redirect response is reproduced by the Cache API');
    386          assert_equals(response.headers.get('Location'), redirectURL,
    387                        'Location header is preserved by Cache API.');
    388        });
    389  }, 'Cache.put should store Response.redirect() correctly');
    390 
    391 cache_test(async (cache) => {
    392    var request = new Request(test_url);
    393    var response = new Response(new Blob([test_body]));
    394    await cache.put(request, response);
    395    var cachedResponse = await cache.match(request);
    396    assert_equals(await cachedResponse.text(), test_body);
    397  }, 'Cache.put called with simple Request and blob Response');
    398 
    399 cache_test(async (cache) => {
    400  var formData = new FormData();
    401  formData.append("name", "value");
    402 
    403  var request = new Request(test_url);
    404  var response = new Response(formData);
    405  await cache.put(request, response);
    406  var cachedResponse = await cache.match(request);
    407  var cachedResponseText = await cachedResponse.text();
    408  assert_true(cachedResponseText.indexOf("name=\"name\"\r\n\r\nvalue") !== -1);
    409 }, 'Cache.put called with simple Request and form data Response');
    410 
    411 done();