forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			279 lines
		
	
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			279 lines
		
	
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* eslint-env webextensions */
 | |
| "use strict";
 | |
| 
 | |
| const PRINT_POSTDATA = httpURL("print_postdata.sjs");
 | |
| const FILE_DUMMY = fileURL("dummy_page.html");
 | |
| const DATA_URL = "data:text/html,Hello%2C World!";
 | |
| const DATA_STRING = "Hello, World!";
 | |
| 
 | |
| async function performLoad(browser, opts, action) {
 | |
|   let loadedPromise = BrowserTestUtils.browserLoaded(
 | |
|     browser,
 | |
|     false,
 | |
|     opts.url,
 | |
|     opts.maybeErrorPage
 | |
|   );
 | |
|   await action();
 | |
|   await loadedPromise;
 | |
| }
 | |
| 
 | |
| const EXTENSION_DATA = {
 | |
|   manifest: {
 | |
|     name: "Simple extension test",
 | |
|     version: "1.0",
 | |
|     manifest_version: 2,
 | |
|     description: "",
 | |
| 
 | |
|     permissions: ["proxy", "webRequest", "webRequestBlocking", "<all_urls>"],
 | |
|   },
 | |
| 
 | |
|   files: {
 | |
|     "dummy.html": "<html>webext dummy</html>",
 | |
|     "redirect.html": "<html>webext redirect</html>",
 | |
|   },
 | |
| 
 | |
|   extUrl: "",
 | |
| 
 | |
|   async background() {
 | |
|     browser.test.log("background script running");
 | |
|     browser.webRequest.onAuthRequired.addListener(
 | |
|       async details => {
 | |
|         browser.test.log("webRequest onAuthRequired");
 | |
| 
 | |
|         // A blocking request that returns a promise exercises a codepath that
 | |
|         // sets the notificationCallbacks on the channel to a JS object that we
 | |
|         // can't do directly QueryObject on with expected results.
 | |
|         // This triggered a crash which was fixed in bug 1528188.
 | |
|         return new Promise((resolve, reject) => {
 | |
|           setTimeout(resolve, 0);
 | |
|         });
 | |
|       },
 | |
|       { urls: ["*://*/*"] },
 | |
|       ["blocking"]
 | |
|     );
 | |
|     browser.webRequest.onBeforeRequest.addListener(
 | |
|       async details => {
 | |
|         browser.test.log("webRequest onBeforeRequest");
 | |
|         let isRedirect =
 | |
|           details.originUrl == browser.runtime.getURL("redirect.html") &&
 | |
|           details.url.endsWith("print_postdata.sjs");
 | |
|         let url = this.extUrl ? this.extUrl : details.url + "?redirected";
 | |
|         return isRedirect ? { redirectUrl: url } : {};
 | |
|       },
 | |
|       { urls: ["*://*/*"] },
 | |
|       ["blocking"]
 | |
|     );
 | |
|     browser.test.onMessage.addListener(async ({ method, url }) => {
 | |
|       if (method == "setRedirectUrl") {
 | |
|         this.extUrl = url;
 | |
|       }
 | |
|       browser.test.sendMessage("done");
 | |
|     });
 | |
|   },
 | |
| };
 | |
| 
 | |
| async function withExtensionDummy(callback) {
 | |
|   let extension = ExtensionTestUtils.loadExtension(EXTENSION_DATA);
 | |
|   await extension.startup();
 | |
|   let rv = await callback(`moz-extension://${extension.uuid}/`, extension);
 | |
|   await extension.unload();
 | |
|   return rv;
 | |
| }
 | |
| 
 | |
| async function postFrom(start, target) {
 | |
|   return BrowserTestUtils.withNewTab(
 | |
|     {
 | |
|       gBrowser,
 | |
|       url: start,
 | |
|     },
 | |
|     async function (browser) {
 | |
|       info("Test tab ready: postFrom " + start);
 | |
| 
 | |
|       // Create the form element in our loaded URI.
 | |
|       await SpecialPowers.spawn(browser, [{ target }], function ({ target }) {
 | |
|         content.document.body.innerHTML = `
 | |
|         <form method="post" action="${target}">
 | |
|           <input type="text" name="initialRemoteType" value="${Services.appinfo.remoteType}">
 | |
|           <input type="submit" id="submit">
 | |
|         </form>`;
 | |
|       });
 | |
| 
 | |
|       // Perform a form POST submit load.
 | |
|       info("Performing POST submission");
 | |
|       await performLoad(
 | |
|         browser,
 | |
|         {
 | |
|           url(url) {
 | |
|             let enable =
 | |
|               url.startsWith(PRINT_POSTDATA) ||
 | |
|               url == target ||
 | |
|               url == DATA_URL;
 | |
|             if (!enable) {
 | |
|               info(`url ${url} is invalid to perform load`);
 | |
|             }
 | |
|             return enable;
 | |
|           },
 | |
|           maybeErrorPage: true,
 | |
|         },
 | |
|         async () => {
 | |
|           await SpecialPowers.spawn(browser, [], () => {
 | |
|             content.document.querySelector("#submit").click();
 | |
|           });
 | |
|         }
 | |
|       );
 | |
| 
 | |
|       // Check that the POST data was submitted.
 | |
|       info("Fetching results");
 | |
|       return SpecialPowers.spawn(browser, [], () => {
 | |
|         return {
 | |
|           remoteType: Services.appinfo.remoteType,
 | |
|           location: "" + content.location.href,
 | |
|           body: content.document.body.textContent,
 | |
|         };
 | |
|       });
 | |
|     }
 | |
|   );
 | |
| }
 | |
| 
 | |
| async function loadAndGetProcessID(browser, target) {
 | |
|   info(`Performing GET load: ${target}`);
 | |
|   await performLoad(
 | |
|     browser,
 | |
|     {
 | |
|       maybeErrorPage: true,
 | |
|     },
 | |
|     () => {
 | |
|       BrowserTestUtils.startLoadingURIString(browser, target);
 | |
|     }
 | |
|   );
 | |
| 
 | |
|   info(`Navigated to: ${target}`);
 | |
|   browser = gBrowser.selectedBrowser;
 | |
|   let processID = await SpecialPowers.spawn(browser, [], () => {
 | |
|     return Services.appinfo.processID;
 | |
|   });
 | |
|   return processID;
 | |
| }
 | |
| 
 | |
| async function testLoadAndRedirect(
 | |
|   target,
 | |
|   expectedProcessSwitch,
 | |
|   testRedirect
 | |
| ) {
 | |
|   let start = httpURL(`dummy_page.html`);
 | |
|   return BrowserTestUtils.withNewTab(
 | |
|     {
 | |
|       gBrowser,
 | |
|       url: start,
 | |
|     },
 | |
|     async function (_browser) {
 | |
|       info("Test tab ready: getFrom " + start);
 | |
| 
 | |
|       let browser = gBrowser.selectedBrowser;
 | |
|       let firstProcessID = await SpecialPowers.spawn(browser, [], () => {
 | |
|         return Services.appinfo.processID;
 | |
|       });
 | |
| 
 | |
|       info(`firstProcessID: ${firstProcessID}`);
 | |
| 
 | |
|       let secondProcessID = await loadAndGetProcessID(browser, target);
 | |
| 
 | |
|       info(`secondProcessID: ${secondProcessID}`);
 | |
|       Assert.equal(firstProcessID != secondProcessID, expectedProcessSwitch);
 | |
| 
 | |
|       if (!testRedirect) {
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       let thirdProcessID = await loadAndGetProcessID(browser, add307(target));
 | |
| 
 | |
|       info(`thirdProcessID: ${thirdProcessID}`);
 | |
|       Assert.equal(firstProcessID != thirdProcessID, expectedProcessSwitch);
 | |
|       Assert.ok(secondProcessID == thirdProcessID);
 | |
|     }
 | |
|   );
 | |
| }
 | |
| 
 | |
| add_task(async function test_enabled() {
 | |
|   // Force only one webIsolated content process to ensure same-origin loads
 | |
|   // always end in the same process.
 | |
|   await SpecialPowers.pushPrefEnv({
 | |
|     set: [["dom.ipc.processCount.webIsolated", 1]],
 | |
|   });
 | |
| 
 | |
|   // URIs should correctly switch processes & the POST
 | |
|   // should succeed.
 | |
|   info("ENABLED -- FILE -- raw URI load");
 | |
|   let resp = await postFrom(FILE_DUMMY, PRINT_POSTDATA);
 | |
|   ok(E10SUtils.isWebRemoteType(resp.remoteType), "process switch");
 | |
|   is(resp.location, PRINT_POSTDATA, "correct location");
 | |
|   is(resp.body, "initialRemoteType=file", "correct POST body");
 | |
| 
 | |
|   info("ENABLED -- FILE -- 307-redirect URI load");
 | |
|   let resp307 = await postFrom(FILE_DUMMY, add307(PRINT_POSTDATA));
 | |
|   ok(E10SUtils.isWebRemoteType(resp307.remoteType), "process switch");
 | |
|   is(resp307.location, PRINT_POSTDATA, "correct location");
 | |
|   is(resp307.body, "initialRemoteType=file", "correct POST body");
 | |
| 
 | |
|   // Same with extensions
 | |
|   await withExtensionDummy(async extOrigin => {
 | |
|     info("ENABLED -- EXTENSION -- raw URI load");
 | |
|     let respExt = await postFrom(extOrigin + "dummy.html", PRINT_POSTDATA);
 | |
|     ok(E10SUtils.isWebRemoteType(respExt.remoteType), "process switch");
 | |
|     is(respExt.location, PRINT_POSTDATA, "correct location");
 | |
|     is(respExt.body, "initialRemoteType=extension", "correct POST body");
 | |
| 
 | |
|     info("ENABLED -- EXTENSION -- extension-redirect URI load");
 | |
|     let respExtRedirect = await postFrom(
 | |
|       extOrigin + "redirect.html",
 | |
|       PRINT_POSTDATA
 | |
|     );
 | |
|     ok(E10SUtils.isWebRemoteType(respExtRedirect.remoteType), "process switch");
 | |
|     is(
 | |
|       respExtRedirect.location,
 | |
|       PRINT_POSTDATA + "?redirected",
 | |
|       "correct location"
 | |
|     );
 | |
|     is(
 | |
|       respExtRedirect.body,
 | |
|       "initialRemoteType=extension?redirected",
 | |
|       "correct POST body"
 | |
|     );
 | |
| 
 | |
|     info("ENABLED -- EXTENSION -- 307-redirect URI load");
 | |
|     let respExt307 = await postFrom(
 | |
|       extOrigin + "dummy.html",
 | |
|       add307(PRINT_POSTDATA)
 | |
|     );
 | |
|     ok(E10SUtils.isWebRemoteType(respExt307.remoteType), "process switch");
 | |
|     is(respExt307.location, PRINT_POSTDATA, "correct location");
 | |
|     is(respExt307.body, "initialRemoteType=extension", "correct POST body");
 | |
|   });
 | |
| });
 | |
| 
 | |
| async function sendMessage(ext, method, url) {
 | |
|   ext.sendMessage({ method, url });
 | |
|   await ext.awaitMessage("done");
 | |
| }
 | |
| 
 | |
| // TODO: Currently no test framework for ftp://.
 | |
| add_task(async function test_protocol() {
 | |
|   // TODO: Processes should be switched due to navigation of different origins.
 | |
|   await testLoadAndRedirect("data:,foo", false, true);
 | |
| 
 | |
|   // Redirecting to file:// is not allowed.
 | |
|   await testLoadAndRedirect(FILE_DUMMY, true, false);
 | |
| 
 | |
|   await withExtensionDummy(async (extOrigin, extension) => {
 | |
|     await sendMessage(extension, "setRedirectUrl", DATA_URL);
 | |
| 
 | |
|     let respExtRedirect = await postFrom(
 | |
|       extOrigin + "redirect.html",
 | |
|       PRINT_POSTDATA
 | |
|     );
 | |
| 
 | |
|     ok(E10SUtils.isWebRemoteType(respExtRedirect.remoteType), "process switch");
 | |
|     is(respExtRedirect.location, DATA_URL, "correct location");
 | |
|     is(respExtRedirect.body, DATA_STRING, "correct POST body");
 | |
|   });
 | |
| });
 | 
