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