Bug 1834799 - [devtools] Support CORS requests for local script override r=devtools-reviewers,bomsy

Depends on D217030

Differential Revision: https://phabricator.services.mozilla.com/D217086
This commit is contained in:
Julian Descottes 2024-07-26 12:33:15 +00:00
parent 57c8aa3275
commit 724e827ac3
5 changed files with 62 additions and 6 deletions

View File

@ -63,6 +63,13 @@ function overrideChannelWithFilePath(channel, path) {
replacedHttpResponse.setResponseHeader("Content-Type", mimeType, false);
}
// Allow all cross origin requests for overrides.
replacedHttpResponse.setResponseHeader(
"Access-Control-Allow-Origin",
"*",
false
);
channel
.QueryInterface(Ci.nsIHttpChannelInternal)
.setResponseOverride(replacedHttpResponse);

View File

@ -6,6 +6,7 @@ support-files = [
"csp_script_to_override.js",
"doc_network-observer-missing-service-worker.html",
"doc_network-observer.html",
"doc_network-observer.html^headers^",
"gzipped.sjs",
"override.html",
"override.js",

View File

@ -2,11 +2,12 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
requestLongerTimeout(3);
const TEST_URL = URL_ROOT + "doc_network-observer.html";
const TEST_URL_CSP = URL_ROOT + "override_script_src_self.html";
const REQUEST_URL =
URL_ROOT + `sjs_network-observer-test-server.sjs?sts=200&fmt=html`;
URL_ROOT + `sjs_network-observer-test-server.sjs?sts=200&fmt=js`;
const CORS_REQUEST_URL = REQUEST_URL.replace("example.com", "plop.example.com");
const CSP_SCRIPT_TO_OVERRIDE = URL_ROOT + "csp_script_to_override.js";
const GZIPPED_REQUEST_URL = URL_ROOT + `gzipped.sjs`;
const OVERRIDE_FILENAME = "override.js";
@ -17,7 +18,8 @@ add_task(async function testLocalOverride() {
let eventsCount = 0;
const networkObserver = new NetworkObserver({
ignoreChannelFunction: channel => channel.URI.spec !== REQUEST_URL,
ignoreChannelFunction: channel =>
![REQUEST_URL, CORS_REQUEST_URL].includes(channel.URI.spec),
onNetworkEvent: event => {
info("received a network event");
eventsCount++;
@ -57,7 +59,7 @@ add_task(async function testLocalOverride() {
gBrowser.selectedBrowser,
[REQUEST_URL],
async _url => {
const script = await content.document.createElement("script");
const script = content.document.createElement("script");
const onLoad = new Promise(resolve =>
script.addEventListener("load", resolve, { once: true })
);
@ -72,6 +74,31 @@ add_task(async function testLocalOverride() {
}
);
info(`Assert that JS scripts with crossorigin="anonymous" can be overriden`);
networkObserver.override(CORS_REQUEST_URL, overrideFile.path);
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[CORS_REQUEST_URL],
async _url => {
content.document.title = "title before crossorigin=anonymous evaluation";
const script = content.document.createElement("script");
script.setAttribute("crossorigin", "anonymous");
script.crossOrigin = "anonymous";
const onLoad = new Promise(resolve =>
script.addEventListener("load", resolve, { once: true })
);
script.src = _url;
content.document.body.appendChild(script);
await onLoad;
is(
content.document.title,
"Override script loaded",
`The <script crossorigin="anonymous"> tag content has been overriden and correctly evaluated`
);
}
);
await BrowserTestUtils.waitForCondition(() => eventsCount >= 1);
networkObserver.destroy();
@ -158,7 +185,7 @@ add_task(async function testLocalOverrideGzipped() {
gBrowser.selectedBrowser,
[GZIPPED_REQUEST_URL],
async _url => {
const script = await content.document.createElement("script");
const script = content.document.createElement("script");
const onLoad = new Promise(resolve =>
script.addEventListener("load", resolve, { once: true })
);
@ -220,7 +247,7 @@ add_task(async function testLocalOverrideCSP() {
);
await SpecialPowers.spawn(browser, [url], async _url => {
const script = await content.document.createElement("script");
const script = content.document.createElement("script");
const onLoad = new Promise(resolve =>
script.addEventListener("load", resolve, { once: true })
);

View File

@ -0,0 +1 @@
Access-Control-Allow-Origin: *

View File

@ -32,6 +32,13 @@ function handleRequest(request, response) {
response.setHeader("Expires", Date(Date.now() + cacheExpire * 1000), false);
}
const allowCORS = params.some(s => s.startsWith("cors"));
function setCORSHeader() {
if (allowCORS) {
response.setHeader("Access-Control-Allow-Origin", "*", false);
}
}
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(
@ -75,6 +82,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "text/html; charset=utf-8", false);
setCacheHeaders();
setCORSHeader();
response.write(content || "<p>Hello HTML!</p>");
response.finish();
break;
@ -87,6 +95,7 @@ function handleRequest(request, response) {
false
);
setCacheHeaders();
setCORSHeader();
response.write("<p>Hello XHTML!</p>");
response.finish();
break;
@ -96,6 +105,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "text/html; charset=utf-8", false);
setCacheHeaders();
setCORSHeader();
response.write("<p>" + str + "</p>");
response.finish();
break;
@ -104,6 +114,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "text/css; charset=utf-8", false);
setCacheHeaders();
setCORSHeader();
response.write("body:pre { content: 'Hello CSS!' }");
response.finish();
break;
@ -116,6 +127,7 @@ function handleRequest(request, response) {
false
);
setCacheHeaders();
setCORSHeader();
response.write("function() { return 'Hello JS!'; }");
response.finish();
break;
@ -128,6 +140,7 @@ function handleRequest(request, response) {
false
);
setCacheHeaders();
setCORSHeader();
response.write('{ "greeting": "Hello JSON!" }');
response.finish();
break;
@ -137,6 +150,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "font/woff", false);
setCacheHeaders();
setCORSHeader();
response.finish();
break;
}
@ -144,6 +158,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "image/png", false);
setCacheHeaders();
setCORSHeader();
response.finish();
break;
}
@ -151,6 +166,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "application/ogg", false);
setCacheHeaders();
setCORSHeader();
response.finish();
break;
}
@ -158,6 +174,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "audio/ogg", false);
setCacheHeaders();
setCORSHeader();
response.finish();
break;
}
@ -165,6 +182,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "video/webm", false);
setCacheHeaders();
setCORSHeader();
response.finish();
break;
}
@ -177,6 +195,7 @@ function handleRequest(request, response) {
response.setHeader("Connection", "upgrade", false);
response.setHeader("Upgrade", "websocket", false);
setCacheHeaders();
setCORSHeader();
response.finish();
break;
}
@ -184,6 +203,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, 404, "Not Found");
response.setHeader("Content-Type", "text/html; charset=utf-8", false);
setCacheHeaders();
setCORSHeader();
response.write("<blink>Not Found</blink>");
response.finish();
break;