test_suspend_channel_on_examine_merged_response.js (5498B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // This file tests async handling of a channel suspended in 6 // notifying http-on-examine-merged-response observers. 7 // Note that this test is developed based on test_bug482601.js. 8 "use strict"; 9 10 const { HttpServer } = ChromeUtils.importESModule( 11 "resource://testing-common/httpd.sys.mjs" 12 ); 13 14 var httpserv = null; 15 var test_nr = 0; 16 var buffer = ""; 17 var observerCalled = false; 18 var channelResumed = false; 19 20 var observer = { 21 QueryInterface: ChromeUtils.generateQI(["nsIObserver"]), 22 23 observe(subject, topic) { 24 if ( 25 topic === "http-on-examine-merged-response" && 26 subject instanceof Ci.nsIHttpChannel 27 ) { 28 var chan = subject.QueryInterface(Ci.nsIHttpChannel); 29 executeSoon(() => { 30 Assert.equal(channelResumed, false); 31 channelResumed = true; 32 chan.resume(); 33 }); 34 Assert.equal(observerCalled, false); 35 observerCalled = true; 36 chan.suspend(); 37 } 38 }, 39 }; 40 41 var listener = { 42 onStartRequest() { 43 buffer = ""; 44 }, 45 46 onDataAvailable(request, stream, offset, count) { 47 buffer = buffer.concat(read_stream(stream, count)); 48 }, 49 50 onStopRequest(request, status) { 51 Assert.equal(status, Cr.NS_OK); 52 Assert.equal(buffer, "0123456789"); 53 Assert.equal(channelResumed, true); 54 Assert.equal(observerCalled, true); 55 test_nr++; 56 do_timeout(0, do_test); 57 }, 58 }; 59 60 function run_test() { 61 httpserv = new HttpServer(); 62 httpserv.registerPathHandler("/path/partial", path_partial); 63 httpserv.registerPathHandler("/path/cached", path_cached); 64 httpserv.start(-1); 65 66 Services.obs.addObserver(observer, "http-on-examine-merged-response"); 67 68 do_timeout(0, do_test); 69 do_test_pending(); 70 } 71 72 function do_test() { 73 if (test_nr < tests.length) { 74 tests[test_nr](); 75 } else { 76 Services.obs.removeObserver(observer, "http-on-examine-merged-response"); 77 httpserv.stop(do_test_finished); 78 } 79 } 80 81 var tests = [test_partial, test_cached]; 82 83 function makeChan(url) { 84 return NetUtil.newChannel({ 85 uri: url, 86 loadUsingSystemPrincipal: true, 87 }).QueryInterface(Ci.nsIHttpChannel); 88 } 89 90 function storeCache(aCacheEntry, aResponseHeads, aContent) { 91 aCacheEntry.setMetaDataElement("request-method", "GET"); 92 aCacheEntry.setMetaDataElement("response-head", aResponseHeads); 93 aCacheEntry.setMetaDataElement("charset", "ISO-8859-1"); 94 95 var oStream = aCacheEntry.openOutputStream(0, aContent.length); 96 var written = oStream.write(aContent, aContent.length); 97 if (written != aContent.length) { 98 do_throw( 99 "oStream.write has not written all data!\n" + 100 " Expected: " + 101 written + 102 "\n" + 103 " Actual: " + 104 aContent.length + 105 "\n" 106 ); 107 } 108 oStream.close(); 109 } 110 111 function test_partial() { 112 observerCalled = false; 113 channelResumed = false; 114 asyncOpenCacheEntry( 115 "http://localhost:" + httpserv.identity.primaryPort + "/path/partial", 116 "disk", 117 Ci.nsICacheStorage.OPEN_NORMALLY, 118 null, 119 test_partial2 120 ); 121 } 122 123 function test_partial2(status, entry) { 124 Assert.equal(status, Cr.NS_OK); 125 storeCache( 126 entry, 127 "HTTP/1.1 200 OK\r\n" + 128 "Date: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + 129 "Server: httpd.js\r\n" + 130 "Last-Modified: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + 131 "Accept-Ranges: bytes\r\n" + 132 "Content-Length: 10\r\n" + 133 "Content-Type: text/plain\r\n", 134 "0123" 135 ); 136 137 observerCalled = false; 138 139 var chan = makeChan( 140 "http://localhost:" + httpserv.identity.primaryPort + "/path/partial" 141 ); 142 chan.asyncOpen(listener); 143 } 144 145 function test_cached() { 146 observerCalled = false; 147 channelResumed = false; 148 asyncOpenCacheEntry( 149 "http://localhost:" + httpserv.identity.primaryPort + "/path/cached", 150 "disk", 151 Ci.nsICacheStorage.OPEN_NORMALLY, 152 null, 153 test_cached2 154 ); 155 } 156 157 function test_cached2(status, entry) { 158 Assert.equal(status, Cr.NS_OK); 159 storeCache( 160 entry, 161 "HTTP/1.1 200 OK\r\n" + 162 "Date: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + 163 "Server: httpd.js\r\n" + 164 "Last-Modified: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + 165 "Accept-Ranges: bytes\r\n" + 166 "Content-Length: 10\r\n" + 167 "Content-Type: text/plain\r\n", 168 "0123456789" 169 ); 170 171 observerCalled = false; 172 173 var chan = makeChan( 174 "http://localhost:" + httpserv.identity.primaryPort + "/path/cached" 175 ); 176 chan.loadFlags = Ci.nsIRequest.VALIDATE_ALWAYS; 177 chan.asyncOpen(listener); 178 } 179 180 // PATHS 181 182 // /path/partial 183 function path_partial(metadata, response) { 184 Assert.ok(metadata.hasHeader("If-Range")); 185 Assert.equal(metadata.getHeader("If-Range"), "Thu, 1 Jan 2009 00:00:00 GMT"); 186 Assert.ok(metadata.hasHeader("Range")); 187 Assert.equal(metadata.getHeader("Range"), "bytes=4-"); 188 189 response.setStatusLine(metadata.httpVersion, 206, "Partial Content"); 190 response.setHeader("Content-Range", "bytes 4-9/10", false); 191 response.setHeader("Content-Type", "text/plain", false); 192 response.setHeader("Last-Modified", "Thu, 1 Jan 2009 00:00:00 GMT"); 193 194 var body = "456789"; 195 response.bodyOutputStream.write(body, body.length); 196 } 197 198 // /path/cached 199 function path_cached(metadata, response) { 200 Assert.ok(metadata.hasHeader("If-Modified-Since")); 201 Assert.equal( 202 metadata.getHeader("If-Modified-Since"), 203 "Thu, 1 Jan 2009 00:00:00 GMT" 204 ); 205 206 response.setStatusLine(metadata.httpVersion, 304, "Not Modified"); 207 }