fix data url workers

This commit is contained in:
velzie 2024-08-31 18:26:17 -04:00
parent 6ea474c3d0
commit ec0fb8b70a
No known key found for this signature in database
GPG key ID: 048413F95F0DDE1F
5 changed files with 75 additions and 43 deletions

View file

@ -85,18 +85,21 @@ impl Rewriter {
impl<'a> Visit<'a> for Rewriter {
fn visit_identifier_reference(&mut self, it: &IdentifierReference<'a>) {
// self.jschanges.push(JsChange::GenericChange {
// span: it.span,
// text: format!(
// "({}(typeof {} == 'undefined' || {}, (()=>{{ try {{return arguments}} catch(_){{}} }})()))",
// self.wrapfn, it.name, it.name
// ),
// });
if UNSAFE_GLOBALS.contains(&it.name.to_string().as_str()) {
if self.config.capture_errors {
self.jschanges.push(JsChange::GenericChange {
span: it.span,
text: format!("{}({})", self.config.wrapfn, it.name),
text: format!(
"{}({}, typeof arguments != 'undefined' && arguments)",
self.config.wrapfn, it.name
),
});
} else {
if UNSAFE_GLOBALS.contains(&it.name.to_string().as_str()) {
self.jschanges.push(JsChange::GenericChange {
span: it.span,
text: format!("{}({})", self.config.wrapfn, it.name),
});
}
}
}

View file

@ -20,20 +20,6 @@ export default function (client: ScramjetClient, self: typeof window) {
},
});
client.Trap("document.baseURI", {
get() {
const base = self.document.querySelector("base");
if (base) {
return new URL(base.href, client.url).href;
}
return client.url.href;
},
set() {
return false;
},
});
client.Trap("document.documentURI", {
get() {
return decodeUrl(self.location.href);

View file

@ -1,4 +1,4 @@
import { encodeUrl, rewriteHeaders } from "../../../shared";
import { decodeUrl, encodeUrl, rewriteHeaders } from "../../../shared";
export default function (client, self) {
client.Proxy("XMLHttpRequest.prototype.open", {
@ -15,4 +15,10 @@ export default function (client, self) {
ctx.args = Object.entries(headerObject)[0];
},
});
client.Trap("XMLHttpRequest.prototype.responseURL", {
get(ctx) {
return decodeUrl(ctx.get());
},
});
}

View file

@ -1,4 +1,5 @@
import { encodeUrl, BareMuxConnection } from "../../shared";
import type { MessageC2W } from "../../worker";
import { ScramjetClient } from "../client";
export default function (client: ScramjetClient, self: typeof globalThis) {
@ -6,26 +7,27 @@ export default function (client: ScramjetClient, self: typeof globalThis) {
construct({ args, call }) {
if (args[0] instanceof URL) args[0] = args[0].href;
if (args[0].startsWith("blob:") || args[0].startsWith("data:")) {
if (args[0].startsWith("blob:")) {
args[0] =
"data:application/javascript;base64," +
btoa(syncfetch(client, args[0]));
}
let data = syncfetch(client, args[0]);
let id = Math.random().toString(8).slice(5);
args[0] = "/scramjet/worker?data=" + args[0];
args[0] = "/scramjet/worker?id=" + id;
if (args[1] && args[1].type === "module") {
args[0] += "&type=module";
}
args[0] += "&origin=" + encodeURIComponent(client.url.origin);
return;
}
client.serviceWorker.controller?.postMessage({
scramjet$type: "dataworker",
data,
id,
} as MessageC2W);
} else {
args[0] = encodeUrl(args[0]) + "?dest=worker";
args[0] = encodeUrl(args[0]) + "?dest=worker";
if (args[1] && args[1].type === "module") {
args[0] += "&type=module";
if (args[1] && args[1].type === "module") {
args[0] += "&type=module";
}
}
const worker = call();

View file

@ -17,6 +17,11 @@ export class ScramjetServiceWorker {
serviceWorkers: FakeServiceWorker[] = [];
dataworkerpromises: Record<
string,
{ promise: Promise<string>; resolve: (v: string) => void }
> = {};
constructor() {
this.client = new self.$scramjet.shared.util.BareClient();
@ -35,8 +40,17 @@ export class ScramjetServiceWorker {
return;
}
// const resolve = this.syncPool[data.scramjet$token];
// delete this.syncPool[data.scramjet$token];
if (data.scramjet$type === "dataworker") {
if (this.dataworkerpromises[data.id]) {
this.dataworkerpromises[data.id].resolve(data.data);
} else {
let resolve: (v: string) => void;
const promise = new Promise<string>((res) => (resolve = res));
this.dataworkerpromises[data.id] = { promise, resolve };
resolve(data.data);
}
return;
}
});
}
@ -110,16 +124,28 @@ export class ScramjetServiceWorker {
async fetch({ request, clientId }: FetchEvent) {
if (new URL(request.url).pathname.startsWith("/scramjet/worker")) {
const dataurl = new URL(request.url).searchParams.get("data");
const id = new URL(request.url).searchParams.get("id");
const type = new URL(request.url).searchParams.get("type");
const res = await fetch(dataurl);
const ab = await res.arrayBuffer();
const origin = new URL(
decodeURIComponent(new URL(request.url).searchParams.get("origin"))
);
const rewritten = rewriteWorkers(ab, type, new URL(origin));
let promise = this.dataworkerpromises[id];
if (!promise) {
let resolve: (v: string) => void;
promise = {
promise: new Promise<string>((res) => (resolve = res)),
resolve,
};
promise.resolve = resolve;
this.dataworkerpromises[id] = promise;
}
const data = await promise.promise;
delete this.dataworkerpromises[id];
const rewritten = rewriteWorkers(data, type, new URL(origin));
return new Response(rewritten, {
headers: {
@ -148,12 +174,21 @@ type CookieMessage = {
url: string;
};
type DataWorkerMessage = {
scramjet$type: "dataworker";
data: string;
id: string;
};
type MessageCommon = {
scramjet$type: string;
scramjet$token: number;
};
type MessageTypeC2W = RegisterServiceWorkerMessage | CookieMessage;
type MessageTypeC2W =
| RegisterServiceWorkerMessage
| CookieMessage
| DataWorkerMessage;
type MessageTypeW2C = CookieMessage;
// c2w: client to (service) worker