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/. */
7 const { HttpServer
} = ChromeUtils
.importESModule(
8 "resource://testing-common/httpd.sys.mjs"
11 const SUCCESS_TEXT
= "success!";
13 function successResponseHandler(req
, resp
) {
14 var text
= SUCCESS_TEXT
;
15 resp
.setHeader("Content-Type", "text/plain", false);
16 resp
.bodyOutputStream
.write(text
, text
.length
);
19 function onBeforeConnect(callback
) {
20 Services
.obs
.addObserver(
23 Services
.obs
.removeObserver(this, "http-on-before-connect");
24 callback(subject
.QueryInterface(Ci
.nsIHttpChannel
));
27 "http-on-before-connect"
31 function onExamineResponse(callback
) {
32 Services
.obs
.addObserver(
35 Services
.obs
.removeObserver(this, "http-on-examine-response");
36 callback(subject
.QueryInterface(Ci
.nsIHttpChannel
));
39 "http-on-examine-response"
43 class EventSinkListener
{
45 if (iid
.equals(Ci
.nsIChannelEventSink
)) {
48 throw Components
.Exception("", Cr
.NS_ERROR_NO_INTERFACE
);
50 asyncOnChannelRedirect(oldChan
, newChan
, flags
, callback
) {
51 // if transparent, asyncOnChannelRedirect should not be called.
53 callback
.onRedirectVerifyCallback(Cr
.NS_OK
);
57 EventSinkListener
.prototype.QueryInterface
= ChromeUtils
.generateQI([
58 "nsIInterfaceRequestor",
59 "nsIChannelEventSink",
62 add_task(async
function test_transparent_redirect() {
63 var server
= new HttpServer();
64 await server
.start(-1);
65 registerCleanupFunction(async () => {
69 server
.registerPathHandler("/success", successResponseHandler
);
71 const baseUrl
= `http://localhost:${server.identity.primaryPort}/`;
72 const successUrl
= baseUrl
+ "success";
74 onBeforeConnect(chan
=> {
76 Promise
.resolve().then(() => {
78 chan
.transparentRedirectTo(Services
.io
.newURI(successUrl
));
86 onExamineResponse(chan
=> {
87 chan
.QueryInterface(Ci
.nsITimedChannel
);
88 Assert
.equal(chan
.redirectCount
, 0, "redirectCount should be 0");
90 chan
.internalRedirectCount
,
92 "internalRedirectCount should be 1"
96 let chan
= NetUtil
.newChannel({
98 loadUsingSystemPrincipal
: true,
99 }).QueryInterface(Ci
.nsIHttpChannelInternal
);
100 let listener
= new EventSinkListener();
101 chan
.notificationCallbacks
= listener
;
103 await
new Promise(resolve
=> {
107 // Should hit /success for both.
108 Assert
.equal(resp
, SUCCESS_TEXT
, "Should redirect to success");