Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / netwerk / test / unit / test_suspend_channel_on_authRetry.js
blobef242b65e5ba91122df3b64ae953a9ab6db2ce32
1 // This file tests async handling of a channel suspended in DoAuthRetry
2 // notifying http-on-modify-request and http-on-before-connect observers.
3 "use strict";
5 const { HttpServer } = ChromeUtils.importESModule(
6 "resource://testing-common/httpd.sys.mjs"
7 );
9 ChromeUtils.defineLazyGetter(this, "URL", function () {
10 return "http://localhost:" + httpserv.identity.primaryPort;
11 });
13 var obs = Services.obs;
15 var requestObserver = null;
17 function AuthPrompt() {}
19 AuthPrompt.prototype = {
20 user: "guest",
21 pass: "guest",
23 QueryInterface: ChromeUtils.generateQI(["nsIAuthPrompt"]),
25 prompt: function ap1_prompt() {
26 do_throw("unexpected prompt call");
29 promptUsernameAndPassword: function promptUP(
30 title,
31 text,
32 realm,
33 savePW,
34 user,
36 ) {
37 user.value = this.user;
38 pw.value = this.pass;
40 obs.addObserver(requestObserver, "http-on-before-connect");
41 obs.addObserver(requestObserver, "http-on-modify-request");
42 return true;
45 promptPassword: function promptPW() {
46 do_throw("unexpected promptPassword call");
50 function requestListenerObserver(
51 suspendOnBeforeConnect,
52 suspendOnModifyRequest
53 ) {
54 this.suspendOnModifyRequest = suspendOnModifyRequest;
55 this.suspendOnBeforeConnect = suspendOnBeforeConnect;
58 requestListenerObserver.prototype = {
59 suspendOnModifyRequest: false,
60 suspendOnBeforeConnect: false,
61 gotOnBeforeConnect: false,
62 resumeOnBeforeConnect: false,
63 gotOnModifyRequest: false,
64 resumeOnModifyRequest: false,
65 QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
67 observe(subject, topic) {
68 if (
69 topic === "http-on-before-connect" &&
70 subject instanceof Ci.nsIHttpChannel
71 ) {
72 if (this.suspendOnBeforeConnect) {
73 let chan = subject.QueryInterface(Ci.nsIHttpChannel);
74 executeSoon(() => {
75 this.resumeOnBeforeConnect = true;
76 chan.resume();
77 });
78 this.gotOnBeforeConnect = true;
79 chan.suspend();
81 } else if (
82 topic === "http-on-modify-request" &&
83 subject instanceof Ci.nsIHttpChannel
84 ) {
85 if (this.suspendOnModifyRequest) {
86 let chan = subject.QueryInterface(Ci.nsIHttpChannel);
87 executeSoon(() => {
88 this.resumeOnModifyRequest = true;
89 chan.resume();
90 });
91 this.gotOnModifyRequest = true;
92 chan.suspend();
98 function Requestor() {}
100 Requestor.prototype = {
101 QueryInterface: ChromeUtils.generateQI(["nsIInterfaceRequestor"]),
103 getInterface: function requestor_gi(iid) {
104 if (iid.equals(Ci.nsIAuthPrompt)) {
105 // Allow the prompt to store state by caching it here
106 if (!this.prompt) {
107 this.prompt = new AuthPrompt();
109 return this.prompt;
112 throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
115 prompt: null,
118 var listener = {
119 expectedCode: -1, // Uninitialized
121 onStartRequest: function test_onStartR(request) {
122 try {
123 if (!Components.isSuccessCode(request.status)) {
124 do_throw("Channel should have a success code!");
127 if (!(request instanceof Ci.nsIHttpChannel)) {
128 do_throw("Expecting an HTTP channel");
131 Assert.equal(request.responseStatus, this.expectedCode);
132 // The request should be succeeded iff we expect 200
133 Assert.equal(request.requestSucceeded, this.expectedCode == 200);
134 } catch (e) {
135 do_throw("Unexpected exception: " + e);
137 throw Components.Exception("", Cr.NS_ERROR_ABORT);
140 onDataAvailable: function test_ODA() {
141 do_throw("Should not get any data!");
144 onStopRequest: function test_onStopR(request, status) {
145 Assert.equal(status, Cr.NS_ERROR_ABORT);
146 if (requestObserver.suspendOnBeforeConnect) {
147 Assert.ok(
148 requestObserver.gotOnBeforeConnect &&
149 requestObserver.resumeOnBeforeConnect
152 if (requestObserver.suspendOnModifyRequest) {
153 Assert.ok(
154 requestObserver.gotOnModifyRequest &&
155 requestObserver.resumeOnModifyRequest
158 obs.removeObserver(requestObserver, "http-on-before-connect");
159 obs.removeObserver(requestObserver, "http-on-modify-request");
160 moveToNextTest();
164 function makeChan(url, loadingUrl) {
165 var principal = Services.scriptSecurityManager.createContentPrincipal(
166 Services.io.newURI(loadingUrl),
169 return NetUtil.newChannel({
170 uri: url,
171 loadingPrincipal: principal,
172 securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
173 contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
177 var tests = [
178 test_suspend_on_before_connect,
179 test_suspend_on_modify_request,
180 test_suspend_all,
183 var current_test = 0;
185 var httpserv = null;
187 function moveToNextTest() {
188 if (current_test < tests.length - 1) {
189 // First, gotta clear the auth cache
190 Cc["@mozilla.org/network/http-auth-manager;1"]
191 .getService(Ci.nsIHttpAuthManager)
192 .clearAll();
194 current_test++;
195 tests[current_test]();
196 } else {
197 do_test_pending();
198 httpserv.stop(do_test_finished);
201 do_test_finished();
204 function run_test() {
205 httpserv = new HttpServer();
207 httpserv.registerPathHandler("/auth", authHandler);
209 httpserv.start(-1);
211 tests[0]();
214 function test_suspend_on_auth(suspendOnBeforeConnect, suspendOnModifyRequest) {
215 var chan = makeChan(URL + "/auth", URL);
216 requestObserver = new requestListenerObserver(
217 suspendOnBeforeConnect,
218 suspendOnModifyRequest
220 chan.notificationCallbacks = new Requestor();
221 listener.expectedCode = 200; // OK
222 chan.asyncOpen(listener);
224 do_test_pending();
227 function test_suspend_on_before_connect() {
228 test_suspend_on_auth(true, false);
231 function test_suspend_on_modify_request() {
232 test_suspend_on_auth(false, true);
235 function test_suspend_all() {
236 test_suspend_on_auth(true, true);
239 // PATH HANDLERS
241 // /auth
242 function authHandler(metadata, response) {
243 // btoa("guest:guest"), but that function is not available here
244 var expectedHeader = "Basic Z3Vlc3Q6Z3Vlc3Q=";
246 var body;
247 if (
248 metadata.hasHeader("Authorization") &&
249 metadata.getHeader("Authorization") == expectedHeader
251 response.setStatusLine(metadata.httpVersion, 200, "OK, authorized");
252 response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
254 body = "success";
255 } else {
256 // didn't know guest:guest, failure
257 response.setStatusLine(metadata.httpVersion, 401, "Unauthorized");
258 response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
260 body = "failed";
263 response.bodyOutputStream.write(body, body.length);