summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit_ipc/test_channel_id.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/unit_ipc/test_channel_id.js')
-rw-r--r--netwerk/test/unit_ipc/test_channel_id.js109
1 files changed, 109 insertions, 0 deletions
diff --git a/netwerk/test/unit_ipc/test_channel_id.js b/netwerk/test/unit_ipc/test_channel_id.js
new file mode 100644
index 000000000..d82e5f5df
--- /dev/null
+++ b/netwerk/test/unit_ipc/test_channel_id.js
@@ -0,0 +1,109 @@
+Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Promise.jsm");
+
+/*
+ * Test that when doing HTTP requests, the nsIHttpChannel is detected in
+ * both parent and child and shares the same channelId across processes.
+ */
+
+let httpserver;
+let port;
+
+function startHttpServer() {
+ httpserver = new HttpServer();
+
+ httpserver.registerPathHandler("/resource", (metadata, response) => {
+ response.setStatusLine(metadata.httpVersion, 200, "OK");
+ response.setHeader("Content-Type", "text/plain", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.bodyOutputStream.write("data", 4);
+ });
+
+ httpserver.registerPathHandler("/redirect", (metadata, response) => {
+ response.setStatusLine(metadata.httpVersion, 302, "Redirect");
+ response.setHeader("Location", "/resource", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+ });
+
+ httpserver.start(-1);
+ port = httpserver.identity.primaryPort;
+}
+
+function stopHttpServer(next) {
+ httpserver.stop(next);
+}
+
+let expectedParentChannels = [];
+let expectedChildMessages = [];
+
+let maybeFinishWaitForParentChannels;
+let parentChannelsDone = new Promise(resolve => {
+ maybeFinishWaitForParentChannels = () => {
+ if (expectedParentChannels.length == 0) {
+ dump("All expected parent channels were detected\n");
+ resolve();
+ }
+ };
+});
+
+function observer(subject, topic, data) {
+ let channel = subject.QueryInterface(Ci.nsIHttpChannel);
+
+ let uri = channel.URI.spec;
+ let origUri = channel.originalURI.spec;
+ let id = channel.channelId;
+ dump(`Parent detected channel: ${uri} (orig=${origUri}): channelId=${id}\n`);
+
+ // did we expect a new channel?
+ let expected = expectedParentChannels.shift();
+ do_check_true(!!expected);
+
+ // Start waiting for the messages about request/response from child
+ for (let event of expected) {
+ let message = `${event}:${id}`;
+ dump(`Expecting message from child: ${message}\n`);
+
+ let messagePromise = do_await_remote_message(message).then(() => {
+ dump(`Expected message from child arrived: ${message}\n`);
+ });
+ expectedChildMessages.push(messagePromise);
+ }
+
+ // If we don't expect any further parent channels, finish the parent wait
+ maybeFinishWaitForParentChannels();
+}
+
+function run_test() {
+ startHttpServer();
+ Services.obs.addObserver(observer, "http-on-modify-request", false);
+ run_test_in_child("child_channel_id.js", makeRequests);
+}
+
+function makeRequests() {
+ // First, a normal request without any redirect. Expect one channel detected
+ // in parent, used by both request and response.
+ expectedParentChannels.push(["request", "response"]);
+ sendCommand(`makeRequest("http://localhost:${port}/resource");`);
+
+ // Second request will be redirected. Expect two channels, one with the
+ // original request, then the redirected one which gets the final response.
+ expectedParentChannels.push(["request"], ["response"]);
+ sendCommand(`makeRequest("http://localhost:${port}/redirect");`);
+
+ waitForParentChannels();
+}
+
+function waitForParentChannels() {
+ parentChannelsDone.then(waitForChildMessages);
+}
+
+function waitForChildMessages() {
+ dump(`Waiting for ${expectedChildMessages.length} child messages\n`);
+ Promise.all(expectedChildMessages).then(finish);
+}
+
+function finish() {
+ Services.obs.removeObserver(observer, "http-on-modify-request");
+ sendCommand("finish();", () => stopHttpServer(do_test_finished));
+}