summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js289
1 files changed, 289 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js
new file mode 100644
index 0000000000..f8116aced0
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_suspend.js
@@ -0,0 +1,289 @@
+"use strict";
+
+const HOSTS = new Set(["example.com"]);
+
+const server = createHttpServer({ hosts: HOSTS });
+
+const BASE_URL = "http://example.com";
+const FETCH_ORIGIN = "http://example.com/dummy";
+
+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));
+});
+
+server.registerPathHandler("/dummy", (request, response) => {
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.write("ok");
+});
+
+add_task(async function test_suspend() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["webRequest", "webRequestBlocking", `${BASE_URL}/`],
+ },
+
+ background() {
+ browser.webRequest.onBeforeSendHeaders.addListener(
+ details => {
+ // Make sure that returning undefined or a promise that resolves to
+ // undefined does not break later handlers.
+ },
+ { urls: ["<all_urls>"] },
+ ["blocking", "requestHeaders"]
+ );
+
+ browser.webRequest.onBeforeSendHeaders.addListener(
+ details => {
+ return Promise.resolve();
+ },
+ { urls: ["<all_urls>"] },
+ ["blocking", "requestHeaders"]
+ );
+
+ browser.webRequest.onBeforeSendHeaders.addListener(
+ details => {
+ let requestHeaders = details.requestHeaders.concat({
+ name: "Foo",
+ value: "Bar",
+ });
+
+ return new Promise(resolve => {
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ setTimeout(resolve, 500);
+ }).then(() => {
+ return { requestHeaders };
+ });
+ },
+ { urls: ["<all_urls>"] },
+ ["blocking", "requestHeaders"]
+ );
+ },
+ });
+
+ await extension.startup();
+
+ let headers = JSON.parse(
+ await ExtensionTestUtils.fetch(
+ FETCH_ORIGIN,
+ `${BASE_URL}/return_headers.sjs`
+ )
+ );
+
+ equal(
+ headers.foo,
+ "Bar",
+ "Request header was correctly set on suspended request"
+ );
+
+ await extension.unload();
+});
+
+// Test that requests that were canceled while suspended for a blocking
+// listener are correctly resumed.
+add_task(async function test_error_resume() {
+ let observer = channel => {
+ if (
+ channel instanceof Ci.nsIHttpChannel &&
+ channel.URI.spec === "http://example.com/dummy"
+ ) {
+ Services.obs.removeObserver(observer, "http-on-before-connect");
+
+ // Wait until the next tick to make sure this runs after WebRequest observers.
+ Promise.resolve().then(() => {
+ channel.cancel(Cr.NS_BINDING_ABORTED);
+ });
+ }
+ };
+
+ Services.obs.addObserver(observer, "http-on-before-connect");
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["webRequest", "webRequestBlocking", `${BASE_URL}/`],
+ },
+
+ background() {
+ browser.webRequest.onBeforeSendHeaders.addListener(
+ details => {
+ browser.test.log(`onBeforeSendHeaders({url: ${details.url}})`);
+
+ if (details.url === "http://example.com/dummy") {
+ browser.test.sendMessage("got-before-send-headers");
+ }
+ },
+ { urls: ["<all_urls>"] },
+ ["blocking"]
+ );
+
+ browser.webRequest.onErrorOccurred.addListener(
+ details => {
+ browser.test.log(`onErrorOccurred({url: ${details.url}})`);
+
+ if (details.url === "http://example.com/dummy") {
+ browser.test.sendMessage("got-error-occurred");
+ }
+ },
+ { urls: ["<all_urls>"] }
+ );
+ },
+ });
+
+ await extension.startup();
+
+ try {
+ await ExtensionTestUtils.fetch(FETCH_ORIGIN, `${BASE_URL}/dummy`);
+ ok(false, "Fetch should have failed.");
+ } catch (e) {
+ ok(true, "Got expected error.");
+ }
+
+ await extension.awaitMessage("got-before-send-headers");
+ await extension.awaitMessage("got-error-occurred");
+
+ // Wait for the next tick so the onErrorRecurred response can be
+ // processed before shutting down the extension.
+ await new Promise(resolve => executeSoon(resolve));
+
+ await extension.unload();
+});
+
+// Test that response header modifications take effect before onStartRequest fires.
+add_task(async function test_set_responseHeaders() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["webRequest", "webRequestBlocking", "http://example.com/"],
+ },
+
+ background() {
+ browser.webRequest.onHeadersReceived.addListener(
+ details => {
+ browser.test.log(`onHeadersReceived({url: ${details.url}})`);
+
+ details.responseHeaders.push({ name: "foo", value: "bar" });
+
+ return { responseHeaders: details.responseHeaders };
+ },
+ { urls: ["http://example.com/?modify_headers"] },
+ ["blocking", "responseHeaders"]
+ );
+ },
+ });
+
+ await extension.startup();
+
+ await new Promise(resolve => setTimeout(resolve, 0));
+
+ let resolveHeaderPromise;
+ let headerPromise = new Promise(resolve => {
+ resolveHeaderPromise = resolve;
+ });
+ {
+ let ssm = Services.scriptSecurityManager;
+
+ let channel = NetUtil.newChannel({
+ uri: "http://example.com/?modify_headers",
+ loadingPrincipal:
+ ssm.createContentPrincipalFromOrigin("http://example.com"),
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_XMLHTTPREQUEST,
+ securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ });
+
+ channel.asyncOpen({
+ QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
+
+ onStartRequest(request) {
+ request.QueryInterface(Ci.nsIHttpChannel);
+
+ try {
+ resolveHeaderPromise(request.getResponseHeader("foo"));
+ } catch (e) {
+ resolveHeaderPromise(null);
+ }
+ request.cancel(Cr.NS_BINDING_ABORTED);
+ },
+
+ onStopRequest() {},
+
+ onDataAvailable() {
+ throw new Components.Exception("", Cr.NS_ERROR_FAILURE);
+ },
+ });
+ }
+
+ let headerValue = await headerPromise;
+ equal(headerValue, "bar", "Expected Foo header value");
+
+ await extension.unload();
+});
+
+// Test that exceptions raised from a blocking webRequest listener that returns
+// a promise are logged as expected.
+add_task(async function test_logged_error_on_promise_result() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["webRequest", "webRequestBlocking", `${BASE_URL}/`],
+ },
+
+ background() {
+ async function onBeforeRequest() {
+ throw new Error("Expected webRequest exception from a promise result");
+ }
+
+ let exceptionRaised = false;
+
+ browser.webRequest.onBeforeRequest.addListener(
+ () => {
+ if (exceptionRaised) {
+ return;
+ }
+
+ // We only need to raise the exception once.
+ exceptionRaised = true;
+ return onBeforeRequest();
+ },
+ {
+ urls: ["http://example.com/*"],
+ types: ["main_frame"],
+ },
+ ["blocking"]
+ );
+
+ browser.webRequest.onBeforeRequest.addListener(
+ () => {
+ browser.test.sendMessage("web-request-event-received");
+ },
+ {
+ urls: ["http://example.com/*"],
+ types: ["main_frame"],
+ },
+ ["blocking"]
+ );
+ },
+ });
+
+ let { messages } = await promiseConsoleOutput(async () => {
+ await extension.startup();
+
+ let contentPage = await ExtensionTestUtils.loadContentPage(
+ `${BASE_URL}/dummy`
+ );
+ await extension.awaitMessage("web-request-event-received");
+ await contentPage.close();
+ });
+
+ ok(
+ messages.some(msg =>
+ /Expected webRequest exception from a promise result/.test(msg.message)
+ ),
+ "Got expected console message"
+ );
+
+ await extension.unload();
+});