Bug 1443942 - Switch over to midflight redirect for all redirect media tests. r=jya
authorChris Pearce <cpearce@mozilla.com>
Thu, 29 Mar 2018 18:16:33 +1300
changeset 779715 e02b7f9e296d7f2373d4e77ab2f3567975f4aae3
parent 779714 482dbcc619ce83241380b6e9376b9f9d1014b433
child 779716 79bd527dd8c86844f14a0c2306223f948f5cfcc0
push id105836
push userbmo:ato@sny.no
push dateTue, 10 Apr 2018 12:07:22 +0000
reviewersjya
bugs1443942
milestone61.0a1
Bug 1443942 - Switch over to midflight redirect for all redirect media tests. r=jya We have two SJS files; midflight-redirect.sjs and dynamic_redirect.sjs, which are very similar, but dynamic_redirect.sjs is buggy, so we should just use midflight-redirect.sjs. dynamic_redirect.sjs is buggy because it relies on the client doing multiple HTTP requests to it in order to redirect, but we can't actually guarantee this. Previously users of it would try things like setting a small MediaCache size, or only using Ogg for which we expect a seek to the end to calculate the duration, but I have observed the entire resource being downloaded in one hit before the media element has finished loading metadata, meaning the seek (in the Ogg case) can happen without another HTTP request. This is even with a small MediaCache. midfligh-redirect.sjs solves this problem by explicitly only returning a partial response, so the client is forced to make another HTTP request, which we will serve a redirect to. MozReview-Commit-ID: 39imyayhnBG
dom/media/test/dynamic_redirect.sjs
dom/media/test/mochitest.ini
dom/media/test/test_mediarecorder_principals.html
dom/media/test/test_mixed_principals.html
deleted file mode 100644
--- a/dom/media/test/dynamic_redirect.sjs
+++ /dev/null
@@ -1,69 +0,0 @@
-function parseQuery(query, key) {
-  for (let p of query.split('&')) {
-    if (p == key) {
-      return true;
-    }
-    if (p.startsWith(key + "=")) {
-      return p.substring(key.length + 1);
-    }
-  }
-}
-
-// Return seek.ogv file content for the first request with a given key.
-// All subsequent requests return a redirect to a different-origin resource.
-function handleRequest(request, response)
-{
-  var query = request.queryString;
-  var key = parseQuery(query, "key");
-  var type = parseQuery(query, "type") || "application/octet-stream";
-  var resource = parseQuery(query, "res");
-  var nested = parseQuery(query, "nested") || false;
-
-  dump("Received request for key = "+ key +"\n");
-  if (!nested) {
-    if (getState(key) == "redirect") {
-      var origin = request.host == "mochi.test" ? "example.org" : "mochi.test:8888";
-      response.setStatusLine(request.httpVersion, 303, "See Other");
-      let url = "http://" + origin +
-                "/tests/dom/media/test/dynamic_redirect.sjs?nested&" + query;
-      dump("Redirecting to "+ url + "\n");
-      response.setHeader("Location", url);
-      response.setHeader("Content-Type", "text/html");
-      return;
-    }
-    setState(key, "redirect");
-  }
-  var file = Components.classes["@mozilla.org/file/directory_service;1"].
-                        getService(Components.interfaces.nsIProperties).
-                        get("CurWorkD", Components.interfaces.nsIFile);
-  var fis  = Components.classes['@mozilla.org/network/file-input-stream;1'].
-                        createInstance(Components.interfaces.nsIFileInputStream);
-  var bis  = Components.classes["@mozilla.org/binaryinputstream;1"].
-                        createInstance(Components.interfaces.nsIBinaryInputStream);
-  var paths = "tests/dom/media/test/" + resource;
-  var split = paths.split("/");
-  for (var i = 0; i < split.length; ++i) {
-    file.append(split[i]);
-  }
-  fis.init(file, -1, -1, false);
-
-  bis.setInputStream(fis);
-  var bytes = bis.readBytes(bis.available());
-  let [from, to] = request.getHeader("range").split("=")[1].split("-").map(s => parseInt(s));
-  to = to || Math.max(from, bytes.length - 1);
-  byterange = bytes.substring(from, to + 1);
-
-  let contentRange = "bytes "+ from +"-"+ to +"/"+ bytes.length;
-  let contentLength = (to - from + 1).toString();
-  dump("Response Content-Range = "+ contentRange +"\n");
-  dump("Response Content-Length = "+ contentLength +"\n");
-
-  response.setStatusLine(request.httpVersion, 206, "Partial Content");
-  response.setHeader("Content-Range", contentRange);
-  response.setHeader("Content-Length", contentLength, false);
-  response.setHeader("Content-Type", type, false);
-  response.setHeader("Accept-Ranges", "bytes", false);
-  response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
-  response.write(byterange, byterange.length);
-  bis.close();
-}
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -429,17 +429,16 @@ support-files =
   detodos-short.webm
   detodos-short.webm^headers^
   detodos-recorder-test.opus
   detodos-recorder-test.opus^headers^
   detodos-short.opus
   detodos-short.opus^headers^
   dirac.ogg
   dirac.ogg^headers^
-  dynamic_redirect.sjs
   dynamic_resource.sjs
   eme.js
   file_access_controls.html
   file_autoplay_policy_unmute_pauses.html
   file_autoplay_policy_activation_window.html
   file_autoplay_policy_activation_frame.html
   flac-s24.flac
   flac-s24.flac^headers^
--- a/dom/media/test/test_mediarecorder_principals.html
+++ b/dom/media/test/test_mediarecorder_principals.html
@@ -41,18 +41,18 @@ function testPrincipals(resource) {
   if (!resource) {
     todo(false, "No types supported");
     return;
   }
   // First test: Load file from same-origin first, then get redirected to
   // another origin before attempting to record stream.
   let video = document.getElementById("v1");
   video.src =
-      "http://mochi.test:8888/tests/dom/media/test/dynamic_redirect.sjs?key=v1_" +
-      key + "&res=" + resource.name + "&type=" + resource.type;
+      "http://mochi.test:8888/tests/dom/media/test/midflight-redirect.sjs?key=v1_" +
+      key + "&resource=" + resource.name + "&type=" + resource.type;
   return new Promise(resolve => video.onloadedmetadata = resolve).then(() => {
     video.load();
     video.play();
     interval = setInterval(() => info("video.currentTime = "+ video.currentTime), 1000);
 
     let msg = "mediaRecorder.start() must throw SecurityError";
     return new Promise(resolve => video.onplaying = resolve)
     .then(() => waitUntil(() => video.currentTime > resource.duration / 5))
@@ -62,18 +62,18 @@ function testPrincipals(resource) {
       .then(() => ok(false, msg), e => is(e.name, "SecurityError", msg)), 0)
     .then(() => clearInterval(interval));
   })
   .then(() => {
     // Second test: Load file from same-origin first, but record ASAP, before
     // getting redirected to another origin.
     let video = document.getElementById("v2");
     video.src =
-        "http://mochi.test:8888/tests/dom/media/test/dynamic_redirect.sjs?key=v2_" +
-        key + "&res=" + resource.name + "&type=" + resource.type;
+        "http://mochi.test:8888/tests/dom/media/test/midflight-redirect.sjs?key=v2_" +
+        key + "&resource=" + resource.name + "&type=" + resource.type;
     let rec, hasStopped, hasEnded = new Promise(r => video.onended = r);
     let data = [];
 
     let msgNoThrow = "mediaRecorder.start() should not throw here";
     let msgSecErr = "mediaRecorder.onerror must fire SecurityError";
     let msgOnStop = "mediaRecorder.onstop must also have fired";
     return new Promise(resolve => video.onloadedmetadata = resolve).then(() => {
       rec = new MediaRecorder(video.mozCaptureStreamUntilEnded());
--- a/dom/media/test/test_mixed_principals.html
+++ b/dom/media/test/test_mixed_principals.html
@@ -42,18 +42,18 @@ https://bugzilla.mozilla.org/show_bug.cg
     function runTest(origin, shouldReadBackOnLoad) {
       return new Promise(function (resolve, reject) {
         // Load will redirect mid-flight, which will be detected and should error,
         // and we should no longer be able to readback.
         var noise = Math.floor(Math.random() * 100000000);
         var video = document.createElement("video");
         video.preload = "metadata";
         video.controls = true;
-        var url = "http://" + origin + "/tests/dom/media/test/dynamic_redirect.sjs?key="
-                  + noise + "&res=pixel_aspect_ratio.mp4"
+        var url = "http://" + origin + "/tests/dom/media/test/midflight-redirect.sjs?key="
+                  + noise + "&resource=pixel_aspect_ratio.mp4"
                   + "&type=video/mp4";
         SimpleTest.info("Loading from " + url);
         video.src = url;
         document.body.appendChild(video);
 
         once(video, "loadeddata", () => {
           is(canReadBack(video), shouldReadBackOnLoad, "Should be able to readback");
           video.play();