Add handler for file upload and download
Some checks are pending
Lint / lint (push) Waiting to run
Test & Build / test (push) Waiting to run

This commit is contained in:
Tims777 2024-09-28 13:32:09 +02:00
parent 2aa363fb11
commit 7ba432faa9
2 changed files with 27 additions and 28 deletions

View File

@ -30,9 +30,10 @@ const port =
app.use(express.static("public")); app.use(express.static("public"));
app.use(bodyParser.raw()); app.use(bodyParser.raw({ limit: "10mb" }));
app.use("/scene/:id", restHandler("scene")); app.use("/scene/*", restHandler("scene"));
app.use("/file/*", restHandler("file"));
app.get("/", (req, res) => { app.get("/", (req, res) => {
res.send("Excalidraw collaboration server is up :)"); res.send("Excalidraw collaboration server is up :)");

View File

@ -1,77 +1,75 @@
import type { RequestHandler } from "express"; import type { RequestHandler } from "express";
interface Scene { interface Resource {
hash: string; hash: string;
data: ArrayBuffer; data: ArrayBuffer;
} }
export function restHandler(_resourceName: string): RequestHandler { export function restHandler(_resName: string): RequestHandler {
const scenes: Record<string, Scene> = {}; const resources: Record<string, Resource> = {};
const _put: RequestHandler = (req, res, next) => { const _put: RequestHandler = (req, res, next) => {
const sceneId = req.params.id; const resId = req.params[0];
const newSceneData = req.body as ArrayBuffer; const newData = req.body as ArrayBuffer;
const newSceneHash = req.header("ETag"); const newHash = req.header("ETag");
const oldSceneHash = req.header("If-Match"); const oldHash = req.header("If-Match");
console.log(oldSceneHash, newSceneHash, newSceneData);
if (!newSceneHash || !newSceneData) { if (!newHash || !newData) {
res.status(400).send("Data or hash not provided."); res.status(400).send("Data or hash not provided.");
return; return;
} }
if (scenes[sceneId] && scenes[sceneId].hash != oldSceneHash) { if (resources[resId] && resources[resId].hash != oldHash) {
res.status(409).send("Hash mismatch. Update denied."); res.status(409).send("Hash mismatch. Update denied.");
return; return;
} }
scenes[sceneId] = { resources[resId] = {
hash: newSceneHash, hash: newHash,
data: newSceneData, data: newData,
}; };
res.status(200).send(`Scene with ID ${sceneId} has been upserted.`); res.status(200).send(`Resource with ID ${resId} has been upserted.`);
next(); next();
}; };
const _get: RequestHandler = (req, res, next) => { const _get: RequestHandler = (req, res, next) => {
const sceneId = req.params.id; const resId = req.params[0];
const oldSceneHash = req.header("If-None-Match"); const oldHash = req.header("If-None-Match");
if (!scenes[sceneId]) { if (!resources[resId]) {
res.status(404).send("Not found."); res.status(404).send("Not found.");
return; return;
} }
if (scenes[sceneId] && scenes[sceneId].hash == oldSceneHash) { if (resources[resId] && resources[resId].hash == oldHash) {
res.status(304).send("Not modified."); res.status(304).send("Not modified.");
return; return;
} }
// TODO: Respect If-None-Match header // TODO: Respect If-None-Match header
const scene = scenes[sceneId]; const resource = resources[resId];
res.header("ETag", scene.hash).header("Content-Type", "application/octet-stream"); res.header("ETag", resource.hash).header("Content-Type", "application/octet-stream");
res.status(200).send(scene.data); res.status(200).send(resource.data);
next(); next();
}; };
const _options: RequestHandler = (req, res, next) => { const _options: RequestHandler = (req, res, next) => {
const sceneId = req.params.id; const resId = req.params[0];
delete scenes[sceneId]; delete resources[resId];
res.status(200).end(); res.status(200).end();
next(); next();
}; };
const _delete: RequestHandler = (req, res, next) => { const _delete: RequestHandler = (req, res, next) => {
const sceneId = req.params.id; const resId = req.params[0];
delete scenes[sceneId]; delete resources[resId];
res.status(200).end(); res.status(200).end();
next(); next();
}; };
return (req, res, next) => { return (req, res, next) => {
const id = req.params.id;
res.header("Access-Control-Allow-Origin", process.env.CORS_ORIGIN || "*"); res.header("Access-Control-Allow-Origin", process.env.CORS_ORIGIN || "*");
res.header("Access-Control-Allow-Methods", "GET, PUT, DELETE, OPTIONS"); res.header("Access-Control-Allow-Methods", "GET, PUT, DELETE, OPTIONS");
res.header("Access-Control-Allow-Headers", "Content-Type, ETag, If-Match, If-None-Match"); res.header("Access-Control-Allow-Headers", "Content-Type, ETag, If-Match, If-None-Match");