Bug 1443942 - Switch over to midflight redirect for all redirect media tests. r?jya draft
authorChris Pearce <cpearce@mozilla.com>
Thu, 29 Mar 2018 18:16:33 +1300
changeset 779066 c42be58b13ce831b78dea312bf4b2c21979313cf
parent 779059 98de0bf9ad6b02daffb7890cb2e64145a16d388a
child 779067 cb197e12965744ebb02db97f7380f42a764a4e93
push id105647
push userbmo:cpearce@mozilla.com
push dateSun, 08 Apr 2018 23:13:55 +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();