diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /dom/media/test/cancellable_request.sjs | |
parent | Initial commit. (diff) | |
download | firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/test/cancellable_request.sjs')
-rw-r--r-- | dom/media/test/cancellable_request.sjs | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/dom/media/test/cancellable_request.sjs b/dom/media/test/cancellable_request.sjs new file mode 100644 index 0000000000..ffeb0c7818 --- /dev/null +++ b/dom/media/test/cancellable_request.sjs @@ -0,0 +1,162 @@ +function parseQuery(request, key) { + var params = request.queryString.split("&"); + for (var j = 0; j < params.length; ++j) { + var p = params[j]; + if (p == key) { + return true; + } + if (p.indexOf(key + "=") == 0) { + return p.substring(key.length + 1); + } + if (!p.includes("=") && key == "") { + return p; + } + } + return false; +} + +function push32BE(array, input) { + array.push(String.fromCharCode((input >> 24) & 0xff)); + array.push(String.fromCharCode((input >> 16) & 0xff)); + array.push(String.fromCharCode((input >> 8) & 0xff)); + array.push(String.fromCharCode(input & 0xff)); +} + +function push32LE(array, input) { + array.push(String.fromCharCode(input & 0xff)); + array.push(String.fromCharCode((input >> 8) & 0xff)); + array.push(String.fromCharCode((input >> 16) & 0xff)); + array.push(String.fromCharCode((input >> 24) & 0xff)); +} + +function push16LE(array, input) { + array.push(String.fromCharCode(input & 0xff)); + array.push(String.fromCharCode((input >> 8) & 0xff)); +} + +function buildWave(samples, sample_rate) { + const RIFF_MAGIC = 0x52494646; + const WAVE_MAGIC = 0x57415645; + const FRMT_MAGIC = 0x666d7420; + const DATA_MAGIC = 0x64617461; + const RIFF_SIZE = 44; + + var header = []; + push32BE(header, RIFF_MAGIC); + push32LE(header, RIFF_SIZE + samples.length * 2); + push32BE(header, WAVE_MAGIC); + push32BE(header, FRMT_MAGIC); + push32LE(header, 16); + push16LE(header, 1); + push16LE(header, 1); + push32LE(header, sample_rate); + push32LE(header, sample_rate); + push16LE(header, 2); + push16LE(header, 16); + push32BE(header, DATA_MAGIC); + push32LE(header, samples.length * 2); + for (var i = 0; i < samples.length; ++i) { + push16LE(header, samples[i], 2); + } + return header; +} + +const CC = Components.Constructor; +const Timer = CC("@mozilla.org/timer;1", "nsITimer", "initWithCallback"); +const BinaryOutputStream = CC( + "@mozilla.org/binaryoutputstream;1", + "nsIBinaryOutputStream", + "setOutputStream" +); + +function poll(f) { + if (f()) { + return; + } + new Timer( + function () { + poll(f); + }, + 100, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} + +function handleRequest(request, response) { + var cancel = parseQuery(request, "cancelkey"); + if (cancel) { + setState(cancel[1], "cancelled"); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write("Cancel approved!"); + return; + } + + var samples = []; + for (var i = 0; i < 1000000; ++i) { + samples.push(0); + } + var bytes = buildWave(samples, 44100).join(""); + + var key = parseQuery(request, "key"); + response.setHeader("Content-Type", "audio/x-wav"); + response.setHeader("Content-Length", "" + bytes.length, false); + + var out = new BinaryOutputStream(response.bodyOutputStream); + + var start = 0, + end = bytes.length - 1; + if (request.hasHeader("Range")) { + var rangeMatch = request.getHeader("Range").match(/^bytes=(\d+)?-(\d+)?$/); + + if (rangeMatch[1] !== undefined) { + start = parseInt(rangeMatch[1], 10); + } + + if (rangeMatch[2] !== undefined) { + end = parseInt(rangeMatch[2], 10); + } + + // No start given, so the end is really the count of bytes from the + // end of the file. + if (start === undefined) { + start = Math.max(0, bytes.length - end); + end = bytes.length - 1; + } + + // start and end are inclusive + if (end === undefined || end >= bytes.length) { + end = bytes.length - 1; + } + + if (end < start) { + response.setStatusLine(request.httpVersion, 200, "OK"); + start = 0; + end = bytes.length - 1; + } else { + response.setStatusLine(request.httpVersion, 206, "Partial Content"); + var contentRange = "bytes " + start + "-" + end + "/" + bytes.length; + response.setHeader("Content-Range", contentRange); + } + } + + if (start > 0) { + // Send all requested data + out.write(bytes.slice(start, end + 1), end + 1 - start); + return; + } + + // Write the first 1.2M of the Wave file. We know the cache size is set to + // 100K so this will fill the cache and and cause a "suspend" event on + // the loading element. + out.write(bytes, 1200000); + + response.processAsync(); + // Now wait for the message to cancel this response + poll(function () { + if (getState(key[1]) != "cancelled") { + return false; + } + response.finish(); + return true; + }); +} |