import { BurpaDriver } from "../Engine/types.js"; import { Request, Response } from "../Independents/Datagram/datagram-types.js"; import { CBurpastateWrapper } from "../Engine/burpastate.js" import { CResponse } from "../Independents/Datagram/datagram.js" import { Vagrant } from "../Engine/host.js" import { parseContentType } from "../Independents/util/misc.js" export const browserDriver: BurpaDriver = { async initialize(state: CBurpastateWrapper): Promise { if (!_installed) { _installed = true; // let host = Burpanet.localHost let host = state.findLocalHost(state.whole.persistent.localHost ?? "") as Vagrant; let dh = state.addVagrant_Old("document", { onRequest: (request: Request) => { return "hello" } }); // host.addChild("document", "", state.whole.persistent.localGateway); } }, async externalFetch(ssl: boolean, request: Request): Promise { let url = `${ssl ? "https" : "http"}://${request.to}${request.path}`; console.warn(`EXTERNAL FETCH ${request.method} ${url}`); let headers: { [key: string]: string } = { ...request.headers }; if (request.port !== "default") { headers["port"] == request.port; } let init = { method: request.method, headers, body: request.body }; let resp = await fetch(url, init); let ctyp = parseContentType(resp.headers.get("content-type")); let body: any; switch (ctyp) { case "application/json": body = await resp.json(); break; case "text/plain": body = await resp.text(); break; default: body = await resp.blob(); } let response = new CResponse({ body, status: resp.status }, request); return Promise.resolve(response); }, isSocketOpen(socket: WebSocket): boolean { return socket.readyState === socket.OPEN }, socketSend(socket: WebSocket, message: Uint8Array): boolean { // if (Math.random() > 0.3) { // return false; // } if (!this.isSocketOpen(socket)) { console.warn("SOCKET IS CLOSED!"); return false; } try { socket.send(message); } catch (e) { console.warn(`Error sending on websocket`, e); return false; } return true; }, createSocket(url: string, messageListener: (message: ArrayBuffer) => void, onOpen: (socket: any) => void, onError: (socket: any, cause: string) => void): any { let socket: any; try { socket = new WebSocket(url); socket.binaryType = "arraybuffer"; socket.onopen = (ev: Event) => { onOpen(socket) } socket.onerror = (ev: Event) => { onError(socket, "error"); //console.warn(`Cannot spawn host as parent host ${ url } is unavailable.`); } socket.onmessage = (event: MessageEvent) => { let message = event.data; if (!(message instanceof ArrayBuffer)) { throw `Need data as binary.Got ${typeof (message)}` } else { // console.log("Received data on socket", event.data); } messageListener(message); } } catch { } return socket; }, socketStatus(socket: WebSocket): string { let status = socket.readyState; if (status == socket.OPEN) { return "open"; } if (status == socket.CLOSED) { return "closed"; } if (status == socket.CLOSING) { return "closing"; } if (status == socket.CONNECTING) { return "connecting"; } return "error"; } } let _installed = false; function findElem(request: Request): HTMLElement | null { if (request.path.startsWith("/document?")) { let params = new URLSearchParams(request.path.split("?")[1]); let selector = params.get("selector"); let id = params.get("id"); if (selector) { return document.querySelector(selector); } else if (id) { return document.getElementById(id); } } if (request.path.startsWith("/document/")) { let id = request.path.substr("/document/".length); return document.getElementById(id); } return null; }