1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// This test makes sure that the authorization header can get deleted e.g. by
// extensions if they are observing "http-on-modify-request". In a first step
// the auth cache is filled with credentials which then get added to the
// following request. On "http-on-modify-request" it is tested whether the
// authorization header got added at all and if so it gets removed. This test
// passes iff both succeeds.
"use strict";
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
var notification = "http-on-modify-request";
var httpServer = null;
var authCredentials = "guest:guest";
var authPath = "/authTest";
var authCredsURL = "http://" + authCredentials + "@localhost:8888" + authPath;
var authURL = "http://localhost:8888" + authPath;
function authHandler(metadata, response) {
if (metadata.hasHeader("Test")) {
// Lets see if the auth header got deleted.
var noAuthHeader = false;
if (!metadata.hasHeader("Authorization")) {
noAuthHeader = true;
}
Assert.ok(noAuthHeader);
}
// Not our test request yet.
else if (!metadata.hasHeader("Authorization")) {
response.setStatusLine(metadata.httpVersion, 401, "Unauthorized");
response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
}
}
function RequestObserver() {
this.register();
}
RequestObserver.prototype = {
register() {
info("Registering " + notification);
Services.obs.addObserver(this, notification, true);
},
QueryInterface: ChromeUtils.generateQI([
"nsIObserver",
"nsISupportsWeakReference",
]),
observe(subject, topic, data) {
if (topic == notification) {
if (!(subject instanceof Ci.nsIHttpChannel)) {
do_throw(notification + " observed a non-HTTP channel.");
}
try {
subject.getRequestHeader("Authorization");
} catch (e) {
// Throw if there is no header to delete. We should get one iff caching
// the auth credentials is working and the header gets added _before_
// "http-on-modify-request" gets called.
httpServer.stop(do_test_finished);
do_throw("No authorization header found, aborting!");
}
// We are still here. Let's remove the authorization header now.
subject.setRequestHeader("Authorization", null, false);
}
},
};
var listener = {
onStartRequest: function test_onStartR(request) {},
onDataAvailable: function test_ODA() {
do_throw("Should not get any data!");
},
onStopRequest: function test_onStopR(request, status) {
if (current_test < tests.length - 1) {
current_test++;
tests[current_test]();
} else {
do_test_pending();
httpServer.stop(do_test_finished);
}
do_test_finished();
},
};
function makeChan(url) {
return NetUtil.newChannel({
uri: url,
loadUsingSystemPrincipal: true,
}).QueryInterface(Ci.nsIHttpChannel);
}
var tests = [startAuthHeaderTest, removeAuthHeaderTest];
var current_test = 0;
// Must create a RequestObserver for the test to pass, we keep it in memory
// to avoid garbage collection.
// eslint-disable-next-line no-unused-vars
var requestObserver = null;
function run_test() {
httpServer = new HttpServer();
httpServer.registerPathHandler(authPath, authHandler);
httpServer.start(8888);
tests[0]();
}
function startAuthHeaderTest() {
var chan = makeChan(authCredsURL);
chan.asyncOpen(listener);
do_test_pending();
}
function removeAuthHeaderTest() {
// After caching the auth credentials in the first test, lets try to remove
// the authorization header now...
requestObserver = new RequestObserver();
var chan = makeChan(authURL);
// Indicating that the request is coming from the second test.
chan.setRequestHeader("Test", "1", false);
chan.asyncOpen(listener);
do_test_pending();
}
|