mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-14 06:50:01 -04:00
fix html rewriting and add header rewriting
This commit is contained in:
parent
b8ee2ef53e
commit
2002eab48c
6 changed files with 80 additions and 11 deletions
|
@ -20,7 +20,6 @@
|
|||
"no-useless-return": "error",
|
||||
"no-shadow": "error",
|
||||
"prefer-const": "warn",
|
||||
"prefer-reflect": "warn",
|
||||
"no-unreachable": "warn",
|
||||
"no-undef": "off"
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { encodeUrl, decodeUrl } from "./rewriters/url";
|
|||
import { rewriteCss } from "./rewriters/css";
|
||||
import { rewriteHtml, rewriteSrcset } from "./rewriters/html";
|
||||
import { rewriteJs } from "./rewriters/js";
|
||||
import { rewriteHeaders } from "./rewriters/headers";
|
||||
|
||||
const bundle = {
|
||||
rewriters: {
|
||||
|
@ -11,7 +12,8 @@ const bundle = {
|
|||
rewriteCss,
|
||||
rewriteHtml,
|
||||
rewriteSrcset,
|
||||
rewriteJs
|
||||
rewriteJs,
|
||||
rewriteHeaders
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import { encodeUrl } from "./url";
|
||||
|
||||
const cspHeaders = [
|
||||
"cross-origin-embedder-policy",
|
||||
"cross-origin-opener-policy",
|
||||
"cross-origin-resource-policy",
|
||||
"content-security-policy",
|
||||
"content-security-policy-report-only",
|
||||
"expect-ct",
|
||||
"feature-policy",
|
||||
"origin-isolation",
|
||||
"strict-transport-security",
|
||||
"upgrade-insecure-requests",
|
||||
"x-content-type-options",
|
||||
"x-download-options",
|
||||
"x-frame-options",
|
||||
"x-permitted-cross-domain-policies",
|
||||
"x-powered-by",
|
||||
"x-xss-protection",
|
||||
];
|
||||
|
||||
const urlHeaders = [
|
||||
"location",
|
||||
"content-location",
|
||||
"referer"
|
||||
];
|
||||
|
||||
export function rewriteHeaders(headers: Headers, origin?: string) {
|
||||
cspHeaders.forEach((header) => {
|
||||
if (headers.has(header)) {
|
||||
headers.delete(header);
|
||||
}
|
||||
});
|
||||
|
||||
urlHeaders.forEach((header) => {
|
||||
if (headers.has(header)) {
|
||||
headers.set(header, encodeUrl(headers.get(header), origin));
|
||||
}
|
||||
});
|
||||
|
||||
if (headers.has("link")) {
|
||||
let link = headers.get("link");
|
||||
|
||||
link = link.replace(/<(.*?)>/g, (match, g1) => {
|
||||
return `<${encodeUrl(g1, origin)}>`;
|
||||
});
|
||||
|
||||
headers.set("link", link);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import { hasAttrib, getAttributeValue } from "domutils";
|
|||
import render from "dom-serializer";
|
||||
import { encodeUrl } from "./url";
|
||||
import { rewriteCss } from "./css";
|
||||
import { rewriteJs } from "./js";
|
||||
|
||||
// html nodes to rewrite
|
||||
// meta
|
||||
|
@ -18,9 +19,10 @@ export function rewriteHtml(html: string, origin?: string) {
|
|||
return render(traverseParsedHtml(handler.root, origin));
|
||||
}
|
||||
|
||||
// typescript error hell
|
||||
// the code still works but the types provided from domhandler are shit
|
||||
function traverseParsedHtml(node: any, origin?: string) {
|
||||
function traverseParsedHtml(node, origin?: string) {
|
||||
// apparently nonce is a global attribute so i'll just delete it at the beginning of the file
|
||||
delete node.attribs.nonce;
|
||||
|
||||
if (node.name === "a" && hasAttrib(node, "href")) {
|
||||
node.attribs.href = encodeUrl(node.attribs.href, origin);
|
||||
} else if (node.name === "iframe") {
|
||||
|
@ -31,12 +33,25 @@ function traverseParsedHtml(node: any, origin?: string) {
|
|||
if (hasAttrib(node, "srcdoc")) {
|
||||
node.attribs.srcdoc = rewriteHtml(node.attribs.srcdoc, origin);
|
||||
}
|
||||
|
||||
if (hasAttrib(node, "csp")) {
|
||||
delete node.attribs.csp;
|
||||
}
|
||||
} else if (node.name === "link") {
|
||||
delete node.attribs.integrity;
|
||||
|
||||
node.attribs.href = encodeUrl(node.attribs.href, origin);
|
||||
|
||||
if (hasAttrib(node, "imagesrcset")) {
|
||||
node.attribs.imagesrcset = rewriteSrcset(node.attribs.imagesrcset);
|
||||
}
|
||||
|
||||
console.log(node.attribs.href)
|
||||
} else if (node.name === "style") {
|
||||
node.children[0].data = rewriteCss(node.children[0].data, origin);
|
||||
} else if (node.name === "script") {
|
||||
delete node.attribs.integrity;
|
||||
|
||||
if (hasAttrib(node, "type") && /(application|text)\/javascript|importmap/.test(getAttributeValue(node, "type"))) {
|
||||
if (hasAttrib(node, "src")) {
|
||||
node.attribs.src = encodeUrl(node.attribs.src, origin);
|
||||
|
@ -44,7 +59,7 @@ function traverseParsedHtml(node: any, origin?: string) {
|
|||
}
|
||||
}
|
||||
|
||||
// implement js rewriting when done
|
||||
node.children[0].data = rewriteJs(node.children[0].data, origin);
|
||||
} else if (node.name === "img" && hasAttrib(node, "src")) {
|
||||
if (hasAttrib(node, "src")) {
|
||||
node.attribs.src = encodeUrl(node.attribs.src, origin);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { rewriteJs } from "./js";
|
||||
|
||||
function canParseUrl(url: string, origin?: string) {
|
||||
if (URL.canParse) {
|
||||
console.log(URL.canParse(url, origin) + "\n" + url + "\n" + origin);
|
||||
|
@ -21,14 +23,11 @@ export function encodeUrl(url: string, origin?: string) {
|
|||
// }
|
||||
|
||||
if (url.startsWith("javascript:")) {
|
||||
// implement when js rewriting is done
|
||||
return url;
|
||||
return "javascript:" + rewriteJs(url.slice("javascript:".length));
|
||||
} else if (/^(#|mailto|about|data)/.test(url)) {
|
||||
return url;
|
||||
} else if (canParseUrl(url, origin)) {
|
||||
console.log(self.__scramjet$config.prefix + self.__scramjet$config.codec.encode(new URL(url, origin).href));
|
||||
|
||||
return self.__scramjet$config.prefix + self.__scramjet$config.codec.encode(new URL(url, origin).href);
|
||||
return location.origin + self.__scramjet$config.prefix + self.__scramjet$config.codec.encode(new URL(url, origin).href);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ self.ScramjetServiceWorker = class ScramjetServiceWorker {
|
|||
async fetch(event: FetchEvent) {
|
||||
const url = new URL(self.__scramjet$bundle.rewriters.url.decodeUrl(event.request.url));
|
||||
|
||||
self.__scramjet$bundle.rewriters.rewriteHeaders(event.request.headers)
|
||||
|
||||
// implement header rewriting later
|
||||
const response = await this.client.fetch(url, {
|
||||
method: event.request.method,
|
||||
|
@ -26,6 +28,8 @@ self.ScramjetServiceWorker = class ScramjetServiceWorker {
|
|||
headers: event.request.headers
|
||||
});
|
||||
|
||||
self.__scramjet$bundle.rewriters.rewriteHeaders(response.headers);
|
||||
|
||||
let responseBody;
|
||||
|
||||
if (event.request.destination === "document") {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue