fetch jank

This commit is contained in:
velzie 2024-08-24 17:54:51 -04:00
parent 7014c2595d
commit 9b2acd8ab7
No known key found for this signature in database
GPG key ID: 048413F95F0DDE1F

View file

@ -1,7 +1,7 @@
import { BareResponseFetch } from "@mercuryworkshop/bare-mux"; import { BareResponseFetch } from "@mercuryworkshop/bare-mux";
import IDBMap from "@webreflection/idb-map"; import IDBMap from "@webreflection/idb-map";
import { ParseResultType } from "parse-domain"; import { ParseResultType } from "parse-domain";
import { ScramjetServiceWorker } from "."; import { MessageW2C, ScramjetServiceWorker } from ".";
import { renderError } from "./error"; import { renderError } from "./error";
import { FakeServiceWorker } from "./fakesw"; import { FakeServiceWorker } from "./fakesw";
import { CookieStore } from "../shared/cookie"; import { CookieStore } from "../shared/cookie";
@ -13,22 +13,22 @@ const { parseDomain, ScramjetHeaders } = self.$scramjet.shared.util;
export async function swfetch( export async function swfetch(
this: ScramjetServiceWorker, this: ScramjetServiceWorker,
{ request }: FetchEvent { 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 dataurl = new URL(request.url).searchParams.get("data");
const res = await fetch(dataurl); const res = await fetch(dataurl);
const ab = await res.arrayBuffer(); const ab = await res.arrayBuffer();
const ismodule = new URL(request.url).searchParams.get("type") === "module";
const origin = new URL( const origin = new URL(
decodeURIComponent(new URL(request.url).searchParams.get("origin")) decodeURIComponent(new URL(request.url).searchParams.get("origin"))
); );
if (ismodule) origin.searchParams.set("type", "module"); const rewritten = rewriteWorkers(
ab,
const rewritten = rewriteWorkers(ab, new URL(origin)); new URL(request.url).searchParams.get("type"),
new URL(origin)
);
return new Response(rewritten, { return new Response(rewritten, {
headers: { headers: {
@ -46,7 +46,16 @@ export async function swfetch(
} }
try { try {
const url = new URL(decodeUrl(request.url)); const requesturl = new URL(request.url);
let workertype = "";
if (requesturl.searchParams.has("type")) {
workertype = requesturl.searchParams.get("type") as string;
requesturl.searchParams.delete("type");
}
if (requesturl.searchParams.has("dest")) {
requesturl.searchParams.delete("dest");
}
const url = new URL(decodeUrl(requesturl));
const activeWorker: FakeServiceWorker | null = this.serviceWorkers.find( const activeWorker: FakeServiceWorker | null = this.serviceWorkers.find(
(w) => w.origin === url.origin (w) => w.origin === url.origin
@ -72,7 +81,10 @@ export async function swfetch(
headers.set(key, value); headers.set(key, value);
} }
if (new URL(request.referrer).pathname != "/") if (
URL.canParse(request.referrer) &&
new URL(request.referrer).pathname != "/"
)
headers.set("Referer", decodeUrl(request.referrer)); headers.set("Referer", decodeUrl(request.referrer));
const cookies = this.cookieStore.getCookies(url, false); const cookies = this.cookieStore.getCookies(url, false);
@ -82,14 +94,16 @@ export async function swfetch(
} }
// TODO this is wrong somehow // TODO this is wrong somehow
headers.set("Sec-Fetch-Mode", "navigate"); headers.set("Sec-Fetch-Mode", "cors");
headers.set("Sec-Fetch-Site", "same-origin"); headers.set("Sec-Fetch-Site", "same-origin");
headers.set("Sec-Fetch-Dest", "empty");
if (new URL(request.referrer).pathname != "/") if (
URL.canParse(request.referrer) &&
new URL(request.referrer).pathname != "/"
)
headers.set("Origin", new URL(request.referrer).origin); headers.set("Origin", new URL(request.referrer).origin);
dbg.log(url.toString(), headers.headers);
const response: BareResponseFetch = await this.client.fetch(url, { const response: BareResponseFetch = await this.client.fetch(url, {
method: request.method, method: request.method,
body: request.body, body: request.body,
@ -104,9 +118,11 @@ export async function swfetch(
return await handleResponse( return await handleResponse(
url, url,
workertype,
request.destination, request.destination,
response, response,
this.cookieStore this.cookieStore,
await self.clients.get(clientId)
); );
} catch (err) { } catch (err) {
console.error("ERROR FROM SERVICE WORKER FETCH", err); console.error("ERROR FROM SERVICE WORKER FETCH", err);
@ -119,17 +135,27 @@ export async function swfetch(
async function handleResponse( async function handleResponse(
url: URL, url: URL,
workertype: string,
destination: RequestDestination, destination: RequestDestination,
response: BareResponseFetch, response: BareResponseFetch,
cookieStore: CookieStore cookieStore: CookieStore,
client: Client
): Promise<Response> { ): Promise<Response> {
let responseBody: string | ArrayBuffer | ReadableStream; let responseBody: string | ArrayBuffer | ReadableStream;
const responseHeaders = rewriteHeaders(response.rawHeaders, url); const responseHeaders = rewriteHeaders(response.rawHeaders, url);
await handleCookies( let maybeHeaders = responseHeaders["set-cookie"] || [];
url, for (const cookie in maybeHeaders) {
cookieStore, client.postMessage({
(responseHeaders["set-cookie"] || []) as string[] scramjet$type: "cookie",
cookie,
url: url.href,
} as MessageW2C);
}
await cookieStore.setCookies(
maybeHeaders instanceof Array ? maybeHeaders : [maybeHeaders],
url
); );
for (const header in responseHeaders) { for (const header in responseHeaders) {
@ -158,7 +184,11 @@ async function handleResponse(
break; break;
case "sharedworker": case "sharedworker":
case "worker": case "worker":
responseBody = rewriteWorkers(await response.arrayBuffer(), url); responseBody = rewriteWorkers(
await response.arrayBuffer(),
workertype,
url
);
break; break;
default: default:
responseBody = response.body; responseBody = response.body;
@ -201,13 +231,3 @@ async function handleResponse(
statusText: response.statusText, statusText: response.statusText,
}); });
} }
async function handleCookies(
url: URL,
cookieStore: CookieStore,
maybeHeaders: string[] | string
) {
const headers = maybeHeaders instanceof Array ? maybeHeaders : [maybeHeaders];
await cookieStore.setCookies(headers, url);
}