forked from mirrors/gecko-dev
247 lines
7.1 KiB
JavaScript
247 lines
7.1 KiB
JavaScript
"use strict";
|
|
|
|
AddonTestUtils.init(this);
|
|
AddonTestUtils.overrideCertDB();
|
|
AddonTestUtils.createAppInfo(
|
|
"xpcshell@tests.mozilla.org",
|
|
"XPCShell",
|
|
"1",
|
|
"43"
|
|
);
|
|
|
|
let { promiseRestartManager, promiseShutdownManager, promiseStartupManager } =
|
|
AddonTestUtils;
|
|
|
|
let nonProxiedRequests = 0;
|
|
const nonProxiedServer = createHttpServer({ hosts: ["example.com"] });
|
|
nonProxiedServer.registerPathHandler("/", (request, response) => {
|
|
nonProxiedRequests++;
|
|
response.setStatusLine(request.httpVersion, 200, "OK");
|
|
response.write("ok");
|
|
});
|
|
|
|
// No hosts defined to avoid proxy filter setup.
|
|
let proxiedRequests = 0;
|
|
const server = createHttpServer();
|
|
server.identity.add("http", "proxied.example.com", 80);
|
|
server.registerPathHandler("/", (request, response) => {
|
|
proxiedRequests++;
|
|
response.setStatusLine(request.httpVersion, 200, "OK");
|
|
response.write("ok");
|
|
});
|
|
|
|
function trackEvents(wrapper) {
|
|
let events = new Map();
|
|
for (let event of ["background-script-event", "start-background-script"]) {
|
|
events.set(event, false);
|
|
wrapper.extension.once(event, () => events.set(event, true));
|
|
}
|
|
return events;
|
|
}
|
|
|
|
add_setup(() => {
|
|
// In case the prefs have a different value by default.
|
|
Services.prefs.setBoolPref(
|
|
"extensions.webextensions.early_background_wakeup_on_request",
|
|
false
|
|
);
|
|
});
|
|
|
|
// Test that a proxy listener during startup does not immediately
|
|
// start the background page, but the event is queued until the background
|
|
// page is started.
|
|
add_task(async function test_proxy_startup() {
|
|
await promiseStartupManager();
|
|
|
|
function background(proxyInfo) {
|
|
browser.proxy.onRequest.addListener(
|
|
details => {
|
|
// ignore speculative requests
|
|
if (details.type == "xmlhttprequest") {
|
|
browser.test.sendMessage("saw-request");
|
|
}
|
|
return proxyInfo;
|
|
},
|
|
{ urls: ["<all_urls>"] }
|
|
);
|
|
}
|
|
|
|
let proxyInfo = {
|
|
host: server.identity.primaryHost,
|
|
port: server.identity.primaryPort,
|
|
type: "http",
|
|
};
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
permissions: ["proxy", "http://proxied.example.com/*"],
|
|
},
|
|
background: `(${background})(${JSON.stringify(proxyInfo)})`,
|
|
});
|
|
|
|
await extension.startup();
|
|
|
|
// Initial requests to test the proxy and non-proxied servers.
|
|
await Promise.all([
|
|
extension.awaitMessage("saw-request"),
|
|
ExtensionTestUtils.fetch("http://proxied.example.com/?a=0"),
|
|
]);
|
|
equal(1, proxiedRequests, "proxied request ok");
|
|
equal(0, nonProxiedRequests, "non proxied request ok");
|
|
|
|
await ExtensionTestUtils.fetch("http://example.com/?a=0");
|
|
equal(1, proxiedRequests, "proxied request ok");
|
|
equal(1, nonProxiedRequests, "non proxied request ok");
|
|
|
|
await promiseRestartManager({ earlyStartup: false });
|
|
await extension.awaitStartup();
|
|
|
|
let events = trackEvents(extension);
|
|
|
|
// Initiate a non-proxied request to make sure the startup listeners are using
|
|
// the extensions filters/etc.
|
|
await ExtensionTestUtils.fetch("http://example.com/?a=1");
|
|
equal(1, proxiedRequests, "proxied request ok");
|
|
equal(2, nonProxiedRequests, "non proxied request ok");
|
|
|
|
equal(
|
|
events.get("background-script-event"),
|
|
false,
|
|
"Should not have gotten a background script event"
|
|
);
|
|
|
|
// Make a request that the extension will proxy once it is started.
|
|
let request = Promise.all([
|
|
extension.awaitMessage("saw-request"),
|
|
ExtensionTestUtils.fetch("http://proxied.example.com/?a=1"),
|
|
]);
|
|
|
|
await promiseExtensionEvent(extension, "background-script-event");
|
|
equal(
|
|
events.get("background-script-event"),
|
|
true,
|
|
"Should have gotten a background script event"
|
|
);
|
|
|
|
// Test the background page startup.
|
|
equal(
|
|
events.get("start-background-script"),
|
|
false,
|
|
"Should not have started the background page yet"
|
|
);
|
|
AddonTestUtils.notifyEarlyStartup();
|
|
await new Promise(executeSoon);
|
|
|
|
equal(
|
|
events.get("start-background-script"),
|
|
true,
|
|
"Should have gotten a background script event"
|
|
);
|
|
|
|
// Verify our proxied request finishes properly and that the
|
|
// request was not handled via our non-proxied server.
|
|
await request;
|
|
equal(2, proxiedRequests, "proxied request ok");
|
|
equal(2, nonProxiedRequests, "non proxied requests ok");
|
|
|
|
// Retry, but now with early_background_wakeup_on_request=true.
|
|
Services.prefs.setBoolPref(
|
|
"extensions.webextensions.early_background_wakeup_on_request",
|
|
true
|
|
);
|
|
await promiseRestartManager({ earlyStartup: false });
|
|
await extension.awaitStartup();
|
|
let request2 = Promise.all([
|
|
extension.awaitMessage("saw-request"),
|
|
ExtensionTestUtils.fetch("http://proxied.example.com/?a=2"),
|
|
]);
|
|
info("Expecting background page to be awakened by the proxy event");
|
|
await extension.awaitBackgroundStarted();
|
|
await request2;
|
|
equal(3, proxiedRequests, "proxied request ok");
|
|
|
|
await extension.unload();
|
|
|
|
await promiseShutdownManager();
|
|
});
|
|
|
|
add_task(async function webRequest_before_proxy() {
|
|
Services.prefs.setBoolPref(
|
|
"extensions.webextensions.early_background_wakeup_on_request",
|
|
true
|
|
);
|
|
await promiseStartupManager();
|
|
|
|
function background() {
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
return { redirectUrl: "data:,response_from_webRequest" };
|
|
},
|
|
{
|
|
urls: ["*://example.com/wr"],
|
|
types: ["xmlhttprequest"],
|
|
},
|
|
["blocking"]
|
|
);
|
|
browser.proxy.onRequest.addListener(
|
|
() => {
|
|
browser.test.sendMessage("seen_proxy_request");
|
|
},
|
|
{
|
|
urls: ["*://example.com/?proxy"],
|
|
types: ["xmlhttprequest"],
|
|
}
|
|
);
|
|
}
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
permissions: [
|
|
"proxy",
|
|
"webRequest",
|
|
"webRequestBlocking",
|
|
"http://example.com/*",
|
|
],
|
|
},
|
|
background,
|
|
});
|
|
await extension.startup();
|
|
let res = await ExtensionTestUtils.fetch(
|
|
"http://example.com",
|
|
"http://example.com/wr"
|
|
);
|
|
Assert.equal(res, "response_from_webRequest", "Request succeeded");
|
|
await promiseRestartManager({ earlyStartup: false });
|
|
|
|
let wrPromise = ExtensionTestUtils.fetch(
|
|
"http://example.com",
|
|
"http://example.com/wr"
|
|
);
|
|
await promiseExtensionEvent(extension, "background-script-event");
|
|
await new Promise(executeSoon);
|
|
Assert.equal(
|
|
extension.extension.backgroundState,
|
|
"stopped",
|
|
"Request intercepted by webRequest should not trigger early startup"
|
|
);
|
|
let proxyPromise = ExtensionTestUtils.fetch(
|
|
"http://example.com",
|
|
"http://example.com/?proxy"
|
|
);
|
|
await promiseExtensionEvent(extension, "background-script-event");
|
|
await new Promise(executeSoon);
|
|
Assert.notEqual(
|
|
extension.extension.backgroundState,
|
|
"stopped",
|
|
`Request intercepted by proxy.onRequest should trigger early startup`
|
|
);
|
|
info("Expecting background page to be awakened by the proxy event");
|
|
await extension.awaitBackgroundStarted();
|
|
Assert.equal(await proxyPromise, "ok", "Got /?proxy response");
|
|
Assert.equal(await wrPromise, "response_from_webRequest", "Got /wr reply");
|
|
await extension.awaitMessage("seen_proxy_request");
|
|
await extension.unload();
|
|
|
|
await promiseShutdownManager();
|
|
});
|