From bf31664685a06bf9168a477e3b957bb8d88e496a Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Thu, 3 Oct 2019 03:43:31 +0000 Subject: [PATCH] Bug 1452562 [wpt PR 10348] - Allow range headers to pass through a service worker, a=testonly Automatic update from web-platform-testsAllow range headers to pass through a service worker (#10348) Tests for https://github.com/whatwg/fetch/pull/560 -- wpt-commits: fb6d16d92af29262b6137b79e61f0c4b136c6ac1 wpt-pr: 10348 UltraBlame original commit: 8b458f3d30b63afa745527bc31744f4971749224 --- testing/web-platform/meta/MANIFEST.json | 426 ++++++- .../tests/fetch/range/general.any.js | 398 ++++++ .../fetch/range/partial-script.window.js | 42 + .../tests/fetch/range/resources/basic.html | 5 + .../tests/fetch/range/resources/long-wav.py | 668 ++++++++++ .../fetch/range/resources/partial-script.py | 240 ++++ .../tests/fetch/range/resources/range-sw.js | 1109 +++++++++++++++++ .../tests/fetch/range/resources/stash-take.py | 46 + .../tests/fetch/range/resources/utils.js | 87 ++ .../tests/fetch/range/sw.https.window.js | 909 ++++++++++++++ 10 files changed, 3929 insertions(+), 1 deletion(-) create mode 100644 testing/web-platform/tests/fetch/range/general.any.js create mode 100644 testing/web-platform/tests/fetch/range/partial-script.window.js create mode 100644 testing/web-platform/tests/fetch/range/resources/basic.html create mode 100644 testing/web-platform/tests/fetch/range/resources/long-wav.py create mode 100644 testing/web-platform/tests/fetch/range/resources/partial-script.py create mode 100644 testing/web-platform/tests/fetch/range/resources/range-sw.js create mode 100644 testing/web-platform/tests/fetch/range/resources/stash-take.py create mode 100644 testing/web-platform/tests/fetch/range/resources/utils.js create mode 100644 testing/web-platform/tests/fetch/range/sw.https.window.js diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 4d5e4e332e2a9..8387e9b1716aa 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -1662847,6 +1662847,122 @@ py " fetch / +range +/ +resources +/ +basic +. +html +" +: +[ +[ +{ +} +] +] +" +fetch +/ +range +/ +resources +/ +long +- +wav +. +py +" +: +[ +[ +{ +} +] +] +" +fetch +/ +range +/ +resources +/ +partial +- +script +. +py +" +: +[ +[ +{ +} +] +] +" +fetch +/ +range +/ +resources +/ +range +- +sw +. +js +" +: +[ +[ +{ +} +] +] +" +fetch +/ +range +/ +resources +/ +stash +- +take +. +py +" +: +[ +[ +{ +} +] +] +" +fetch +/ +range +/ +resources +/ +utils +. +js +" +: +[ +[ +{ +} +] +] +" +fetch +/ sec - metadata @@ -2018384,6 +2018500,122 @@ html " fetch / +range +/ +general +. +any +. +js +" +: +[ +[ +" +/ +fetch +/ +range +/ +general +. +any +. +html +" +{ +} +] +[ +" +/ +fetch +/ +range +/ +general +. +any +. +worker +. +html +" +{ +} +] +] +" +fetch +/ +range +/ +partial +- +script +. +window +. +js +" +: +[ +[ +" +/ +fetch +/ +range +/ +partial +- +script +. +window +. +html +" +{ +} +] +] +" +fetch +/ +range +/ +sw +. +https +. +window +. +js +" +: +[ +[ +" +/ +fetch +/ +range +/ +sw +. +https +. +window +. +html +" +{ +} +] +] +" +fetch +/ sec - metadata @@ -3716272,6 +3716504,198 @@ support " fetch / +range +/ +general +. +any +. +js +" +: +[ +" +2c16c0398373fca53ae80aae1107868c8cdeb6b4 +" +" +testharness +" +] +" +fetch +/ +range +/ +partial +- +script +. +window +. +js +" +: +[ +" +1352080860b8671290919ab0d09cb41f4100763e +" +" +testharness +" +] +" +fetch +/ +range +/ +resources +/ +basic +. +html +" +: +[ +" +51a23151c28992fe062b36914463de216bd55fbe +" +" +support +" +] +" +fetch +/ +range +/ +resources +/ +long +- +wav +. +py +" +: +[ +" +a9bdaefeb4e9cefd4bb678832d7ffcbe1b3167f7 +" +" +support +" +] +" +fetch +/ +range +/ +resources +/ +partial +- +script +. +py +" +: +[ +" +d74bf301d56ad7d5ae4067e8e27ec544a21aa2ed +" +" +support +" +] +" +fetch +/ +range +/ +resources +/ +range +- +sw +. +js +" +: +[ +" +1ec66e1dd8bf9a11b058b90e32ca7caab2233d4d +" +" +support +" +] +" +fetch +/ +range +/ +resources +/ +stash +- +take +. +py +" +: +[ +" +9d29b6276fa690d6acb366bdb4d60a12bc57ea52 +" +" +support +" +] +" +fetch +/ +range +/ +resources +/ +utils +. +js +" +: +[ +" +81cc493a76265cc64408fc2d41a67434ec99391a +" +" +support +" +] +" +fetch +/ +range +/ +sw +. +https +. +window +. +js +" +: +[ +" +5bf1ebc9ce82990013831f2f7f55589e29a69bde +" +" +testharness +" +] +" +fetch +/ sec - metadata @@ -4073531,7 +4073955,7 @@ js : [ " -74ea529125a5e2c5cd3d350f7c56ae614f82010d +079d31394903266dddb067f8f4dba5a94e522bdc " " support diff --git a/testing/web-platform/tests/fetch/range/general.any.js b/testing/web-platform/tests/fetch/range/general.any.js new file mode 100644 index 0000000000000..631b599031dab --- /dev/null +++ b/testing/web-platform/tests/fetch/range/general.any.js @@ -0,0 +1,398 @@ +function +headersGuardNone +( +fill +) +{ +if +( +fill +) +return +new +Headers +( +fill +) +; +return +new +Headers +( +) +; +} +function +headersGuardResponse +( +fill +) +{ +const +opts += +{ +} +; +if +( +fill +) +opts +. +headers += +fill +; +return +new +Response +( +' +' +opts +) +. +headers +; +} +function +headersGuardRequest +( +fill +) +{ +const +opts += +{ +} +; +if +( +fill +) +opts +. +headers += +fill +; +return +new +Request +( +' +. +/ +' +opts +) +. +headers +; +} +function +headersGuardRequestNoCors +( +fill +) +{ +const +opts += +{ +mode +: +' +no +- +cors +' +} +; +if +( +fill +) +opts +. +headers += +fill +; +return +new +Request +( +' +. +/ +' +opts +) +. +headers +; +} +const +headerGuardTypes += +[ +[ +' +none +' +headersGuardNone +] +[ +' +response +' +headersGuardResponse +] +[ +' +request +' +headersGuardRequest +] +] +; +for +( +const +[ +guardType +createHeaders +] +of +headerGuardTypes +) +{ +test +( +( +) += +> +{ +let +headers += +createHeaders +( +{ +Range +: +' +foo +' +} +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +' +foo +' +) +; +headers += +createHeaders +( +) +; +headers +. +append +( +' +Range +' +' +foo +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +' +foo +' +) +; +headers += +createHeaders +( +) +; +headers +. +set +( +' +Range +' +' +foo +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +' +foo +' +) +; +} +Range +header +setting +allowed +for +guard +type +: +{ +guardType +} +) +; +} +test +( +( +) += +> +{ +let +headers += +headersGuardRequestNoCors +( +{ +Range +: +' +foo +' +} +) +; +assert_false +( +headers +. +has +( +' +Range +' +) +) +; +headers += +headersGuardRequestNoCors +( +) +; +headers +. +append +( +' +Range +' +' +foo +' +) +; +assert_false +( +headers +. +has +( +' +Range +' +) +) +; +headers += +headersGuardRequestNoCors +( +) +; +headers +. +set +( +' +Range +' +' +foo +' +) +; +assert_false +( +headers +. +has +( +' +Range +' +) +) +; +} +Privileged +header +not +allowed +for +guard +type +: +request +- +no +- +cors +) +; diff --git a/testing/web-platform/tests/fetch/range/partial-script.window.js b/testing/web-platform/tests/fetch/range/partial-script.window.js new file mode 100644 index 0000000000000..1431a439c8d4b --- /dev/null +++ b/testing/web-platform/tests/fetch/range/partial-script.window.js @@ -0,0 +1,42 @@ +promise_test +( +async +t += +> +{ +await +loadScript +( +' +resources +/ +partial +- +script +. +py +? +pretend +- +offset += +90000 +' +) +; +assert_true +( +self +. +scriptExecuted +) +; +} +Script +executed +from +partial +response +) +; diff --git a/testing/web-platform/tests/fetch/range/resources/basic.html b/testing/web-platform/tests/fetch/range/resources/basic.html new file mode 100644 index 0000000000000..d95ce5110b920 --- /dev/null +++ b/testing/web-platform/tests/fetch/range/resources/basic.html @@ -0,0 +1,5 @@ +< +! +DOCTYPE +html +> diff --git a/testing/web-platform/tests/fetch/range/resources/long-wav.py b/testing/web-platform/tests/fetch/range/resources/long-wav.py new file mode 100644 index 0000000000000..2ed14e317b659 --- /dev/null +++ b/testing/web-platform/tests/fetch/range/resources/long-wav.py @@ -0,0 +1,668 @@ +" +" +" +This +generates +a +30 +minute +silent +wav +and +is +capable +of +responding +to +Range +requests +. +" +" +" +import +time +import +re +import +struct +def +create_wav_header +( +sample_rate +bit_depth +channels +duration +) +: + +bytes_per_sample += +bit_depth +/ +8 + +block_align += +bytes_per_sample +* +channels + +byte_rate += +sample_rate +* +block_align + +sub_chunk_2_size += +duration +* +byte_rate + +data += +b +' +' + +data ++ += +b +' +RIFF +' + +data ++ += +struct +. +pack +( +' +< +L +' +36 ++ +sub_chunk_2_size +) + +data ++ += +b +' +WAVE +' + +data ++ += +b +' +fmt +' + +data ++ += +struct +. +pack +( +' +< +L +' +16 +) + +data ++ += +struct +. +pack +( +' +< +H +' +1 +) + +data ++ += +struct +. +pack +( +' +< +H +' +channels +) + +data ++ += +struct +. +pack +( +' +< +L +' +sample_rate +) + +data ++ += +struct +. +pack +( +' +< +L +' +byte_rate +) + +data ++ += +struct +. +pack +( +' +< +H +' +block_align +) + +data ++ += +struct +. +pack +( +' +< +H +' +bit_depth +) + +data ++ += +b +' +data +' + +data ++ += +struct +. +pack +( +' +< +L +' +sub_chunk_2_size +) + +return +data +def +main +( +request +response +) +: + +response +. +headers +. +set +( +" +Content +- +Type +" +" +audio +/ +wav +" +) + +response +. +headers +. +set +( +" +Accept +- +Ranges +" +" +bytes +" +) + +response +. +headers +. +set +( +" +Cache +- +Control +" +" +no +- +cache +" +) + +range_header += +request +. +headers +. +get +( +' +Range +' +' +' +) + +range_received_key += +request +. +GET +. +first +( +' +range +- +received +- +key +' +' +' +) + +if +range_received_key +and +range_header +: + +request +. +stash +. +put +( +range_received_key +' +range +- +header +- +received +' +' +/ +fetch +/ +range +/ +' +) + +sample_rate += +8000 + +bit_depth += +8 + +channels += +1 + +duration += +60 +* +5 + +total_length += +( +sample_rate +* +bit_depth +* +channels +* +duration +) +/ +8 + +bytes_remaining_to_send += +total_length + +initial_write += +' +' + +if +range_header +: + +response +. +status += +206 + +start +end += +re +. +search +( +r +' +^ +bytes += +( +\ +d +* +) +- +( +\ +d +* +) +' +range_header +) +. +groups +( +) + +start += +int +( +start +) + +end += +int +( +end +) +if +end +else +0 + +if +end +: + +bytes_remaining_to_send += +( +end ++ +1 +) +- +start + +else +: + +bytes_remaining_to_send += +total_length +- +start + +wav_header += +create_wav_header +( +sample_rate +bit_depth +channels +duration +) + +if +start +< +len +( +wav_header +) +: + +initial_write += +wav_header +[ +start +: +] + +if +bytes_remaining_to_send +< +len +( +initial_write +) +: + +initial_write += +initial_write +[ +0 +: +bytes_remaining_to_send +] + +content_range += +" +bytes +{ +} +- +{ +} +/ +{ +} +" +. +format +( +start +end +or +total_length +- +1 +total_length +) + +response +. +headers +. +set +( +" +Content +- +Range +" +content_range +) + +else +: + +initial_write += +create_wav_header +( +sample_rate +bit_depth +channels +duration +) + +response +. +headers +. +set +( +" +Content +- +Length +" +bytes_remaining_to_send +) + +response +. +write_status_headers +( +) + +response +. +writer +. +write +( +initial_write +) + +bytes_remaining_to_send +- += +len +( +initial_write +) + +while +bytes_remaining_to_send +> +0 +: + +if +not +response +. +writer +. +flush +( +) +: + +break + +to_send += +b +' +\ +x00 +' +* +min +( +bytes_remaining_to_send +sample_rate +) + +bytes_remaining_to_send +- += +len +( +to_send +) + +response +. +writer +. +write +( +to_send +) + +time +. +sleep +( +0 +. +5 +) diff --git a/testing/web-platform/tests/fetch/range/resources/partial-script.py b/testing/web-platform/tests/fetch/range/resources/partial-script.py new file mode 100644 index 0000000000000..86e62894dcd1a --- /dev/null +++ b/testing/web-platform/tests/fetch/range/resources/partial-script.py @@ -0,0 +1,240 @@ +" +" +" +This +generates +a +partial +response +containing +valid +JavaScript +. +" +" +" +def +main +( +request +response +) +: + +require_range += +request +. +GET +. +first +( +' +require +- +range +' +' +' +) + +pretend_offset += +int +( +request +. +GET +. +first +( +' +pretend +- +offset +' +' +0 +' +) +) + +range_header += +request +. +headers +. +get +( +' +Range +' +' +' +) + +if +require_range +and +not +range_header +: + +response +. +set_error +( +412 +" +Range +header +required +" +) + +response +. +write +( +) + +return + +response +. +headers +. +set +( +" +Content +- +Type +" +" +text +/ +plain +" +) + +response +. +headers +. +set +( +" +Accept +- +Ranges +" +" +bytes +" +) + +response +. +headers +. +set +( +" +Cache +- +Control +" +" +no +- +cache +" +) + +response +. +status += +206 + +to_send += +' +self +. +scriptExecuted += +true +; +' + +length += +len +( +to_send +) + +content_range += +" +bytes +{ +} +- +{ +} +/ +{ +} +" +. +format +( + +pretend_offset +pretend_offset ++ +length +- +1 +pretend_offset ++ +length +) + +response +. +headers +. +set +( +" +Content +- +Range +" +content_range +) + +response +. +headers +. +set +( +" +Content +- +Length +" +length +) + +response +. +content += +to_send diff --git a/testing/web-platform/tests/fetch/range/resources/range-sw.js b/testing/web-platform/tests/fetch/range/resources/range-sw.js new file mode 100644 index 0000000000000..d3f7bbf0958e4 --- /dev/null +++ b/testing/web-platform/tests/fetch/range/resources/range-sw.js @@ -0,0 +1,1109 @@ +importScripts +( +' +/ +resources +/ +testharness +. +js +' +) +; +setup +( +{ +explicit_done +: +true +} +) +; +function +assert_range_request +( +request +expectedRangeHeader +name +) +{ +assert_equals +( +request +. +headers +. +get +( +' +Range +' +) +expectedRangeHeader +name +) +; +} +async +function +broadcast +( +msg +) +{ +for +( +const +client +of +await +clients +. +matchAll +( +) +) +{ +client +. +postMessage +( +msg +) +; +} +} +addEventListener +( +' +fetch +' +event += +> +{ +const +request += +event +. +request +; +const +url += +new +URL +( +request +. +url +) +; +const +action += +url +. +searchParams +. +get +( +' +action +' +) +; +switch +( +action +) +{ +case +' +range +- +header +- +filter +- +test +' +: +rangeHeaderFilterTest +( +request +) +; +return +; +case +' +range +- +header +- +passthrough +- +test +' +: +rangeHeaderPassthroughTest +( +event +) +; +return +; +case +' +store +- +ranged +- +response +' +: +storeRangedResponse +( +event +) +; +return +; +case +' +use +- +stored +- +ranged +- +response +' +: +useStoredRangeResponse +( +event +) +; +return +; +} +} +) +; +function +rangeHeaderFilterTest +( +request +) +{ +const +rangeValue += +request +. +headers +. +get +( +' +Range +' +) +; +test +( +( +) += +> +{ +assert_range_request +( +new +Request +( +request +) +rangeValue +Untampered +) +; +assert_range_request +( +new +Request +( +request +{ +} +) +rangeValue +Untampered +( +no +init +props +set +) +) +; +assert_range_request +( +new +Request +( +request +{ +__foo +: +' +bar +' +} +) +rangeValue +Untampered +( +only +invalid +props +set +) +) +; +assert_range_request +( +new +Request +( +request +{ +mode +: +' +cors +' +} +) +rangeValue +More +permissive +mode +) +; +assert_range_request +( +request +. +clone +( +) +rangeValue +Clone +) +; +} +" +Range +headers +correctly +preserved +" +) +; +test +( +( +) += +> +{ +assert_range_request +( +new +Request +( +request +{ +headers +: +{ +Range +: +' +foo +' +} +} +) +null +Tampered +- +range +header +set +) +; +assert_range_request +( +new +Request +( +request +{ +headers +: +{ +} +} +) +null +Tampered +- +empty +headers +set +) +; +assert_range_request +( +new +Request +( +request +{ +mode +: +' +no +- +cors +' +} +) +null +Tampered +mode +set +) +; +assert_range_request +( +new +Request +( +request +{ +cache +: +' +no +- +cache +' +} +) +null +Tampered +cache +mode +set +) +; +} +" +Range +headers +correctly +removed +" +) +; +test +( +( +) += +> +{ +let +headers +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +delete +( +' +does +- +not +- +exist +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +rangeValue +Preserved +if +no +header +actually +removed +) +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +append +( +' +foo +' +' +bar +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +rangeValue +Preserved +if +silent +- +failure +on +append +( +due +to +request +- +no +- +cors +guard +) +) +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +set +( +' +foo +' +' +bar +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +rangeValue +Preserved +if +silent +- +failure +on +set +( +due +to +request +- +no +- +cors +guard +) +) +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +append +( +' +Range +' +' +foo +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +rangeValue +Preserved +if +silent +- +failure +on +append +( +due +to +request +- +no +- +cors +guard +) +) +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +set +( +' +Range +' +' +foo +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +rangeValue +Preserved +if +silent +- +failure +on +set +( +due +to +request +- +no +- +cors +guard +) +) +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +append +( +' +Accept +' +' +whatever +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +null +Stripped +if +header +successfully +appended +) +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +set +( +' +Accept +' +' +whatever +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +null +Stripped +if +header +successfully +set +) +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +delete +( +' +Accept +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +null +Stripped +if +header +successfully +deleted +) +; +headers += +new +Request +( +request +) +. +headers +; +headers +. +delete +( +' +Range +' +) +; +assert_equals +( +headers +. +get +( +' +Range +' +) +null +Stripped +if +range +header +successfully +deleted +) +; +} +" +Headers +correctly +filtered +" +) +; +done +( +) +; +} +function +rangeHeaderPassthroughTest +( +event +) +{ +const +request += +event +. +request +; +const +url += +new +URL +( +request +. +url +) +; +const +key += +url +. +searchParams +. +get +( +' +range +- +received +- +key +' +) +; +event +. +waitUntil +( +new +Promise +( +resolve += +> +{ +promise_test +( +async +( +) += +> +{ +await +fetch +( +event +. +request +) +; +const +response += +await +fetch +( +' +stash +- +take +. +py +? +key += +' ++ +key +) +; +assert_equals +( +await +response +. +json +( +) +' +" +range +- +header +- +received +" +' +) +; +resolve +( +) +; +} +Include +range +header +in +network +request +) +; +done +( +) +; +} +) +) +; +event +. +respondWith +( +new +Response +( +' +' +) +) +; +} +let +storedRangeResponseP +; +function +storeRangedResponse +( +event +) +{ +const +request += +event +. +request +; +const +id += +new +URL +( +request +. +url +) +. +searchParams +. +get +( +' +id +' +) +; +storedRangeResponseP += +fetch +( +event +. +request +) +; +broadcast +( +{ +id +} +) +; +event +. +respondWith +( +new +Response +( +' +' +) +) +; +} +function +useStoredRangeResponse +( +event +) +{ +event +. +respondWith +( +async +function +( +) +{ +const +response += +await +storedRangeResponseP +; +if +( +! +response +) +throw +Error +( +" +Expected +stored +range +response +" +) +; +return +response +. +clone +( +) +; +} +( +) +) +; +} diff --git a/testing/web-platform/tests/fetch/range/resources/stash-take.py b/testing/web-platform/tests/fetch/range/resources/stash-take.py new file mode 100644 index 0000000000000..a852155eb2344 --- /dev/null +++ b/testing/web-platform/tests/fetch/range/resources/stash-take.py @@ -0,0 +1,46 @@ +from +wptserve +. +handlers +import +json_handler +json_handler +def +main +( +request +response +) +: + +key += +request +. +GET +. +first +( +" +key +" +) + +return +request +. +server +. +stash +. +take +( +key +' +/ +fetch +/ +range +/ +' +) diff --git a/testing/web-platform/tests/fetch/range/resources/utils.js b/testing/web-platform/tests/fetch/range/resources/utils.js new file mode 100644 index 0000000000000..f5523b89d7e1f --- /dev/null +++ b/testing/web-platform/tests/fetch/range/resources/utils.js @@ -0,0 +1,87 @@ +function +loadScript +( +url +{ +doc += +document +} += +{ +} +) +{ +return +new +Promise +( +( +resolve +reject +) += +> +{ +const +script += +doc +. +createElement +( +' +script +' +) +; +script +. +onload += +( +) += +> +resolve +( +) +; +script +. +onerror += +( +) += +> +reject +( +Error +( +" +Script +load +failed +" +) +) +; +script +. +src += +url +; +doc +. +body +. +appendChild +( +script +) +; +} +) +} diff --git a/testing/web-platform/tests/fetch/range/sw.https.window.js b/testing/web-platform/tests/fetch/range/sw.https.window.js new file mode 100644 index 0000000000000..a936f953ad1ce --- /dev/null +++ b/testing/web-platform/tests/fetch/range/sw.https.window.js @@ -0,0 +1,909 @@ +const +{ +REMOTE_HOST +} += +get_host_info +( +) +; +const +SCOPE += +' +resources +/ +basic +. +html +' ++ +Math +. +random +( +) +; +function +appendAudio +( +document +url +) +{ +const +audio += +document +. +createElement +( +' +audio +' +) +; +audio +. +muted += +true +; +audio +. +src += +url +; +audio +. +preload += +true +; +document +. +body +. +appendChild +( +audio +) +; +} +async +function +cleanup +( +) +{ +for +( +const +iframe +of +document +. +querySelectorAll +( +' +. +test +- +iframe +' +) +) +{ +iframe +. +parentNode +. +removeChild +( +iframe +) +; +} +const +reg += +await +navigator +. +serviceWorker +. +getRegistration +( +SCOPE +) +; +if +( +reg +) +await +reg +. +unregister +( +) +; +} +async +function +setupRegistration +( +t +) +{ +await +cleanup +( +) +; +const +reg += +await +navigator +. +serviceWorker +. +register +( +' +resources +/ +range +- +sw +. +js +' +{ +scope +: +SCOPE +} +) +; +await +wait_for_state +( +t +reg +. +installing +' +activated +' +) +; +return +reg +; +} +function +awaitMessage +( +obj +id +) +{ +return +new +Promise +( +resolve += +> +{ +obj +. +addEventListener +( +' +message +' +function +listener +( +event +) +{ +if +( +event +. +data +. +id +! += += +id +) +return +; +obj +. +removeEventListener +( +' +message +' +listener +) +; +resolve +( +) +; +} +) +; +} +) +; +} +promise_test +( +async +t += +> +{ +const +reg += +await +setupRegistration +( +t +) +; +const +iframe += +await +with_iframe +( +SCOPE +) +; +const +w += +iframe +. +contentWindow +; +const +url += +new +URL +( +' +long +- +wav +. +py +? +action += +range +- +header +- +filter +- +test +' +w +. +location +) +; +url +. +hostname += +REMOTE_HOST +; +appendAudio +( +w +. +document +url +) +; +await +fetch_tests_from_worker +( +reg +. +active +) +; +} +Defer +range +header +filter +tests +to +service +worker +) +; +promise_test +( +async +t += +> +{ +const +reg += +await +setupRegistration +( +t +) +; +const +iframe += +await +with_iframe +( +SCOPE +) +; +const +w += +iframe +. +contentWindow +; +const +url += +new +URL +( +' +long +- +wav +. +py +' +w +. +location +) +; +url +. +searchParams +. +set +( +' +action +' +' +range +- +header +- +passthrough +- +test +' +) +; +url +. +searchParams +. +set +( +' +range +- +received +- +key +' +token +( +) +) +; +url +. +hostname += +REMOTE_HOST +; +appendAudio +( +w +. +document +url +) +; +await +fetch_tests_from_worker +( +reg +. +active +) +; +} +Defer +range +header +passthrough +tests +to +service +worker +) +; +promise_test +( +async +t += +> +{ +await +setupRegistration +( +t +) +; +const +iframe += +await +with_iframe +( +SCOPE +) +; +const +w += +iframe +. +contentWindow +; +const +id += +Math +. +random +( +) ++ +' +' +; +const +storedRangeResponse += +awaitMessage +( +w +. +navigator +. +serviceWorker +id +) +; +const +url += +new +URL +( +' +partial +- +script +. +py +' +w +. +location +) +; +url +. +searchParams +. +set +( +' +require +- +range +' +' +1 +' +) +; +url +. +searchParams +. +set +( +' +action +' +' +store +- +ranged +- +response +' +) +; +url +. +searchParams +. +set +( +' +id +' +id +) +; +url +. +hostname += +REMOTE_HOST +; +appendAudio +( +w +. +document +url +) +; +await +storedRangeResponse +; +const +fetchPromise += +w +. +fetch +( +' +? +action += +use +- +stored +- +ranged +- +response +' +{ +mode +: +' +no +- +cors +' +} +) +; +promise_rejects +( +t +new +TypeError +( +) +fetchPromise +) +; +const +loadScriptPromise += +loadScript +( +' +? +action += +use +- +stored +- +ranged +- +response +' +{ +doc +: +w +. +document +} +) +; +promise_rejects +( +t +new +Error +( +) +loadScriptPromise +) +; +await +loadScriptPromise +. +catch +( +( +) += +> +{ +} +) +; +assert_false +( +! +! +w +. +scriptExecuted +Partial +response +shouldn +' +t +be +executed +) +; +} +Ranged +response +not +allowed +following +no +- +cors +ranged +request +) +; +promise_test +( +async +t += +> +{ +await +setupRegistration +( +t +) +; +const +iframe += +await +with_iframe +( +SCOPE +) +; +const +w += +iframe +. +contentWindow +; +const +id += +Math +. +random +( +) ++ +' +' +; +const +storedRangeResponse += +awaitMessage +( +w +. +navigator +. +serviceWorker +id +) +; +const +url += +new +URL +( +' +partial +- +script +. +py +' +w +. +location +) +; +url +. +searchParams +. +set +( +' +require +- +range +' +' +1 +' +) +; +url +. +searchParams +. +set +( +' +action +' +' +store +- +ranged +- +response +' +) +; +url +. +searchParams +. +set +( +' +id +' +id +) +; +appendAudio +( +w +. +document +url +) +; +await +storedRangeResponse +; +await +w +. +fetch +( +' +? +action += +use +- +stored +- +ranged +- +response +' +) +; +await +loadScript +( +' +? +action += +use +- +stored +- +ranged +- +response +' +{ +doc +: +w +. +document +} +) +; +assert_true +( +w +. +scriptExecuted +Partial +response +should +be +executed +) +; +} +Non +- +opaque +ranged +response +executed +) +;