Add handlers for scene up- and downloads
This commit is contained in:
parent
03ff435860
commit
2aa363fb11
@ -7,6 +7,7 @@
|
|||||||
"@types/node": "14.14.31",
|
"@types/node": "14.14.31",
|
||||||
"@typescript-eslint/eslint-plugin": "4.16.1",
|
"@typescript-eslint/eslint-plugin": "4.16.1",
|
||||||
"@typescript-eslint/parser": "4.16.1",
|
"@typescript-eslint/parser": "4.16.1",
|
||||||
|
"body-parser": "^1.20.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"debug": "4.3.1",
|
"debug": "4.3.1",
|
||||||
"dotenv": "^10.0.0",
|
"dotenv": "^10.0.0",
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import debug from "debug";
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import http from "http";
|
import http from "http";
|
||||||
import { Server as SocketIO } from "socket.io";
|
import { Server as SocketIO } from "socket.io";
|
||||||
|
import { restHandler } from "./restHandler";
|
||||||
|
import bodyParser from "body-parser";
|
||||||
|
|
||||||
type UserToFollow = {
|
type UserToFollow = {
|
||||||
socketId: string;
|
socketId: string;
|
||||||
@ -28,6 +30,10 @@ const port =
|
|||||||
|
|
||||||
app.use(express.static("public"));
|
app.use(express.static("public"));
|
||||||
|
|
||||||
|
app.use(bodyParser.raw());
|
||||||
|
|
||||||
|
app.use("/scene/:id", restHandler("scene"));
|
||||||
|
|
||||||
app.get("/", (req, res) => {
|
app.get("/", (req, res) => {
|
||||||
res.send("Excalidraw collaboration server is up :)");
|
res.send("Excalidraw collaboration server is up :)");
|
||||||
});
|
});
|
||||||
|
|||||||
95
src/restHandler.ts
Normal file
95
src/restHandler.ts
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import type { RequestHandler } from "express";
|
||||||
|
|
||||||
|
interface Scene {
|
||||||
|
hash: string;
|
||||||
|
data: ArrayBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function restHandler(_resourceName: string): RequestHandler {
|
||||||
|
const scenes: Record<string, Scene> = {};
|
||||||
|
|
||||||
|
const _put: RequestHandler = (req, res, next) => {
|
||||||
|
const sceneId = req.params.id;
|
||||||
|
const newSceneData = req.body as ArrayBuffer;
|
||||||
|
const newSceneHash = req.header("ETag");
|
||||||
|
const oldSceneHash = req.header("If-Match");
|
||||||
|
console.log(oldSceneHash, newSceneHash, newSceneData);
|
||||||
|
|
||||||
|
if (!newSceneHash || !newSceneData) {
|
||||||
|
res.status(400).send("Data or hash not provided.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scenes[sceneId] && scenes[sceneId].hash != oldSceneHash) {
|
||||||
|
res.status(409).send("Hash mismatch. Update denied.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scenes[sceneId] = {
|
||||||
|
hash: newSceneHash,
|
||||||
|
data: newSceneData,
|
||||||
|
};
|
||||||
|
|
||||||
|
res.status(200).send(`Scene with ID ${sceneId} has been upserted.`);
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
const _get: RequestHandler = (req, res, next) => {
|
||||||
|
const sceneId = req.params.id;
|
||||||
|
const oldSceneHash = req.header("If-None-Match");
|
||||||
|
|
||||||
|
if (!scenes[sceneId]) {
|
||||||
|
res.status(404).send("Not found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scenes[sceneId] && scenes[sceneId].hash == oldSceneHash) {
|
||||||
|
res.status(304).send("Not modified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Respect If-None-Match header
|
||||||
|
|
||||||
|
const scene = scenes[sceneId];
|
||||||
|
res.header("ETag", scene.hash).header("Content-Type", "application/octet-stream");
|
||||||
|
res.status(200).send(scene.data);
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
const _options: RequestHandler = (req, res, next) => {
|
||||||
|
const sceneId = req.params.id;
|
||||||
|
delete scenes[sceneId];
|
||||||
|
res.status(200).end();
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
const _delete: RequestHandler = (req, res, next) => {
|
||||||
|
const sceneId = req.params.id;
|
||||||
|
delete scenes[sceneId];
|
||||||
|
res.status(200).end();
|
||||||
|
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-Methods", "GET, PUT, DELETE, OPTIONS");
|
||||||
|
res.header("Access-Control-Allow-Headers", "Content-Type, ETag, If-Match, If-None-Match");
|
||||||
|
switch (req.method) {
|
||||||
|
case "GET":
|
||||||
|
_get(req, res, next);
|
||||||
|
break;
|
||||||
|
case "PUT":
|
||||||
|
_put(req, res, next);
|
||||||
|
break;
|
||||||
|
case "OPTIONS":
|
||||||
|
_options(req, res, next);
|
||||||
|
break;
|
||||||
|
case "DELETE":
|
||||||
|
_delete(req, res, next);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user