test_bug1312774_http1.js (3977B)
1 // test bug 1312774. 2 // Create 6 (=network.http.max-persistent-connections-per-server) 3 // common Http requests and 2 urgent-start Http requests to a single 4 // host and path, in parallel. 5 // Let all the requests unanswered by the server handler. (process them 6 // async and don't finish) 7 // The first 6 pending common requests will fill the limit for per-server 8 // parallelism. 9 // But the two urgent requests must reach the server despite those 6 common 10 // pending requests. 11 // The server handler doesn't let the test finish until all 8 expected requests 12 // arrive. 13 // Note: if the urgent request handling is broken (the urgent-marked requests 14 // get blocked by queuing) this test will time out 15 16 "use strict"; 17 18 const { HttpServer } = ChromeUtils.importESModule( 19 "resource://testing-common/httpd.sys.mjs" 20 ); 21 var server = new HttpServer(); 22 server.start(-1); 23 var baseURL = "http://localhost:" + server.identity.primaryPort + "/"; 24 var maxConnections = 0; 25 var urgentRequests = 0; 26 var debug = false; 27 28 function log(msg) { 29 if (!debug) { 30 return; 31 } 32 33 if (msg) { 34 dump("TEST INFO | " + msg + "\n"); 35 } 36 } 37 38 function make_channel(url) { 39 var request = NetUtil.newChannel({ 40 uri: url, 41 loadUsingSystemPrincipal: true, 42 }); 43 request.QueryInterface(Ci.nsIHttpChannel); 44 return request; 45 } 46 47 function serverStopListener() { 48 server.stop(); 49 } 50 51 function commonHttpRequest(id) { 52 let uri = baseURL; 53 var chan = make_channel(uri); 54 var listner = new HttpResponseListener(id); 55 chan.setRequestHeader("X-ID", id, false); 56 chan.setRequestHeader("Cache-control", "no-store", false); 57 chan.asyncOpen(listner); 58 log("Create common http request id=" + id); 59 } 60 61 function urgentStartHttpRequest(id) { 62 let uri = baseURL; 63 var chan = make_channel(uri); 64 var listner = new HttpResponseListener(id); 65 var cos = chan.QueryInterface(Ci.nsIClassOfService); 66 cos.addClassFlags(Ci.nsIClassOfService.UrgentStart); 67 chan.setRequestHeader("X-ID", id, false); 68 chan.setRequestHeader("Cache-control", "no-store", false); 69 chan.asyncOpen(listner); 70 log("Create urgent-start http request id=" + id); 71 } 72 73 function setup_httpRequests() { 74 log("setup_httpRequests"); 75 for (var i = 0; i < maxConnections; i++) { 76 commonHttpRequest(i); 77 do_test_pending(); 78 } 79 } 80 81 function setup_urgentStartRequests() { 82 for (var i = 0; i < urgentRequests; i++) { 83 urgentStartHttpRequest(1000 + i); 84 do_test_pending(); 85 } 86 } 87 88 function HttpResponseListener(id) { 89 this.id = id; 90 } 91 92 HttpResponseListener.prototype = { 93 onStartRequest() {}, 94 95 onDataAvailable() {}, 96 97 onStopRequest() { 98 log("STOP id=" + this.id); 99 do_test_finished(); 100 }, 101 }; 102 103 var responseQueue = []; 104 function setup_http_server() { 105 log("setup_http_server"); 106 maxConnections = Services.prefs.getIntPref( 107 "network.http.max-persistent-connections-per-server" 108 ); 109 urgentRequests = 2; 110 var allCommonHttpRequestReceived = false; 111 // Start server; will be stopped at test cleanup time. 112 server.registerPathHandler("/", function (metadata, response) { 113 var id = metadata.getHeader("X-ID"); 114 log("Server recived the response id=" + id); 115 response.processAsync(); 116 responseQueue.push(response); 117 118 if ( 119 responseQueue.length == maxConnections && 120 !allCommonHttpRequestReceived 121 ) { 122 allCommonHttpRequestReceived = true; 123 setup_urgentStartRequests(); 124 } 125 // Wait for all expected requests to come but don't process then. 126 // Collect them in a queue for later processing. We don't want to 127 // respond to the client until all the expected requests are made 128 // to the server. 129 if (responseQueue.length == maxConnections + urgentRequests) { 130 processResponse(); 131 } 132 }); 133 134 registerCleanupFunction(function () { 135 server.stop(serverStopListener); 136 }); 137 } 138 139 function processResponse() { 140 while (responseQueue.length) { 141 var resposne = responseQueue.pop(); 142 resposne.finish(); 143 } 144 } 145 146 function run_test() { 147 setup_http_server(); 148 setup_httpRequests(); 149 }