mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-13 22:40:01 -04:00
fix data url workers
This commit is contained in:
parent
6ea474c3d0
commit
ec0fb8b70a
5 changed files with 75 additions and 43 deletions
|
@ -85,13 +85,15 @@ impl Rewriter {
|
||||||
|
|
||||||
impl<'a> Visit<'a> for Rewriter {
|
impl<'a> Visit<'a> for Rewriter {
|
||||||
fn visit_identifier_reference(&mut self, it: &IdentifierReference<'a>) {
|
fn visit_identifier_reference(&mut self, it: &IdentifierReference<'a>) {
|
||||||
// self.jschanges.push(JsChange::GenericChange {
|
if self.config.capture_errors {
|
||||||
// span: it.span,
|
self.jschanges.push(JsChange::GenericChange {
|
||||||
// text: format!(
|
span: it.span,
|
||||||
// "({}(typeof {} == 'undefined' || {}, (()=>{{ try {{return arguments}} catch(_){{}} }})()))",
|
text: format!(
|
||||||
// self.wrapfn, it.name, it.name
|
"{}({}, typeof arguments != 'undefined' && arguments)",
|
||||||
// ),
|
self.config.wrapfn, it.name
|
||||||
// });
|
),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
if UNSAFE_GLOBALS.contains(&it.name.to_string().as_str()) {
|
if UNSAFE_GLOBALS.contains(&it.name.to_string().as_str()) {
|
||||||
self.jschanges.push(JsChange::GenericChange {
|
self.jschanges.push(JsChange::GenericChange {
|
||||||
span: it.span,
|
span: it.span,
|
||||||
|
@ -99,6 +101,7 @@ impl<'a> Visit<'a> for Rewriter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we need to rewrite `new Something` to `new (wrapfn(Something))` instead of `new wrapfn(Something)`, that's why there's weird extra code here
|
// we need to rewrite `new Something` to `new (wrapfn(Something))` instead of `new wrapfn(Something)`, that's why there's weird extra code here
|
||||||
fn visit_new_expression(&mut self, it: &oxc_ast::ast::NewExpression<'a>) {
|
fn visit_new_expression(&mut self, it: &oxc_ast::ast::NewExpression<'a>) {
|
||||||
|
|
|
@ -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", {
|
client.Trap("document.documentURI", {
|
||||||
get() {
|
get() {
|
||||||
return decodeUrl(self.location.href);
|
return decodeUrl(self.location.href);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { encodeUrl, rewriteHeaders } from "../../../shared";
|
import { decodeUrl, encodeUrl, rewriteHeaders } from "../../../shared";
|
||||||
|
|
||||||
export default function (client, self) {
|
export default function (client, self) {
|
||||||
client.Proxy("XMLHttpRequest.prototype.open", {
|
client.Proxy("XMLHttpRequest.prototype.open", {
|
||||||
|
@ -15,4 +15,10 @@ export default function (client, self) {
|
||||||
ctx.args = Object.entries(headerObject)[0];
|
ctx.args = Object.entries(headerObject)[0];
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
client.Trap("XMLHttpRequest.prototype.responseURL", {
|
||||||
|
get(ctx) {
|
||||||
|
return decodeUrl(ctx.get());
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { encodeUrl, BareMuxConnection } from "../../shared";
|
import { encodeUrl, BareMuxConnection } from "../../shared";
|
||||||
|
import type { MessageC2W } from "../../worker";
|
||||||
import { ScramjetClient } from "../client";
|
import { ScramjetClient } from "../client";
|
||||||
|
|
||||||
export default function (client: ScramjetClient, self: typeof globalThis) {
|
export default function (client: ScramjetClient, self: typeof globalThis) {
|
||||||
|
@ -6,27 +7,28 @@ export default function (client: ScramjetClient, self: typeof globalThis) {
|
||||||
construct({ args, call }) {
|
construct({ args, call }) {
|
||||||
if (args[0] instanceof URL) args[0] = args[0].href;
|
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].startsWith("data:")) {
|
||||||
if (args[0].startsWith("blob:")) {
|
let data = syncfetch(client, args[0]);
|
||||||
args[0] =
|
let id = Math.random().toString(8).slice(5);
|
||||||
"data:application/javascript;base64," +
|
|
||||||
btoa(syncfetch(client, args[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
args[0] = "/scramjet/worker?data=" + args[0];
|
args[0] = "/scramjet/worker?id=" + id;
|
||||||
if (args[1] && args[1].type === "module") {
|
if (args[1] && args[1].type === "module") {
|
||||||
args[0] += "&type=module";
|
args[0] += "&type=module";
|
||||||
}
|
}
|
||||||
|
|
||||||
args[0] += "&origin=" + encodeURIComponent(client.url.origin);
|
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") {
|
if (args[1] && args[1].type === "module") {
|
||||||
args[0] += "&type=module";
|
args[0] += "&type=module";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const worker = call();
|
const worker = call();
|
||||||
const conn = new BareMuxConnection();
|
const conn = new BareMuxConnection();
|
||||||
|
|
|
@ -17,6 +17,11 @@ export class ScramjetServiceWorker {
|
||||||
|
|
||||||
serviceWorkers: FakeServiceWorker[] = [];
|
serviceWorkers: FakeServiceWorker[] = [];
|
||||||
|
|
||||||
|
dataworkerpromises: Record<
|
||||||
|
string,
|
||||||
|
{ promise: Promise<string>; resolve: (v: string) => void }
|
||||||
|
> = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.client = new self.$scramjet.shared.util.BareClient();
|
this.client = new self.$scramjet.shared.util.BareClient();
|
||||||
|
|
||||||
|
@ -35,8 +40,17 @@ export class ScramjetServiceWorker {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const resolve = this.syncPool[data.scramjet$token];
|
if (data.scramjet$type === "dataworker") {
|
||||||
// delete this.syncPool[data.scramjet$token];
|
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) {
|
async fetch({ request, clientId }: FetchEvent) {
|
||||||
if (new URL(request.url).pathname.startsWith("/scramjet/worker")) {
|
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 type = new URL(request.url).searchParams.get("type");
|
||||||
const res = await fetch(dataurl);
|
|
||||||
const ab = await res.arrayBuffer();
|
|
||||||
|
|
||||||
const origin = new URL(
|
const origin = new URL(
|
||||||
decodeURIComponent(new URL(request.url).searchParams.get("origin"))
|
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, {
|
return new Response(rewritten, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -148,12 +174,21 @@ type CookieMessage = {
|
||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type DataWorkerMessage = {
|
||||||
|
scramjet$type: "dataworker";
|
||||||
|
data: string;
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
type MessageCommon = {
|
type MessageCommon = {
|
||||||
scramjet$type: string;
|
scramjet$type: string;
|
||||||
scramjet$token: number;
|
scramjet$token: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type MessageTypeC2W = RegisterServiceWorkerMessage | CookieMessage;
|
type MessageTypeC2W =
|
||||||
|
| RegisterServiceWorkerMessage
|
||||||
|
| CookieMessage
|
||||||
|
| DataWorkerMessage;
|
||||||
type MessageTypeW2C = CookieMessage;
|
type MessageTypeW2C = CookieMessage;
|
||||||
|
|
||||||
// c2w: client to (service) worker
|
// c2w: client to (service) worker
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue