test_channel_id.js (3429B)
1 const { HttpServer } = ChromeUtils.importESModule( 2 "resource://testing-common/httpd.sys.mjs" 3 ); 4 5 /* 6 * Test that when doing HTTP requests, the nsIHttpChannel is detected in 7 * both parent and child and shares the same channelId across processes. 8 */ 9 10 let httpserver; 11 let port; 12 13 function startHttpServer() { 14 httpserver = new HttpServer(); 15 16 httpserver.registerPathHandler("/resource", (metadata, response) => { 17 response.setStatusLine(metadata.httpVersion, 200, "OK"); 18 response.setHeader("Content-Type", "text/plain", false); 19 response.setHeader("Cache-Control", "no-cache", false); 20 response.bodyOutputStream.write("data", 4); 21 }); 22 23 httpserver.registerPathHandler("/redirect", (metadata, response) => { 24 response.setStatusLine(metadata.httpVersion, 302, "Redirect"); 25 response.setHeader("Location", "/resource", false); 26 response.setHeader("Cache-Control", "no-cache", false); 27 }); 28 29 httpserver.start(-1); 30 port = httpserver.identity.primaryPort; 31 } 32 33 function stopHttpServer(next) { 34 httpserver.stop(next); 35 } 36 37 let expectedParentChannels = []; 38 let expectedChildMessages = []; 39 40 let maybeFinishWaitForParentChannels; 41 let parentChannelsDone = new Promise(resolve => { 42 maybeFinishWaitForParentChannels = () => { 43 if (!expectedParentChannels.length) { 44 dump("All expected parent channels were detected\n"); 45 resolve(); 46 } 47 }; 48 }); 49 50 function observer(subject) { 51 let channel = subject.QueryInterface(Ci.nsIHttpChannel); 52 53 let uri = channel.URI.spec; 54 let origUri = channel.originalURI.spec; 55 let id = channel.channelId; 56 dump(`Parent detected channel: ${uri} (orig=${origUri}): channelId=${id}\n`); 57 58 // did we expect a new channel? 59 let expected = expectedParentChannels.shift(); 60 Assert.ok(!!expected); 61 62 // Start waiting for the messages about request/response from child 63 for (let event of expected) { 64 let message = `${event}:${id}`; 65 dump(`Expecting message from child: ${message}\n`); 66 67 let messagePromise = do_await_remote_message(message).then(() => { 68 dump(`Expected message from child arrived: ${message}\n`); 69 }); 70 expectedChildMessages.push(messagePromise); 71 } 72 73 // If we don't expect any further parent channels, finish the parent wait 74 maybeFinishWaitForParentChannels(); 75 } 76 77 function run_test() { 78 startHttpServer(); 79 Services.obs.addObserver(observer, "http-on-modify-request"); 80 run_test_in_child("child_channel_id.js", makeRequests); 81 } 82 83 function makeRequests() { 84 // First, a normal request without any redirect. Expect one channel detected 85 // in parent, used by both request and response. 86 expectedParentChannels.push(["request", "response"]); 87 sendCommand(`makeRequest("http://localhost:${port}/resource");`); 88 89 // Second request will be redirected. Expect two channels, one with the 90 // original request, then the redirected one which gets the final response. 91 expectedParentChannels.push(["request"], ["response"]); 92 sendCommand(`makeRequest("http://localhost:${port}/redirect");`); 93 94 waitForParentChannels(); 95 } 96 97 function waitForParentChannels() { 98 parentChannelsDone.then(waitForChildMessages); 99 } 100 101 function waitForChildMessages() { 102 dump(`Waiting for ${expectedChildMessages.length} child messages\n`); 103 Promise.all(expectedChildMessages).then(finish); 104 } 105 106 function finish() { 107 Services.obs.removeObserver(observer, "http-on-modify-request"); 108 sendCommand("finish();", () => stopHttpServer(do_test_finished)); 109 }