ScramjetHandleResponseEvent

This commit is contained in:
velzie 2024-10-10 20:53:06 -04:00
parent 41288749e4
commit e2c3d3d651
2 changed files with 38 additions and 19 deletions

View file

@ -1,4 +1,4 @@
import { BareResponseFetch } from "@mercuryworkshop/bare-mux"; import { BareHeaders, 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 { MessageW2C, ScramjetServiceWorker } from "."; import { MessageW2C, ScramjetServiceWorker } from ".";
@ -17,6 +17,7 @@ import {
} from "../shared"; } from "../shared";
import type { URLMeta } from "../shared/rewriters/url"; import type { URLMeta } from "../shared/rewriters/url";
import { Readable } from "stream";
function newmeta(url: URL): URLMeta { function newmeta(url: URL): URLMeta {
return { return {
@ -28,13 +29,13 @@ function newmeta(url: URL): URLMeta {
export async function swfetch( export async function swfetch(
this: ScramjetServiceWorker, this: ScramjetServiceWorker,
request: Request, request: Request,
client: Client | null client: Client | null,
) { ) {
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")) {
return Response.redirect( return Response.redirect(
encodeUrl(urlParam.get("url"), newmeta(new URL(urlParam.get("url")))) encodeUrl(urlParam.get("url"), newmeta(new URL(urlParam.get("url")))),
); );
} }
@ -51,7 +52,7 @@ export async function swfetch(
const url = new URL(decodeUrl(requesturl)); 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,
); );
if ( if (
@ -65,7 +66,7 @@ export async function swfetch(
} }
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",
); );
} }
@ -81,7 +82,7 @@ export async function swfetch(
// TODO: i was against cors emulation but we might actually break stuff if we send full origin/referrer always // TODO: i was against cors emulation but we might actually break stuff if we send full origin/referrer always
const url = new URL(decodeUrl(client.url)); const url = new URL(decodeUrl(client.url));
if (url.toString().includes("youtube.com")) { if (url.toString().includes("youtube.com")) {
console.log(headers); // console.log(headers);
} else { } else {
headers.set("Referer", url.toString()); headers.set("Referer", url.toString());
headers.set("Origin", url.origin); headers.set("Origin", url.origin);
@ -117,7 +118,8 @@ export async function swfetch(
request.destination, request.destination,
response, response,
this.cookieStore, this.cookieStore,
client client,
this,
); );
} catch (err) { } catch (err) {
console.error("ERROR FROM SERVICE WORKER FETCH", err); console.error("ERROR FROM SERVICE WORKER FETCH", err);
@ -134,7 +136,8 @@ async function handleResponse(
destination: RequestDestination, destination: RequestDestination,
response: BareResponseFetch, response: BareResponseFetch,
cookieStore: CookieStore, cookieStore: CookieStore,
client: Client client: Client,
swtarget: ScramjetServiceWorker,
): Promise<Response> { ): Promise<Response> {
let responseBody: string | ArrayBuffer | ReadableStream; let responseBody: string | ArrayBuffer | ReadableStream;
const responseHeaders = rewriteHeaders(response.rawHeaders, newmeta(url)); const responseHeaders = rewriteHeaders(response.rawHeaders, newmeta(url));
@ -151,7 +154,7 @@ async function handleResponse(
await cookieStore.setCookies( await cookieStore.setCookies(
maybeHeaders instanceof Array ? maybeHeaders : [maybeHeaders], maybeHeaders instanceof Array ? maybeHeaders : [maybeHeaders],
url url,
); );
for (const header in responseHeaders) { for (const header in responseHeaders) {
@ -169,7 +172,7 @@ async function handleResponse(
await response.text(), await response.text(),
cookieStore, cookieStore,
newmeta(url), newmeta(url),
true true,
); );
} else { } else {
responseBody = response.body; responseBody = response.body;
@ -188,7 +191,7 @@ async function handleResponse(
responseBody = rewriteWorkers( responseBody = rewriteWorkers(
await response.arrayBuffer(), await response.arrayBuffer(),
workertype, workertype,
newmeta(url) newmeta(url),
); );
break; break;
default: default:
@ -237,9 +240,23 @@ async function handleResponse(
responseHeaders["Cross-Origin-Opener-Policy"] = "same-origin"; responseHeaders["Cross-Origin-Opener-Policy"] = "same-origin";
} }
return new Response(responseBody, { const ev = new ScramjetHandleResponseEvent("handleResponse");
headers: responseHeaders as HeadersInit, ev.responseBody = responseBody;
status: response.status, ev.responseHeaders = responseHeaders;
statusText: response.statusText, ev.status = response.status;
ev.statusText = response.statusText;
swtarget.dispatchEvent(ev);
return new Response(ev.responseBody, {
headers: ev.responseHeaders as HeadersInit,
status: ev.status,
statusText: ev.statusText,
}); });
} }
export class ScramjetHandleResponseEvent extends Event {
public responseHeaders: Record<string, string>;
public responseBody: string | ArrayBuffer | ReadableStream;
public status: number;
public statusText: string;
}

View file

@ -5,7 +5,7 @@ import { ScramjetThreadpool } from "./threadpool";
import type BareClient from "@mercuryworkshop/bare-mux"; import type BareClient from "@mercuryworkshop/bare-mux";
import { rewriteWorkers } from "../shared"; import { rewriteWorkers } from "../shared";
export class ScramjetServiceWorker { export class ScramjetServiceWorker extends EventTarget {
client: BareClient; client: BareClient;
config: typeof self.$scramjet.config; config: typeof self.$scramjet.config;
threadpool: ScramjetThreadpool; threadpool: ScramjetThreadpool;
@ -23,6 +23,7 @@ export class ScramjetServiceWorker {
> = {}; > = {};
constructor() { constructor() {
super();
this.client = new self.$scramjet.shared.util.BareClient(); this.client = new self.$scramjet.shared.util.BareClient();
this.threadpool = new ScramjetThreadpool(); this.threadpool = new ScramjetThreadpool();
@ -75,7 +76,7 @@ export class ScramjetServiceWorker {
clients = clients.filter( clients = clients.filter(
(client) => (client) =>
client.type === "window" && client.type === "window" &&
!new URL(client.url).pathname.startsWith(this.config.prefix) !new URL(client.url).pathname.startsWith(this.config.prefix),
); );
if (clients.length === 0) throw new Error("No clients found"); if (clients.length === 0) throw new Error("No clients found");
@ -98,7 +99,7 @@ export class ScramjetServiceWorker {
clients = clients.filter( clients = clients.filter(
(client) => (client) =>
client.type === "window" && client.type === "window" &&
!new URL(client.url).pathname.startsWith(this.config.prefix) !new URL(client.url).pathname.startsWith(this.config.prefix),
); );
if (clients.length === 0) throw new Error("No clients found"); if (clients.length === 0) throw new Error("No clients found");
@ -129,7 +130,7 @@ export class ScramjetServiceWorker {
const type = new URL(request.url).searchParams.get("type"); const type = new URL(request.url).searchParams.get("type");
const origin = new URL( const origin = new URL(
decodeURIComponent(new URL(request.url).searchParams.get("origin")) decodeURIComponent(new URL(request.url).searchParams.get("origin")),
); );
let promise = this.dataworkerpromises[id]; let promise = this.dataworkerpromises[id];
@ -155,6 +156,7 @@ export class ScramjetServiceWorker {
"Content-Type": "application/javascript", "Content-Type": "application/javascript",
}; };
// this is broken on firefox
if (crossOriginIsolated) { if (crossOriginIsolated) {
headers["Cross-Origin-Opener-Policy"] = "same-origin"; headers["Cross-Origin-Opener-Policy"] = "same-origin";
headers["Cross-Origin-Embedder-Policy"] = "require-corp"; headers["Cross-Origin-Embedder-Policy"] = "require-corp";