Skip to content

Commit

Permalink
Bug 1452562 [wpt PR 10348] - Allow range headers to pass through a se…
Browse files Browse the repository at this point in the history
…rvice worker, a=testonly

Automatic update from web-platform-testsAllow range headers to pass through a service worker (#10348)

Tests for whatwg/fetch#560

--

wpt-commits: fb6d16d92af29262b6137b79e61f0c4b136c6ac1
wpt-pr: 10348

UltraBlame original commit: 8b458f3d30b63afa745527bc31744f4971749224
  • Loading branch information
marco-c committed Oct 3, 2019
1 parent efbc2b8 commit caa8dbf
Show file tree
Hide file tree
Showing 11 changed files with 589 additions and 1 deletion.
90 changes: 89 additions & 1 deletion testing/web-platform/meta/MANIFEST.json
Original file line number Diff line number Diff line change
Expand Up @@ -273616,6 +273616,36 @@
{}
]
],
"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/README.md": [
[
{}
Expand Down Expand Up @@ -330610,6 +330640,28 @@
{}
]
],
"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/fetch.tentative.https.sub.html": [
[
"/fetch/sec-metadata/fetch.tentative.https.sub.html",
Expand Down Expand Up @@ -559765,6 +559817,42 @@
"bb002c0d5d4d46f426462f776cff00cf600f5a4a",
"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/README.md": [
"75d58b35c1e5572d02dd3ad90ac65301e35c4bc7",
"support"
Expand Down Expand Up @@ -603486,7 +603574,7 @@
"support"
],
"service-workers/service-worker/resources/test-helpers.sub.js": [
"74ea529125a5e2c5cd3d350f7c56ae614f82010d",
"079d31394903266dddb067f8f4dba5a94e522bdc",
"support"
],
"service-workers/service-worker/resources/testharness-helpers.js": [
Expand Down
60 changes: 60 additions & 0 deletions testing/web-platform/tests/fetch/range/general.any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

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`);

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@



promise_test(async t => {
await loadScript('resources/partial-script.py?pretend-offset=90000');
assert_true(self.scriptExecuted);
}, `Script executed from partial response`);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!DOCTYPE html>
111 changes: 111 additions & 0 deletions testing/web-platform/tests/fetch/range/resources/long-wav.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"""
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)
30 changes: 30 additions & 0 deletions testing/web-platform/tests/fetch/range/resources/partial-script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""
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
Loading

0 comments on commit caa8dbf

Please sign in to comment.