midflight-redirect.sjs (2841B)
1 function parseQuery(query, key) { 2 for (let p of query.split("&")) { 3 if (p == key) { 4 return true; 5 } 6 if (p.startsWith(key + "=")) { 7 return p.substring(key.length + 1); 8 } 9 } 10 return false; 11 } 12 13 // Return the first few bytes in a short byte range response. When Firefox 14 // requests subsequent bytes in a second range request, respond with a 15 // redirect. Requests after the first redirected are serviced as expected. 16 function handleRequest(request, response) { 17 var query = request.queryString; 18 var resource = parseQuery(query, "resource"); 19 var type = parseQuery(query, "type") || "application/octet-stream"; 20 var redirected = parseQuery(query, "redirected") || false; 21 var useCors = parseQuery(query, "cors") || false; 22 23 var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); 24 var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( 25 Ci.nsIFileInputStream 26 ); 27 var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( 28 Ci.nsIBinaryInputStream 29 ); 30 var paths = "tests/dom/media/test/" + resource; 31 var split = paths.split("/"); 32 for (var i = 0; i < split.length; ++i) { 33 file.append(split[i]); 34 } 35 fis.init(file, -1, -1, false); 36 37 bis.setInputStream(fis); 38 var bytes = bis.readBytes(bis.available()); 39 let [from, to] = request 40 .getHeader("range") 41 .split("=")[1] 42 .split("-") 43 .map(s => parseInt(s)); 44 45 if (!redirected && from > 0) { 46 var origin = 47 request.host == "mochi.test" ? "example.org" : "mochi.test:8888"; 48 response.setStatusLine(request.httpVersion, 303, "See Other"); 49 let url = 50 "http://" + 51 origin + 52 "/tests/dom/media/test/midflight-redirect.sjs?redirected&" + 53 query; 54 response.setHeader("Location", url); 55 response.setHeader("Content-Type", "text/html"); 56 return; 57 } 58 59 if (isNaN(to)) { 60 to = bytes.length - 1; 61 } 62 63 if (from == 0 && !redirected) { 64 to = 65 parseInt(parseQuery(query, "redirectAt")) || Math.floor(bytes.length / 4); 66 } 67 to = Math.min(to, bytes.length - 1); 68 69 // Note: 'to' is the first index *excluded*, so we need (to + 1) 70 // in the substring end here. 71 let byterange = bytes.substring(from, to + 1); 72 73 let contentRange = "bytes " + from + "-" + to + "/" + bytes.length; 74 let contentLength = byterange.length.toString(); 75 76 response.setStatusLine(request.httpVersion, 206, "Partial Content"); 77 response.setHeader("Content-Range", contentRange); 78 response.setHeader("Content-Length", contentLength, false); 79 response.setHeader("Content-Type", type, false); 80 response.setHeader("Accept-Ranges", "bytes", false); 81 response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); 82 if (redirected && useCors) { 83 response.setHeader("Access-Control-Allow-Origin", "*"); 84 } 85 response.write(byterange, byterange.length); 86 bis.close(); 87 }