test_channel_id.js 3.4 KB

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