#!/bin/env -S deno run --allow-net --allow-env --allow-read=. import { Application, Router } from "https://deno.land/x/oak/mod.ts"; let router = new Router() let displayIndex = 0; let display = null; router.get("/_loled/display/register", (ctx) => { if(ctx.request.ip != "127.0.0.1"){ ctx.response.status = 403 ctx.response.body = "Only local machine is allowed to register a display" return; } let name = ctx.request.url.searchParams.get("name"); if(!name){ name = "display-"+displayIndex } displayIndex++; const target = ctx.sendEvents(); display = { name, sse: target } target.dispatchMessage({ type: "welcome", name }); }); router.post("/_loled/grab-display",async (ctx) => { const bdy = await ctx.request.body({type: "json"}).value; if(display){ display.sse.dispatchMessage({ type: "offer", offer: bdy.offer, iceCandidates: bdy.iceCandidates }); const answr = await new Promise((res, rej) => { const timeout = setTimeout(() => { rej(new Error("Timeout")) delete display.putAnswer }, 10000) display.putAnswer = (answr) => { clearTimeout(timeout) delete display.putAnswer res(answr) } }) ctx.response.type = "application/json" ctx.response.body = JSON.stringify(answr) } else { ctx.response.status = 404 ctx.response.body = "No display available" } }) router.post("/_loled/display/put-answer", async (ctx) => { const bdy = await ctx.request.body({type: "json"}).value; if(display){ if(display.putAnswer){ display.putAnswer(bdy) ctx.response.status = 200 } else { ctx.response.status = 404 ctx.response.body = "No offer pending" } } else { ctx.response.status = 404 ctx.response.body = "No display available" } }); const app = new Application(); // CORS app.use((ctx, next) => { ctx.response.headers.append("Access-Control-Allow-Methods", "POST, GET, OPTIONS") ctx.response.headers.append("Access-Control-Allow-Origin", "*") ctx.response.headers.append("Access-Control-Max-Age", "3600") ctx.response.headers.append("Access-Control-Allow-Headers", "*") if(ctx.request.method == "OPTION"){ ctx.response.status = 204 } else { return next() } }) app.use((ctx, next) => { if(ctx.request.url.pathname.startsWith("/_loled")){ ctx.response.headers.append("Cache-Control", "no-store") } return next() }) // Static app.use(async (ctx, next) => { if(ctx.request.url.pathname.startsWith("/_loled")) return next() try { await ctx.send({ root: `${Deno.cwd()}/static`, index: "index.html", path: ctx.request.url.pathname }); } catch { ctx.response.status = 404 ctx.response.body = "Not found" } }) app.use(router.routes()) app.use(router.allowedMethods()) await app.listen({ port: Deno.env.get("PORT") || 80 });