1 // This file tests async handling of a channel suspended in http-on-modify-request.
4 const { HttpServer } = ChromeUtils.importESModule(
5 "resource://testing-common/httpd.sys.mjs"
8 var obs = Services.obs;
10 var ios = Services.io;
12 // baseUrl is always the initial connection attempt and is handled by
13 // failResponseHandler since every test expects that request will either be
14 // redirected or cancelled.
17 function failResponseHandler(metadata, response) {
18 var text = "failure response";
19 response.setHeader("Content-Type", "text/plain", false);
20 response.bodyOutputStream.write(text, text.length);
21 Assert.ok(false, "Received request when we shouldn't.");
24 function successResponseHandler(metadata, response) {
25 var text = "success response";
26 response.setHeader("Content-Type", "text/plain", false);
27 response.bodyOutputStream.write(text, text.length);
28 Assert.ok(true, "Received expected request.");
31 function onModifyListener(callback) {
34 observe(subject, topic, data) {
35 var obs = Cc["@mozilla.org/observer-service;1"].getService();
36 obs = obs.QueryInterface(Ci.nsIObserverService);
37 obs.removeObserver(this, "http-on-modify-request");
38 callback(subject.QueryInterface(Ci.nsIHttpChannel));
41 "http-on-modify-request"
45 function startChannelRequest(baseUrl, flags, expectedResponse = null) {
46 var chan = NetUtil.newChannel({
48 loadUsingSystemPrincipal: true,
52 (request, data, context) => {
53 if (expectedResponse) {
54 Assert.equal(data, expectedResponse);
56 Assert.ok(!data, "no response");
58 executeSoon(run_next_test);
66 add_test(function testSimpleRedirect() {
67 onModifyListener(chan => {
68 chan.redirectTo(ios.newURI(`${baseUrl}/success`));
70 startChannelRequest(baseUrl, undefined, "success response");
73 add_test(function testSimpleCancel() {
74 onModifyListener(chan => {
75 chan.cancel(Cr.NS_BINDING_ABORTED);
77 startChannelRequest(baseUrl, CL_EXPECT_FAILURE);
80 add_test(function testSimpleCancelRedirect() {
81 onModifyListener(chan => {
82 chan.redirectTo(ios.newURI(`${baseUrl}/fail`));
83 chan.cancel(Cr.NS_BINDING_ABORTED);
85 startChannelRequest(baseUrl, CL_EXPECT_FAILURE);
88 // Test a request that will get redirected asynchronously. baseUrl should
89 // not be requested, we should receive the request for the redirectedUrl.
90 add_test(function testAsyncRedirect() {
91 onModifyListener(chan => {
92 // Suspend the channel then yield to make this async.
94 Promise.resolve().then(() => {
95 chan.redirectTo(ios.newURI(`${baseUrl}/success`));
99 startChannelRequest(baseUrl, undefined, "success response");
102 add_test(function testSyncRedirect() {
103 onModifyListener(chan => {
105 chan.redirectTo(ios.newURI(`${baseUrl}/success`));
106 Promise.resolve().then(() => {
110 startChannelRequest(baseUrl, undefined, "success response");
113 add_test(function testAsyncCancel() {
114 onModifyListener(chan => {
115 // Suspend the channel then yield to make this async.
117 Promise.resolve().then(() => {
118 chan.cancel(Cr.NS_BINDING_ABORTED);
122 startChannelRequest(baseUrl, CL_EXPECT_FAILURE);
125 add_test(function testSyncCancel() {
126 onModifyListener(chan => {
128 chan.cancel(Cr.NS_BINDING_ABORTED);
129 Promise.resolve().then(() => {
133 startChannelRequest(baseUrl, CL_EXPECT_FAILURE);
136 // Test request that will get redirected and cancelled asynchronously,
137 // ensure no connection is made.
138 add_test(function testAsyncCancelRedirect() {
139 onModifyListener(chan => {
140 // Suspend the channel then yield to make this async.
142 Promise.resolve().then(() => {
143 chan.cancel(Cr.NS_BINDING_ABORTED);
144 chan.redirectTo(ios.newURI(`${baseUrl}/fail`));
148 startChannelRequest(baseUrl, CL_EXPECT_FAILURE);
151 // Test a request that will get cancelled synchronously, ensure async redirect
153 add_test(function testSyncCancelRedirect() {
154 onModifyListener(chan => {
156 chan.cancel(Cr.NS_BINDING_ABORTED);
157 Promise.resolve().then(() => {
158 chan.redirectTo(ios.newURI(`${baseUrl}/fail`));
162 startChannelRequest(baseUrl, CL_EXPECT_FAILURE);
165 function run_test() {
166 var httpServer = new HttpServer();
167 httpServer.registerPathHandler("/", failResponseHandler);
168 httpServer.registerPathHandler("/fail", failResponseHandler);
169 httpServer.registerPathHandler("/success", successResponseHandler);
170 httpServer.start(-1);
172 baseUrl = `http://localhost:${httpServer.identity.primaryPort}`;
176 registerCleanupFunction(function () {
177 httpServer.stop(() => {});