"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; } // 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: [""] } ); } 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 have gotten a background script event" ); 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"); await extension.unload(); await promiseShutdownManager(); });