From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../test/xpcshell/test_ext_permission_xhr.js | 240 +++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_permission_xhr.js (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_permission_xhr.js') diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_permission_xhr.js b/toolkit/components/extensions/test/xpcshell/test_ext_permission_xhr.js new file mode 100644 index 0000000000..88afd36dcc --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_permission_xhr.js @@ -0,0 +1,240 @@ +"use strict"; + +// This file tests the behavior of fetch/XMLHttpRequest in content scripts, in +// relation to permissions, in MV2. +// In MV3, the expectations are different, test coverage for that is in +// test_ext_xhr_cors.js (along with CORS tests that also apply to MV2). + +const server = createHttpServer({ + hosts: ["xpcshell.test", "example.com", "example.org"], +}); +server.registerDirectory("/data/", do_get_file("data")); + +server.registerPathHandler("/example.txt", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write("ok"); +}); + +server.registerPathHandler("/return_headers.sjs", (request, response) => { + response.setHeader("Content-Type", "text/plain", false); + + let headers = {}; + for (let { data: header } of request.headers) { + headers[header.toLowerCase()] = request.getHeader(header); + } + + response.write(JSON.stringify(headers)); +}); + +/* eslint-disable mozilla/balanced-listeners */ + +add_task(async function test_simple() { + async function runTests(cx) { + function xhr(XMLHttpRequest) { + return url => { + return new Promise((resolve, reject) => { + let req = new XMLHttpRequest(); + req.open("GET", url); + req.addEventListener("load", resolve); + req.addEventListener("error", reject); + req.send(); + }); + }; + } + + function run(shouldFail, fetch) { + function passListener() { + browser.test.succeed(`${cx}.${fetch.name} pass listener`); + } + + function failListener() { + browser.test.fail(`${cx}.${fetch.name} fail listener`); + } + + /* eslint-disable no-else-return */ + if (shouldFail) { + return fetch("http://example.org/example.txt").then( + failListener, + passListener + ); + } else { + return fetch("http://example.com/example.txt").then( + passListener, + failListener + ); + } + /* eslint-enable no-else-return */ + } + + try { + await run(true, xhr(XMLHttpRequest)); + await run(false, xhr(XMLHttpRequest)); + await run(true, xhr(window.XMLHttpRequest)); + await run(false, xhr(window.XMLHttpRequest)); + await run(true, fetch); + await run(false, fetch); + await run(true, window.fetch); + await run(false, window.fetch); + } catch (err) { + browser.test.fail(`Error: ${err} :: ${err.stack}`); + browser.test.notifyFail("permission_xhr"); + } + } + + async function background(runTestsFn) { + await runTestsFn("bg"); + browser.test.notifyPass("permission_xhr"); + } + + let extensionData = { + background: `(${background})(${runTests})`, + manifest: { + permissions: ["http://example.com/"], + content_scripts: [ + { + matches: ["http://xpcshell.test/data/file_permission_xhr.html"], + js: ["content.js"], + }, + ], + }, + files: { + "content.js": `(${async runTestsFn => { + await runTestsFn("content"); + + window.wrappedJSObject.privilegedFetch = fetch; + window.wrappedJSObject.privilegedXHR = XMLHttpRequest; + + window.addEventListener("message", function rcv({ data }) { + switch (data.msg) { + case "test": + break; + + case "assertTrue": + browser.test.assertTrue(data.condition, data.description); + break; + + case "finish": + window.removeEventListener("message", rcv); + browser.test.sendMessage("content-script-finished"); + break; + } + }); + window.postMessage("test", "*"); + }})(${runTests})`, + }, + }; + + let extension = ExtensionTestUtils.loadExtension(extensionData); + await extension.startup(); + + let contentPage = await ExtensionTestUtils.loadContentPage( + "http://xpcshell.test/data/file_permission_xhr.html" + ); + await extension.awaitMessage("content-script-finished"); + await contentPage.close(); + + await extension.awaitFinish("permission_xhr"); + await extension.unload(); +}); + +// This test case ensures that a WebExtension content script can still use the same +// XMLHttpRequest and fetch APIs that the webpage can use and be recognized from +// the target server with the same origin and referer headers of the target webpage +// (see Bug 1295660 for a rationale). +add_task(async function test_page_xhr() { + async function contentScript() { + const content = this.content; + + const { webpageFetchResult, webpageXhrResult } = await new Promise( + resolve => { + const listenPageMessage = event => { + if (!event.data || event.data.type !== "testPageGlobals") { + return; + } + + window.removeEventListener("message", listenPageMessage); + + browser.test.assertEq( + true, + !!content.XMLHttpRequest, + "The content script should have access to content.XMLHTTPRequest" + ); + browser.test.assertEq( + true, + !!content.fetch, + "The content script should have access to window.pageFetch" + ); + + resolve(event.data); + }; + + window.addEventListener("message", listenPageMessage); + + window.postMessage({}, "*"); + } + ); + + const url = new URL("/return_headers.sjs", location).href; + + await Promise.all([ + new Promise((resolve, reject) => { + const req = new content.XMLHttpRequest(); + req.open("GET", url); + req.addEventListener("load", () => + resolve(JSON.parse(req.responseText)) + ); + req.addEventListener("error", reject); + req.send(); + }), + content.fetch(url).then(res => res.json()), + ]) + .then(async ([xhrResult, fetchResult]) => { + browser.test.assertEq( + webpageFetchResult.referer, + fetchResult.referer, + "window.pageFetch referrer is the same of a webpage fetch request" + ); + browser.test.assertEq( + webpageFetchResult.origin, + fetchResult.origin, + "window.pageFetch origin is the same of a webpage fetch request" + ); + + browser.test.assertEq( + webpageXhrResult.referer, + xhrResult.referer, + "content.XMLHttpRequest referrer is the same of a webpage fetch request" + ); + }) + .catch(error => { + browser.test.fail(`Unexpected error: ${error}`); + }); + + browser.test.notifyPass("content-script-page-xhr"); + } + + let extensionData = { + manifest: { + content_scripts: [ + { + matches: ["http://xpcshell.test/*"], + js: ["content.js"], + }, + ], + }, + files: { + "content.js": `(${contentScript})()`, + }, + }; + + let extension = ExtensionTestUtils.loadExtension(extensionData); + await extension.startup(); + + let contentPage = await ExtensionTestUtils.loadContentPage( + "http://xpcshell.test/data/file_page_xhr.html" + ); + await extension.awaitFinish("content-script-page-xhr"); + await contentPage.close(); + + await extension.unload(); +}); -- cgit v1.2.3