diff options
Diffstat (limited to 'test/wpt/tests/fetch/range/resources/long-wav.py')
-rw-r--r-- | test/wpt/tests/fetch/range/resources/long-wav.py | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/test/wpt/tests/fetch/range/resources/long-wav.py b/test/wpt/tests/fetch/range/resources/long-wav.py new file mode 100644 index 0000000..acfc81a --- /dev/null +++ b/test/wpt/tests/fetch/range/resources/long-wav.py @@ -0,0 +1,134 @@ +""" +This generates a 30 minute silent wav, and is capable of +responding to Range requests. +""" +import time +import re +import struct + +from wptserve.utils import isomorphic_decode + +def create_wav_header(sample_rate, bit_depth, channels, duration): + bytes_per_sample = int(bit_depth / 8) + block_align = bytes_per_sample * channels + byte_rate = sample_rate * block_align + sub_chunk_2_size = duration * byte_rate + + data = b'' + # ChunkID + data += b'RIFF' + # ChunkSize + data += struct.pack('<L', 36 + sub_chunk_2_size) + # Format + data += b'WAVE' + # Subchunk1ID + data += b'fmt ' + # Subchunk1Size + data += struct.pack('<L', 16) + # AudioFormat + data += struct.pack('<H', 1) + # NumChannels + data += struct.pack('<H', channels) + # SampleRate + data += struct.pack('<L', sample_rate) + # ByteRate + data += struct.pack('<L', byte_rate) + # BlockAlign + data += struct.pack('<H', block_align) + # BitsPerSample + data += struct.pack('<H', bit_depth) + # Subchunk2ID + data += b'data' + # Subchunk2Size + data += struct.pack('<L', sub_chunk_2_size) + + return data + + +def main(request, response): + if request.method == u"OPTIONS": + response.status = (404, b"Not Found") + response.headers.set(b"Content-Type", b"text/plain") + return b"Preflight not accepted" + + response.headers.set(b"Content-Type", b"audio/wav") + response.headers.set(b"Accept-Ranges", b"bytes") + response.headers.set(b"Cache-Control", b"no-cache") + response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b'Origin', b'')) + + range_header = request.headers.get(b'Range', b'') + range_header_match = range_header and re.search(r'^bytes=(\d*)-(\d*)$', isomorphic_decode(range_header)) + range_received_key = request.GET.first(b'range-received-key', b'') + accept_encoding_key = request.GET.first(b'accept-encoding-key', b'') + + if range_received_key and range_header: + # Remove any current value + request.server.stash.take(range_received_key, b'/fetch/range/') + # This is later collected using stash-take.py + request.server.stash.put(range_received_key, u'range-header-received', b'/fetch/range/') + + if accept_encoding_key: + # Remove any current value + request.server.stash.take( + accept_encoding_key, + b'/fetch/range/' + ) + # This is later collected using stash-take.py + request.server.stash.put( + accept_encoding_key, + isomorphic_decode(request.headers.get(b'Accept-Encoding', b'')), + b'/fetch/range/' + ) + + # Audio details + sample_rate = 8000 + bit_depth = 8 + channels = 1 + duration = 60 * 5 + + total_length = int((sample_rate * bit_depth * channels * duration) / 8) + bytes_remaining_to_send = total_length + initial_write = b'' + + if range_header_match: + response.status = 206 + start, end = range_header_match.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 = b"bytes %d-%d/%d" % (start, end or total_length - 1, total_length) + + response.headers.set(b"Content-Range", content_range) + else: + initial_write = create_wav_header(sample_rate, bit_depth, channels, duration) + + response.headers.set(b"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: + to_send = b'\x00' * min(bytes_remaining_to_send, sample_rate) + bytes_remaining_to_send -= len(to_send) + + if not response.writer.write(to_send): + break + + # Throttle the stream + time.sleep(0.5) |