summaryrefslogtreecommitdiffstats
path: root/toolkit/components/webextensions/test/mochitest/test_ext_webrequest_suspend.html
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/webextensions/test/mochitest/test_ext_webrequest_suspend.html')
-rw-r--r--toolkit/components/webextensions/test/mochitest/test_ext_webrequest_suspend.html216
1 files changed, 216 insertions, 0 deletions
diff --git a/toolkit/components/webextensions/test/mochitest/test_ext_webrequest_suspend.html b/toolkit/components/webextensions/test/mochitest/test_ext_webrequest_suspend.html
new file mode 100644
index 000000000..c8423ec7c
--- /dev/null
+++ b/toolkit/components/webextensions/test/mochitest/test_ext_webrequest_suspend.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for simple WebExtension</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+ <script type="text/javascript" src="head.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type="text/javascript">
+"use strict";
+
+add_task(function* test_suspend() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: [
+ "webRequest",
+ "webRequestBlocking",
+ ],
+ },
+
+ 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 => {
+ setTimeout(resolve, 500);
+ }).then(() => {
+ return {requestHeaders};
+ });
+ },
+ {urls: ["<all_urls>"]},
+ ["blocking", "requestHeaders"]);
+ },
+ });
+
+ yield extension.startup();
+
+ let result = yield fetch(SimpleTest.getTestFileURL("return_headers.sjs"));
+
+ let headers = JSON.parse(yield result.text());
+
+ is(headers.foo, "Bar", "Request header was correctly set on suspended request");
+
+ yield extension.unload();
+});
+
+
+// Test that requests that were canceled while suspended for a blocking
+// listener are correctly resumed.
+add_task(function* test_error_resume() {
+ let chromeScript = SpecialPowers.loadChromeScript(() => {
+ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+ Cu.import("resource://gre/modules/Services.jsm");
+
+ let observer = channel => {
+ if (channel instanceof Ci.nsIHttpChannel && channel.URI.spec === "http://example.com/") {
+ Services.obs.removeObserver(observer, "http-on-modify-request");
+
+ // 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-modify-request", false);
+ });
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: [
+ "webRequest",
+ "webRequestBlocking",
+ ],
+ },
+
+ background() {
+ browser.webRequest.onBeforeSendHeaders.addListener(
+ details => {
+ browser.test.log(`onBeforeSendHeaders({url: ${details.url}})`);
+
+ if (details.url === "http://example.com/") {
+ 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/") {
+ browser.test.sendMessage("got-error-occurred");
+ }
+ },
+ {urls: ["<all_urls>"]});
+ },
+ });
+
+ yield extension.startup();
+
+ try {
+ yield fetch("http://example.com/");
+ ok(false, "Fetch should have failed.");
+ } catch (e) {
+ ok(true, "Got expected error.");
+ }
+
+ yield extension.awaitMessage("got-before-send-headers");
+ yield extension.awaitMessage("got-error-occurred");
+
+ yield extension.unload();
+ chromeScript.destroy();
+});
+
+
+// Test that response header modifications take effect before onStartRequest fires.
+add_task(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"]);
+ },
+ });
+
+ yield extension.startup();
+
+ yield new Promise(resolve => setTimeout(resolve, 0));
+
+ let chromeScript = SpecialPowers.loadChromeScript(() => {
+ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+ Cu.import("resource://gre/modules/NetUtil.jsm");
+ Cu.import("resource://gre/modules/Services.jsm");
+ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+ let ssm = Services.scriptSecurityManager;
+
+ let channel = NetUtil.newChannel({
+ uri: "http://example.com/?modify_headers",
+ loadingPrincipal: ssm.createCodebasePrincipalFromOrigin("http://example.com"),
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_XMLHTTPREQUEST,
+ securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+ });
+
+ channel.asyncOpen2({
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener]),
+
+ onStartRequest(request, context) {
+ request.QueryInterface(Ci.nsIHttpChannel);
+
+ try {
+ sendAsyncMessage("response-header-foo", request.getResponseHeader("foo"));
+ } catch (e) {
+ sendAsyncMessage("response-header-foo", null);
+ }
+ request.cancel(Cr.NS_BINDING_ABORTED);
+ },
+
+ onStopRequest() {
+ },
+
+ onDataAvailable() {
+ throw new Components.Exception("", Cr.NS_ERROR_FAILURE);
+ },
+ });
+ });
+
+ let headerValue = yield chromeScript.promiseOneMessage("response-header-foo");
+ is(headerValue, "bar", "Expected Foo header value");
+
+ yield extension.unload();
+ chromeScript.destroy();
+});
+
+
+</script>
+</body>
+</html>