mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-13 22:40:01 -04:00
fix postmessage shit
This commit is contained in:
parent
6cccf1f412
commit
d011d73a80
6 changed files with 44 additions and 36 deletions
|
@ -46,7 +46,7 @@ export class ScramjetClient {
|
||||||
windowProxy: any;
|
windowProxy: any;
|
||||||
locationProxy: any;
|
locationProxy: any;
|
||||||
|
|
||||||
eventcallbacks: WeakMap<
|
eventcallbacks: Map<
|
||||||
any,
|
any,
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,7 @@ export class ScramjetClient {
|
||||||
proxiedCallback: AnyFunction;
|
proxiedCallback: AnyFunction;
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
> = new WeakMap();
|
> = new Map();
|
||||||
|
|
||||||
constructor(public global: typeof globalThis) {
|
constructor(public global: typeof globalThis) {
|
||||||
if ("document" in self) {
|
if ("document" in self) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { encodeUrl } from "../shared";
|
import { encodeUrl } from "../shared";
|
||||||
import { ScramjetClient } from "../client";
|
import { ScramjetClient } from "../client";
|
||||||
|
import { type MessageC2W } from "../../worker";
|
||||||
|
|
||||||
// we need a late order because we're mangling with addEventListener at a higher level
|
// we need a late order because we're mangling with addEventListener at a higher level
|
||||||
export const order = 2;
|
export const order = 2;
|
||||||
|
@ -47,7 +48,8 @@ export default function (client: ScramjetClient, self: Self) {
|
||||||
{
|
{
|
||||||
scramjet$type: "registerServiceWorker",
|
scramjet$type: "registerServiceWorker",
|
||||||
port: handle,
|
port: handle,
|
||||||
},
|
origin: client.url.origin,
|
||||||
|
} as MessageC2W,
|
||||||
[handle]
|
[handle]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,9 @@ if (!(ScramjetClient.SCRAMJET in self)) {
|
||||||
const client = new ScramjetClient(self);
|
const client = new ScramjetClient(self);
|
||||||
client.hook();
|
client.hook();
|
||||||
|
|
||||||
if (issw) {
|
if (
|
||||||
|
new URL(self.location.href).searchParams.get("dest") === "serviceworker"
|
||||||
|
) {
|
||||||
const runtime = new ScramjetServiceWorkerRuntime(client);
|
const runtime = new ScramjetServiceWorkerRuntime(client);
|
||||||
runtime.hook();
|
runtime.hook();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,32 +3,30 @@ import { encodeUrl } from "./shared";
|
||||||
|
|
||||||
export class ScramjetServiceWorkerRuntime {
|
export class ScramjetServiceWorkerRuntime {
|
||||||
constructor(public client: ScramjetClient) {
|
constructor(public client: ScramjetClient) {
|
||||||
addEventListener("connect", (cevent: MessageEvent) => {
|
// @ts-ignore
|
||||||
|
self.onconnect = (cevent: MessageEvent) => {
|
||||||
const port = cevent.ports[0];
|
const port = cevent.ports[0];
|
||||||
|
|
||||||
port.addEventListener("message", (event) => {
|
port.addEventListener("message", (event) => {
|
||||||
if ("scramjet$type" in event.data) {
|
if ("scramjet$type" in event.data) {
|
||||||
handleMessage(client, event.data, port);
|
handleMessage(client, event.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
port.start();
|
port.start();
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
hook() {}
|
hook() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMessage(
|
function handleMessage(client: ScramjetClient, data: MessageW2R) {
|
||||||
client: ScramjetClient,
|
const port = data.scramjet$port;
|
||||||
data: MessageW2R,
|
|
||||||
port: MessagePort
|
|
||||||
) {
|
|
||||||
const type = data.scramjet$type;
|
const type = data.scramjet$type;
|
||||||
const token = data.scramjet$token;
|
const token = data.scramjet$token;
|
||||||
|
|
||||||
if (type === "fetch") {
|
if (type === "fetch") {
|
||||||
const fetchhandlers = client.eventcallbacks.get("fetch");
|
const fetchhandlers = client.eventcallbacks.get(self);
|
||||||
if (!fetchhandlers) return;
|
if (!fetchhandlers) return;
|
||||||
|
|
||||||
for (const handler of fetchhandlers) {
|
for (const handler of fetchhandlers) {
|
||||||
|
@ -37,24 +35,21 @@ function handleMessage(
|
||||||
body: request.body,
|
body: request.body,
|
||||||
headers: new Headers(request.headers),
|
headers: new Headers(request.headers),
|
||||||
method: request.method,
|
method: request.method,
|
||||||
mode: request.mode,
|
mode: "same-origin",
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.defineProperty(fakeRequest, "destination", {
|
Object.defineProperty(fakeRequest, "destination", {
|
||||||
value: request.destinitation,
|
value: request.destinitation,
|
||||||
});
|
});
|
||||||
|
|
||||||
const fakeFetchEvent = new FetchEvent("fetch", {
|
// TODO: clean up, maybe put into a class
|
||||||
request: fakeRequest,
|
const fakeFetchEvent: any = new Event("fetch");
|
||||||
});
|
fakeFetchEvent.request = fakeRequest;
|
||||||
|
|
||||||
fakeFetchEvent.respondWith = async (
|
fakeFetchEvent.respondWith = async (
|
||||||
response: Response | Promise<Response>
|
response: Response | Promise<Response>
|
||||||
) => {
|
) => {
|
||||||
response = await response;
|
response = await response;
|
||||||
|
const message: MessageR2W = {
|
||||||
response.body;
|
|
||||||
port.postMessage({
|
|
||||||
scramjet$type: "fetch",
|
scramjet$type: "fetch",
|
||||||
scramjet$token: token,
|
scramjet$token: token,
|
||||||
scramjet$response: {
|
scramjet$response: {
|
||||||
|
@ -63,7 +58,9 @@ function handleMessage(
|
||||||
status: response.status,
|
status: response.status,
|
||||||
statusText: response.statusText,
|
statusText: response.statusText,
|
||||||
},
|
},
|
||||||
} as MessageR2W);
|
};
|
||||||
|
|
||||||
|
port.postMessage(message, [response.body]);
|
||||||
};
|
};
|
||||||
|
|
||||||
handler.proxiedCallback(trustEvent(fakeFetchEvent));
|
handler.proxiedCallback(trustEvent(fakeFetchEvent));
|
||||||
|
@ -76,7 +73,7 @@ function trustEvent(event: Event): Event {
|
||||||
get(target, prop, reciever) {
|
get(target, prop, reciever) {
|
||||||
if (prop === "isTrusted") return true;
|
if (prop === "isTrusted") return true;
|
||||||
|
|
||||||
return Reflect.get(target, prop, reciever);
|
return Reflect.get(target, prop);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -118,4 +115,5 @@ type MessageCommon = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MessageR2W = MessageCommon & MessageTypeR2W;
|
export type MessageR2W = MessageCommon & MessageTypeR2W;
|
||||||
export type MessageW2R = MessageCommon & MessageTypeW2R;
|
export type MessageW2R = MessageCommon &
|
||||||
|
MessageTypeW2R & { scramjet$port: MessagePort };
|
||||||
|
|
|
@ -3,18 +3,18 @@ import { type MessageW2R, type MessageR2W } from "../client/swruntime";
|
||||||
export class FakeServiceWorker {
|
export class FakeServiceWorker {
|
||||||
syncToken = 0;
|
syncToken = 0;
|
||||||
promises: Record<number, (val?: MessageR2W) => void> = {};
|
promises: Record<number, (val?: MessageR2W) => void> = {};
|
||||||
|
messageChannel = new MessageChannel();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public handle: MessagePort,
|
public handle: MessagePort,
|
||||||
public origin: string
|
public origin: string
|
||||||
) {
|
) {
|
||||||
this.handle.start();
|
this.messageChannel.port1.addEventListener("message", (event) => {
|
||||||
|
|
||||||
this.handle.addEventListener("message", (event) => {
|
|
||||||
if ("scramjet$type" in event.data) {
|
if ("scramjet$type" in event.data) {
|
||||||
this.handleMessage(event.data);
|
this.handleMessage(event.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.messageChannel.port1.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMessage(data: MessageR2W) {
|
handleMessage(data: MessageR2W) {
|
||||||
|
@ -31,6 +31,7 @@ export class FakeServiceWorker {
|
||||||
const message: MessageW2R = {
|
const message: MessageW2R = {
|
||||||
scramjet$type: "fetch",
|
scramjet$type: "fetch",
|
||||||
scramjet$token: token,
|
scramjet$token: token,
|
||||||
|
scramjet$port: this.messageChannel.port2,
|
||||||
scramjet$request: {
|
scramjet$request: {
|
||||||
url: request.url,
|
url: request.url,
|
||||||
body: request.body,
|
body: request.body,
|
||||||
|
@ -41,7 +42,10 @@ export class FakeServiceWorker {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
this.handle.postMessage(message);
|
const transfer: any = request.body ? [request.body] : [];
|
||||||
|
transfer.push(this.messageChannel.port2);
|
||||||
|
|
||||||
|
this.handle.postMessage(message, transfer);
|
||||||
|
|
||||||
const { scramjet$response: r } = (await new Promise((resolve) => {
|
const { scramjet$response: r } = (await new Promise((resolve) => {
|
||||||
this.promises[token] = resolve;
|
this.promises[token] = resolve;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import IDBMap from "@webreflection/idb-map";
|
||||||
import { ParseResultType } from "parse-domain";
|
import { ParseResultType } from "parse-domain";
|
||||||
import { ScramjetServiceWorker } from ".";
|
import { ScramjetServiceWorker } from ".";
|
||||||
import { renderError } from "./error";
|
import { renderError } from "./error";
|
||||||
|
import { FakeServiceWorker } from "./fakesw";
|
||||||
|
|
||||||
const { encodeUrl, decodeUrl } = self.$scramjet.shared.url;
|
const { encodeUrl, decodeUrl } = self.$scramjet.shared.url;
|
||||||
const { rewriteHeaders, rewriteHtml, rewriteJs, rewriteCss, rewriteWorkers } =
|
const { rewriteHeaders, rewriteHtml, rewriteJs, rewriteCss, rewriteWorkers } =
|
||||||
|
@ -35,14 +36,6 @@ export async function swfetch(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeWorker = this.serviceWorkers.find(
|
|
||||||
(w) => w.origin === new URL(request.url).origin
|
|
||||||
);
|
|
||||||
if (activeWorker) {
|
|
||||||
// TODO: check scope
|
|
||||||
return await activeWorker.fetch(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
const urlParam = new URLSearchParams(new URL(request.url).search);
|
const urlParam = new URLSearchParams(new URL(request.url).search);
|
||||||
|
|
||||||
if (urlParam.has("url")) {
|
if (urlParam.has("url")) {
|
||||||
|
@ -53,6 +46,15 @@ export async function swfetch(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = new URL(decodeUrl(request.url));
|
const url = new URL(decodeUrl(request.url));
|
||||||
|
|
||||||
|
const activeWorker: FakeServiceWorker | null = this.serviceWorkers.find(
|
||||||
|
(w) => w.origin === url.origin
|
||||||
|
);
|
||||||
|
|
||||||
|
if (activeWorker) {
|
||||||
|
// TODO: check scope
|
||||||
|
return await activeWorker.fetch(request);
|
||||||
|
}
|
||||||
if (url.origin == new URL(request.url).origin) {
|
if (url.origin == new URL(request.url).origin) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"attempted to fetch from same origin - this means the site has obtained a reference to the real origin, aborting"
|
"attempted to fetch from same origin - this means the site has obtained a reference to the real origin, aborting"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue