Bug 1138354 - Add proxy authencation info for 'mozbrowserusernameandpasswordrequired' event. r=mayhemer

This commit is contained in:
Shian-Yow Wu 2015-03-26 18:49:16 +08:00
parent 4728e2412c
commit c074ff533b
5 changed files with 120 additions and 4 deletions

View File

@ -272,7 +272,8 @@ BrowserElementParent.prototype = {
/* username and password */
let detail = {
host: authDetail.host,
realm: authDetail.realm
realm: authDetail.realm,
isProxy: authDetail.isProxy
};
evt = this._createEvent('usernameandpasswordrequired', detail,

View File

@ -383,17 +383,46 @@ BrowserElementAuthPrompt.prototype = {
host: hostname,
realm: httpRealm,
username: authInfo.username,
isProxy: !!(authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY),
isOnlyPassword: !!(authInfo.flags & Ci.nsIAuthInformation.ONLY_PASSWORD)
};
},
// The code is taken from nsLoginManagerPrompter.js, with slight
// modification for parameter name consistency here.
_getAuthTarget : function (channel, authInfo) {
let hostname = this._getFormattedHostname(channel.URI);
let hostname, realm;
// If our proxy is demanding authentication, don't use the
// channel's actual destination.
if (authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) {
if (!(channel instanceof Ci.nsIProxiedChannel))
throw new Error("proxy auth needs nsIProxiedChannel");
let info = channel.proxyInfo;
if (!info)
throw new Error("proxy auth needs nsIProxyInfo");
// Proxies don't have a scheme, but we'll use "moz-proxy://"
// so that it's more obvious what the login is for.
var idnService = Cc["@mozilla.org/network/idn-service;1"].
getService(Ci.nsIIDNService);
hostname = "moz-proxy://" +
idnService.convertUTF8toACE(info.host) +
":" + info.port;
realm = authInfo.realm;
if (!realm)
realm = hostname;
return [hostname, realm];
}
hostname = this._getFormattedHostname(channel.URI);
// If a HTTP WWW-Authenticate header specified a realm, that value
// will be available here. If it wasn't set or wasn't HTTP, we'll use
// the formatted hostname instead.
let realm = authInfo.realm;
realm = authInfo.realm;
if (!realm)
realm = hostname;

View File

@ -66,11 +66,12 @@ function testHttpAuth(e) {
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
is(e.detail, 'http auth success', 'expect authentication to succeed');
SimpleTest.executeSoon(testAuthJarNoInterfere);
SimpleTest.executeSoon(testProxyAuth);
});
is(e.detail.realm, 'http_realm', 'expected realm matches');
is(e.detail.host, 'http://test', 'expected host matches');
is(e.detail.isProxy, false, 'expected isProxy is false');
e.preventDefault();
SimpleTest.executeSoon(function() {
@ -78,6 +79,74 @@ function testHttpAuth(e) {
});
}
function testProxyAuth(e) {
// The testingSJS simulates the 407 proxy authentication required response
// for proxy server, which will trigger the browser element to send prompt
// event with proxy infomation.
var testingSJS = 'http://test/tests/dom/browser-element/mochitest/file_http_407_response.sjs';
var mozproxy;
function onUserNameAndPasswordRequired(e) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired);
iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
is(e.detail, 'http auth success', 'expect authentication to succeed');
SimpleTest.executeSoon(testAuthJarNoInterfere);
});
is(e.detail.realm, 'http_realm', 'expected realm matches');
is(e.detail.host, mozproxy, 'expected host matches');
is(e.detail.isProxy, true, 'expected isProxy is true');
e.preventDefault();
SimpleTest.executeSoon(function() {
e.detail.authenticate("proxyuser", "proxypass");
});
}
// Resolve proxy information used by the test suite, we need it to validate
// whether the proxy information delivered with the prompt event is correct.
var resolveCallback = SpecialPowers.wrapCallbackObject({
QueryInterface: function (iid) {
const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
if (!interfaces.some( function(v) { return iid.equals(v) } )) {
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
}
return this;
},
onProxyAvailable: function (req, channel, pi, status) {
isnot(pi, null, 'expected proxy information available');
if (pi) {
mozproxy = "moz-proxy://" + pi.host + ":" + pi.port;
}
iframe.addEventListener("mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired);
iframe.src = testingSJS;
}
});
var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
.getService(SpecialPowers.Ci.nsIIOService);
var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"]
.getService();
var systemPrincipal = SpecialPowers.Services.scriptSecurityManager
.getSystemPrincipal();
var channel = ioService.newChannel2(testingSJS,
null,
null,
null,
systemPrincipal,
null,
SpecialPowers.Ci.nsILoadInfo.SEC_NORMAL,
SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER);
pps.asyncResolve(channel, 0, resolveCallback);
}
function testAuthJarNoInterfere(e) {
var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
.getService(SpecialPowers.Ci.nsIHttpAuthManager);

View File

@ -0,0 +1,16 @@
function handleRequest(request, response)
{
var auth = "";
try {
auth = request.getHeader("Proxy-Authorization");
} catch(e) {}
if (auth == "Basic cHJveHl1c2VyOnByb3h5cGFzcw==") {
response.setStatusLine("1.1", 200, "OK");
response.write("<html><head><title>http auth success</title></head><html>");
} else {
response.setStatusLine("1.1", 407, "Proxy Authentication Required");
response.setHeader("Proxy-Authenticate", "Basic realm=\"http_realm\"");
response.write("<html><head><title>http auth failed</title></head><html>");
}
}

View File

@ -111,6 +111,7 @@ support-files =
file_empty_script.js
file_focus.html
file_http_401_response.sjs
file_http_407_response.sjs
file_inputmethod.html
file_post_request.html
file_wyciwyg.html