michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // This test makes sure that the authorization header can get deleted e.g. by michael@0: // extensions if they are observing "http-on-modify-request". In a first step michael@0: // the auth cache is filled with credentials which then get added to the michael@0: // following request. On "http-on-modify-request" it is tested whether the michael@0: // authorization header got added at all and if so it gets removed. This test michael@0: // passes iff both succeeds. michael@0: michael@0: Components.utils.import("resource://testing-common/httpd.js"); michael@0: michael@0: var notification = "http-on-modify-request"; michael@0: michael@0: var httpServer = null; michael@0: michael@0: var authCredentials = "guest:guest"; michael@0: var authPath = "/authTest"; michael@0: var authCredsURL = "http://" + authCredentials + "@localhost:8888" + authPath; michael@0: var authURL = "http://localhost:8888" + authPath; michael@0: michael@0: function authHandler(metadata, response) { michael@0: if (metadata.hasHeader("Test")) { michael@0: // Lets see if the auth header got deleted. michael@0: var noAuthHeader = false; michael@0: if (!metadata.hasHeader("Authorization")) { michael@0: noAuthHeader = true; michael@0: } michael@0: do_check_true(noAuthHeader); michael@0: } else { michael@0: // Not our test request yet. michael@0: if (!metadata.hasHeader("Authorization")) { michael@0: response.setStatusLine(metadata.httpVersion, 401, "Unauthorized"); michael@0: response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false); michael@0: } michael@0: } michael@0: } michael@0: michael@0: function RequestObserver() { michael@0: this.register(); michael@0: } michael@0: michael@0: RequestObserver.prototype = { michael@0: register: function() { michael@0: do_print("Registering " + notification); michael@0: Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService). michael@0: addObserver(this, notification, true); michael@0: }, michael@0: michael@0: QueryInterface: function(iid) { michael@0: if (iid.equals(Ci.nsIObserver) || iid.equals(Ci.nsISupportsWeakReference) || michael@0: iid.equals(Ci.nsISupports)) { michael@0: return this; michael@0: } michael@0: throw Cr.NS_ERROR_NO_INTERFACE; michael@0: }, michael@0: michael@0: observe: function(subject, topic, data) { michael@0: if (topic == notification) { michael@0: if (!(subject instanceof Ci.nsIHttpChannel)) { michael@0: do_throw(notification + " observed a non-HTTP channel."); michael@0: } michael@0: try { michael@0: let authHeader = subject.getRequestHeader("Authorization"); michael@0: } catch (e) { michael@0: // Throw if there is no header to delete. We should get one iff caching michael@0: // the auth credentials is working and the header gets added _before_ michael@0: // "http-on-modify-request" gets called. michael@0: httpServer.stop(do_test_finished); michael@0: do_throw("No authorization header found, aborting!"); michael@0: } michael@0: // We are still here. Let's remove the authorization header now. michael@0: subject.setRequestHeader("Authorization", null, false); michael@0: } michael@0: } michael@0: } michael@0: michael@0: var listener = { michael@0: onStartRequest: function test_onStartR(request, ctx) {}, michael@0: michael@0: onDataAvailable: function test_ODA() { michael@0: do_throw("Should not get any data!"); michael@0: }, michael@0: michael@0: onStopRequest: function test_onStopR(request, ctx, status) { michael@0: if (current_test < (tests.length - 1)) { michael@0: current_test++; michael@0: tests[current_test](); michael@0: } else { michael@0: do_test_pending(); michael@0: httpServer.stop(do_test_finished); michael@0: } michael@0: do_test_finished(); michael@0: } michael@0: }; michael@0: michael@0: function makeChan(url) { michael@0: var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); michael@0: var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel); michael@0: return chan; michael@0: } michael@0: michael@0: var tests = [startAuthHeaderTest, removeAuthHeaderTest]; michael@0: michael@0: var current_test = 0; michael@0: michael@0: var requestObserver = null; michael@0: michael@0: function run_test() { michael@0: httpServer = new HttpServer(); michael@0: httpServer.registerPathHandler(authPath, authHandler); michael@0: httpServer.start(8888); michael@0: michael@0: tests[0](); michael@0: } michael@0: michael@0: function startAuthHeaderTest() { michael@0: var chan = makeChan(authCredsURL); michael@0: chan.asyncOpen(listener, null); michael@0: michael@0: do_test_pending(); michael@0: } michael@0: michael@0: function removeAuthHeaderTest() { michael@0: // After caching the auth credentials in the first test, lets try to remove michael@0: // the authorization header now... michael@0: requestObserver = new RequestObserver(); michael@0: var chan = makeChan(authURL); michael@0: // Indicating that the request is coming from the second test. michael@0: chan.setRequestHeader("Test", "1", false); michael@0: chan.asyncOpen(listener, null); michael@0: michael@0: do_test_pending(); michael@0: }