Bug 1152332 - Let connection proxy filters return the result asynchronously - update/introduce tests, r=michal

--HG--
rename : netwerk/test/unit/test_protocolproxyservice.js => netwerk/test/unit/test_protocolproxyservice-async-filters.js
This commit is contained in:
Honza Bambas 2018-02-08 05:49:00 +02:00
Родитель 53cdbf6d2a
Коммит e68b22643e
5 изменённых файлов: 481 добавлений и 12 удалений

Просмотреть файл

@ -72,11 +72,11 @@ function observeChannels(onChannel) {
// We use a dummy proxy filter to catch all channels, even those that do not
// generate an "http-on-modify-request" notification, such as link preconnects.
let proxyFilter = {
applyFilter(aProxyService, aChannel, aProxy) {
applyFilter(aProxyService, aChannel, aProxy, aCallback) {
// We have the channel; provide it to the callback.
onChannel(aChannel);
// Pass on aProxy unmodified.
return aProxy;
aCallback.onProxyFilterResult(aProxy);
}
};
protocolProxyService.registerChannelFilter(proxyFilter, 0);

Просмотреть файл

@ -0,0 +1,464 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* 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 testcase exercises the Protocol Proxy Service's async filter functionality
// run_filter_*() are entry points for each individual test.
"use strict";
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var pps = Components.classes["@mozilla.org/network/protocol-proxy-service;1"]
.getService();
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
/**
* Test nsIProtocolHandler that allows proxying, but doesn't allow HTTP
* proxying.
*/
function TestProtocolHandler() {
}
TestProtocolHandler.prototype = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIProtocolHandler) ||
iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
scheme: "moz-test",
defaultPort: -1,
protocolFlags: Components.interfaces.nsIProtocolHandler.URI_NOAUTH |
Components.interfaces.nsIProtocolHandler.URI_NORELATIVE |
Components.interfaces.nsIProtocolHandler.ALLOWS_PROXY |
Components.interfaces.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD,
newURI: function(spec, originCharset, baseURI) {
return Components.classes["@mozilla.org/network/simple-uri-mutator;1"]
.createInstance(Components.interfaces.nsIURIMutator)
.setSpec(spec)
.finalize();
},
newChannel2: function(uri, aLoadInfo) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
newChannel: function(uri) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
allowPort: function(port, scheme) {
return true;
}
};
function TestProtocolHandlerFactory() {
}
TestProtocolHandlerFactory.prototype = {
createInstance: function(delegate, iid) {
return new TestProtocolHandler().QueryInterface(iid);
},
lockFactory: function(lock) {
}
};
function register_test_protocol_handler() {
var reg = Components.manager.QueryInterface(
Components.interfaces.nsIComponentRegistrar);
reg.registerFactory(Components.ID("{4ea7dd3a-8cae-499c-9f18-e1de773ca25b}"),
"TestProtocolHandler",
"@mozilla.org/network/protocol;1?name=moz-test",
new TestProtocolHandlerFactory());
}
function check_proxy(pi, type, host, port, flags, timeout, hasNext) {
Assert.notEqual(pi, null);
Assert.equal(pi.type, type);
Assert.equal(pi.host, host);
Assert.equal(pi.port, port);
if (flags != -1)
Assert.equal(pi.flags, flags);
if (timeout != -1)
Assert.equal(pi.failoverTimeout, timeout);
if (hasNext)
Assert.notEqual(pi.failoverProxy, null);
else
Assert.equal(pi.failoverProxy, null);
}
const SYNC = 0;
const THROW = 1;
const ASYNC = 2;
function TestFilter(type, host, port, flags, timeout, result) {
this._type = type;
this._host = host;
this._port = port;
this._flags = flags;
this._timeout = timeout;
this._result = result;
}
TestFilter.prototype = {
_type: "",
_host: "",
_port: -1,
_flags: 0,
_timeout: 0,
_async: false,
_throwing: false,
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIProtocolProxyFilter) ||
iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
applyFilter: function(pps, uri, pi, cb) {
if (this._result == THROW) {
throw Cr.NS_ERROR_FAILURE;
}
var pi_tail = pps.newProxyInfo(this._type, this._host, this._port,
this._flags, this._timeout, null);
if (pi)
pi.failoverProxy = pi_tail;
else
pi = pi_tail;
if (this._result == ASYNC) {
executeSoon(() => { cb.onProxyFilterResult(pi) });
} else {
cb.onProxyFilterResult(pi);
}
}
};
function resolveCallback() { }
resolveCallback.prototype = {
nextFunction: null,
QueryInterface : function (iid) {
const interfaces = [Components.interfaces.nsIProtocolProxyCallback,
Components.interfaces.nsISupports];
if (!interfaces.some( function(v) { return iid.equals(v) } ))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
onProxyAvailable : function (req, channel, pi, status) {
this.nextFunction(pi);
}
};
// ==============================================================
var filter1;
var filter2;
var filter3;
function run_filter_test1() {
filter1 = new TestFilter("http", "foo", 8080, 0, 10, ASYNC);
filter2 = new TestFilter("http", "bar", 8090, 0, 10, ASYNC);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
var cb = new resolveCallback();
cb.nextFunction = filter_test1_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test1_1(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter2);
var cb = new resolveCallback();
cb.nextFunction = filter_test1_2;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test1_2(pi) {
check_proxy(pi, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
var cb = new resolveCallback();
cb.nextFunction = filter_test1_3;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test1_3(pi) {
Assert.equal(pi, null);
run_filter2_sync_async();
}
function run_filter2_sync_async() {
filter1 = new TestFilter("http", "foo", 8080, 0, 10, SYNC);
filter2 = new TestFilter("http", "bar", 8090, 0, 10, ASYNC);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
var cb = new resolveCallback();
cb.nextFunction = filter_test2_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test2_1(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
pps.unregisterFilter(filter2);
run_filter3_async_sync();
}
function run_filter3_async_sync()
{
filter1 = new TestFilter("http", "foo", 8080, 0, 10, ASYNC);
filter2 = new TestFilter("http", "bar", 8090, 0, 10, SYNC);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
var cb = new resolveCallback();
cb.nextFunction = filter_test3_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test3_1(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
pps.unregisterFilter(filter2);
run_filter4_throwing_sync_sync();
}
function run_filter4_throwing_sync_sync()
{
filter1 = new TestFilter("", "", 0, 0, 0, THROW);
filter2 = new TestFilter("http", "foo", 8080, 0, 10, SYNC);
filter3 = new TestFilter("http", "bar", 8090, 0, 10, SYNC);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
pps.registerFilter(filter3, 5);
var cb = new resolveCallback();
cb.nextFunction = filter_test4_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla2.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test4_1(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
pps.unregisterFilter(filter2);
pps.unregisterFilter(filter3);
run_filter5_sync_sync_throwing();
}
function run_filter5_sync_sync_throwing()
{
filter1 = new TestFilter("http", "foo", 8080, 0, 10, SYNC);
filter2 = new TestFilter("http", "bar", 8090, 0, 10, SYNC);
filter3 = new TestFilter("", "", 0, 0, 0, THROW);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
pps.registerFilter(filter3, 5);
var cb = new resolveCallback();
cb.nextFunction = filter_test5_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test5_1(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
pps.unregisterFilter(filter2);
pps.unregisterFilter(filter3);
run_filter5_2_throwing_async_async();
}
function run_filter5_2_throwing_async_async()
{
filter1 = new TestFilter("", "", 0, 0, 0, THROW);
filter2 = new TestFilter("http", "foo", 8080, 0, 10, ASYNC);
filter3 = new TestFilter("http", "bar", 8090, 0, 10, ASYNC);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
pps.registerFilter(filter3, 5);
var cb = new resolveCallback();
cb.nextFunction = filter_test5_2;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test5_2(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
pps.unregisterFilter(filter2);
pps.unregisterFilter(filter3);
run_filter6_async_async_throwing();
}
function run_filter6_async_async_throwing()
{
filter1 = new TestFilter("http", "foo", 8080, 0, 10, ASYNC);
filter2 = new TestFilter("http", "bar", 8090, 0, 10, ASYNC);
filter3 = new TestFilter("", "", 0, 0, 0, THROW);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
pps.registerFilter(filter3, 5);
var cb = new resolveCallback();
cb.nextFunction = filter_test6_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test6_1(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
pps.unregisterFilter(filter2);
pps.unregisterFilter(filter3);
run_filter7_async_throwing_async();
}
function run_filter7_async_throwing_async()
{
filter1 = new TestFilter("http", "foo", 8080, 0, 10, ASYNC);
filter2 = new TestFilter("", "", 0, 0, 0, THROW);
filter3 = new TestFilter("http", "bar", 8090, 0, 10, ASYNC);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
pps.registerFilter(filter3, 5);
var cb = new resolveCallback();
cb.nextFunction = filter_test7_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test7_1(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
pps.unregisterFilter(filter2);
pps.unregisterFilter(filter3);
run_filter8_sync_throwing_sync();
}
function run_filter8_sync_throwing_sync()
{
filter1 = new TestFilter("http", "foo", 8080, 0, 10, SYNC);
filter2 = new TestFilter("", "", 0, 0, 0, THROW);
filter3 = new TestFilter("http", "bar", 8090, 0, 10, SYNC);
pps.registerFilter(filter1, 20);
pps.registerFilter(filter2, 10);
pps.registerFilter(filter3, 5);
var cb = new resolveCallback();
cb.nextFunction = filter_test8_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test8_1(pi) {
check_proxy(pi, "http", "bar", 8090, 0, 10, true);
check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false);
pps.unregisterFilter(filter1);
pps.unregisterFilter(filter2);
pps.unregisterFilter(filter3);
run_filter9_throwing();
}
function run_filter9_throwing()
{
filter1 = new TestFilter("", "", 0, 0, 0, THROW);
pps.registerFilter(filter1, 20);
var cb = new resolveCallback();
cb.nextFunction = filter_test9_1;
var channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true
});
var req = pps.asyncResolve(channel, 0, cb);
}
function filter_test9_1(pi)
{
Assert.equal(pi, null);
do_test_finished();
}
// =========================================
function run_test() {
register_test_protocol_handler();
// start of asynchronous test chain
run_filter_test1();
do_test_pending();
}

Просмотреть файл

@ -118,14 +118,14 @@ TestFilter.prototype = {
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
applyFilter: function(pps, uri, pi) {
applyFilter: function(pps, uri, pi, cb) {
var pi_tail = pps.newProxyInfo(this._type, this._host, this._port,
this._flags, this._timeout, null);
if (pi)
pi.failoverProxy = pi_tail;
else
pi = pi_tail;
return pi;
cb.onProxyFilterResult(pi);
}
};
@ -137,9 +137,11 @@ BasicFilter.prototype = {
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
applyFilter: function(pps, uri, pi) {
return pps.newProxyInfo("http", "localhost", 8080, 0, 10,
pps.newProxyInfo("direct", "", -1, 0, 0, null));
applyFilter: function(pps, uri, pi, cb) {
cb.onProxyFilterResult(
pps.newProxyInfo("http", "localhost", 8080, 0, 10,
pps.newProxyInfo("direct", "", -1, 0, 0, null))
);
}
};
@ -151,9 +153,11 @@ BasicChannelFilter.prototype = {
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
applyFilter: function(pps, channel, pi) {
return pps.newProxyInfo("http", channel.URI.host, 7777, 0, 10,
pps.newProxyInfo("direct", "", -1, 0, 0, null));
applyFilter: function(pps, channel, pi, cb) {
cb.onProxyFilterResult(
pps.newProxyInfo("http", channel.URI.host, 7777, 0, 10,
pps.newProxyInfo("direct", "", -1, 0, 0, null))
);
}
};

Просмотреть файл

@ -269,6 +269,7 @@ skip-if = os == "android"
[test_private_cookie_changed.js]
[test_progress.js]
[test_protocolproxyservice.js]
[test_protocolproxyservice-async-filters.js]
[test_proxy-failover_canceled.js]
[test_proxy-failover_passing.js]
[test_proxy-replace_canceled.js]

Просмотреть файл

@ -226,7 +226,7 @@ function add_tests() {
// We use a dummy proxy filter to catch all channels, even those that do not
// generate an "http-on-modify-request" notification.
let proxyFilter = {
applyFilter(aProxyService, aChannel, aProxy) {
applyFilter(aProxyService, aChannel, aProxy, aCallback) {
// We have the channel; provide it to the callback.
if (aChannel.originalURI.spec == "http://localhost:8888/") {
gObservedCnt++;
@ -234,7 +234,7 @@ function add_tests() {
aFirstPartyDomain, "firstPartyDomain should match");
}
// Pass on aProxy unmodified.
return aProxy;
aCallback.onProxyFilterResult(aProxy);
}
};
protocolProxyService.registerChannelFilter(proxyFilter, 0);