test_resumable_truncate.js (2593B)
1 "use strict"; 2 3 const { HttpServer } = ChromeUtils.importESModule( 4 "resource://testing-common/httpd.sys.mjs" 5 ); 6 7 var httpserver = null; 8 9 function make_channel(url) { 10 return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true }); 11 } 12 13 const responseBody = "response body"; 14 15 function cachedHandler(metadata, response) { 16 var body = responseBody; 17 if (metadata.hasHeader("Range")) { 18 var matches = metadata 19 .getHeader("Range") 20 .match(/^\s*bytes=(\d+)?-(\d+)?\s*$/); 21 var from = matches[1] === undefined ? 0 : matches[1]; 22 var to = matches[2] === undefined ? responseBody.length - 1 : matches[2]; 23 if (from >= responseBody.length) { 24 response.setStatusLine(metadata.httpVersion, 416, "Start pos too high"); 25 response.setHeader("Content-Range", "*/" + responseBody.length, false); 26 return; 27 } 28 body = responseBody.slice(from, to + 1); 29 // always respond to successful range requests with 206 30 response.setStatusLine(metadata.httpVersion, 206, "Partial Content"); 31 response.setHeader( 32 "Content-Range", 33 from + "-" + to + "/" + responseBody.length, 34 false 35 ); 36 } 37 38 response.setHeader("Content-Type", "text/plain", false); 39 response.setHeader("ETag", "Just testing"); 40 response.setHeader("Accept-Ranges", "bytes"); 41 42 response.bodyOutputStream.write(body, body.length); 43 } 44 45 function Canceler(continueFn) { 46 this.continueFn = continueFn; 47 } 48 49 Canceler.prototype = { 50 QueryInterface: ChromeUtils.generateQI([ 51 "nsIStreamListener", 52 "nsIRequestObserver", 53 ]), 54 55 onStartRequest() {}, 56 57 onDataAvailable(request) { 58 request.QueryInterface(Ci.nsIChannel).cancel(Cr.NS_BINDING_ABORTED); 59 }, 60 61 onStopRequest(request, status) { 62 Assert.equal(status, Cr.NS_BINDING_ABORTED); 63 this.continueFn(); 64 }, 65 }; 66 67 function finish_test() { 68 httpserver.stop(do_test_finished); 69 } 70 71 function start_cache_read() { 72 var chan = make_channel( 73 "http://localhost:" + httpserver.identity.primaryPort + "/cached/test.gz" 74 ); 75 chan.asyncOpen(new ChannelListener(finish_test, null)); 76 } 77 78 function start_canceler() { 79 var chan = make_channel( 80 "http://localhost:" + httpserver.identity.primaryPort + "/cached/test.gz" 81 ); 82 chan.asyncOpen(new Canceler(start_cache_read)); 83 } 84 85 function run_test() { 86 httpserver = new HttpServer(); 87 httpserver.registerPathHandler("/cached/test.gz", cachedHandler); 88 httpserver.start(-1); 89 90 var chan = make_channel( 91 "http://localhost:" + httpserver.identity.primaryPort + "/cached/test.gz" 92 ); 93 chan.asyncOpen(new ChannelListener(start_canceler, null)); 94 do_test_pending(); 95 }