summaryrefslogtreecommitdiffstats
path: root/dom/media/test/cancellable_request.sjs
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/test/cancellable_request.sjs')
-rw-r--r--dom/media/test/cancellable_request.sjs162
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;
+ });
+}