test_progress.js (3944B)
1 "use strict"; 2 3 const { HttpServer } = ChromeUtils.importESModule( 4 "resource://testing-common/httpd.sys.mjs" 5 ); 6 7 ChromeUtils.defineLazyGetter(this, "URL", function () { 8 return "http://localhost:" + httpserver.identity.primaryPort; 9 }); 10 11 var httpserver = new HttpServer(); 12 var testpath = "/simple"; 13 var httpbody = "0123456789"; 14 15 var last = 0, 16 max = 0; 17 18 const STATUS_RECEIVING_FROM = 0x4b0006; 19 const LOOPS = 50000; 20 21 const TYPE_ONSTATUS = 1; 22 const TYPE_ONPROGRESS = 2; 23 const TYPE_ONSTARTREQUEST = 3; 24 const TYPE_ONDATAAVAILABLE = 4; 25 const TYPE_ONSTOPREQUEST = 5; 26 27 var ProgressCallback = function () {}; 28 29 ProgressCallback.prototype = { 30 _listener: null, 31 _got_onstartrequest: false, 32 _got_onstatus_after_onstartrequest: false, 33 _last_callback_handled: null, 34 statusArg: "", 35 finish: null, 36 37 QueryInterface: ChromeUtils.generateQI([ 38 "nsIProgressEventSink", 39 "nsIStreamListener", 40 "nsIRequestObserver", 41 ]), 42 43 getInterface(iid) { 44 if ( 45 iid.equals(Ci.nsIProgressEventSink) || 46 iid.equals(Ci.nsIStreamListener) || 47 iid.equals(Ci.nsIRequestObserver) 48 ) { 49 return this; 50 } 51 throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE); 52 }, 53 54 onStartRequest(request) { 55 Assert.equal(this._last_callback_handled, TYPE_ONSTATUS); 56 this._got_onstartrequest = true; 57 this._last_callback_handled = TYPE_ONSTARTREQUEST; 58 59 this._listener = new ChannelListener(checkRequest, request); 60 this._listener.onStartRequest(request); 61 }, 62 63 onDataAvailable(request, data, offset, count) { 64 Assert.equal(this._last_callback_handled, TYPE_ONPROGRESS); 65 this._last_callback_handled = TYPE_ONDATAAVAILABLE; 66 67 this._listener.onDataAvailable(request, data, offset, count); 68 }, 69 70 onStopRequest(request, status) { 71 Assert.equal(this._last_callback_handled, TYPE_ONDATAAVAILABLE); 72 Assert.ok(this._got_onstatus_after_onstartrequest); 73 this._last_callback_handled = TYPE_ONSTOPREQUEST; 74 75 this._listener.onStopRequest(request, status); 76 delete this._listener; 77 this.finish(); 78 }, 79 80 onProgress(request, progress, progressMax) { 81 Assert.equal(this._last_callback_handled, TYPE_ONSTATUS); 82 this._last_callback_handled = TYPE_ONPROGRESS; 83 84 Assert.equal(this.mStatus, STATUS_RECEIVING_FROM); 85 last = progress; 86 max = progressMax; 87 }, 88 89 onStatus(request, status, statusArg) { 90 if (!this._got_onstartrequest) { 91 // Ensure that all messages before onStartRequest are onStatus 92 if (this._last_callback_handled) { 93 Assert.equal(this._last_callback_handled, TYPE_ONSTATUS); 94 } 95 } else if (this._last_callback_handled == TYPE_ONSTARTREQUEST) { 96 this._got_onstatus_after_onstartrequest = true; 97 } else { 98 Assert.equal(this._last_callback_handled, TYPE_ONDATAAVAILABLE); 99 } 100 this._last_callback_handled = TYPE_ONSTATUS; 101 102 Assert.equal(statusArg, this.statusArg); 103 this.mStatus = status; 104 }, 105 106 mStatus: 0, 107 }; 108 109 registerCleanupFunction(async () => { 110 await httpserver.stop(); 111 }); 112 113 function chanPromise(uri, statusArg) { 114 return new Promise(resolve => { 115 var chan = NetUtil.newChannel({ 116 uri, 117 loadUsingSystemPrincipal: true, 118 }); 119 chan.QueryInterface(Ci.nsIHttpChannel); 120 chan.requestMethod = "GET"; 121 let listener = new ProgressCallback(); 122 listener.statusArg = statusArg; 123 chan.notificationCallbacks = listener; 124 listener.finish = resolve; 125 chan.asyncOpen(listener); 126 }); 127 } 128 129 add_task(async function test_http1_1() { 130 httpserver.registerPathHandler(testpath, serverHandler); 131 httpserver.start(-1); 132 await chanPromise(URL + testpath, "localhost"); 133 }); 134 135 function serverHandler(metadata, response) { 136 response.setHeader("Content-Type", "text/plain", false); 137 for (let i = 0; i < LOOPS; i++) { 138 response.bodyOutputStream.write(httpbody, httpbody.length); 139 } 140 } 141 142 function checkRequest() { 143 Assert.equal(last, httpbody.length * LOOPS); 144 Assert.equal(max, httpbody.length * LOOPS); 145 }