loled/loled.js

111 lines
2.7 KiB
JavaScript
Executable File

#!/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 = 200
} else {
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 });