diff --git a/back/src/App.ts b/back/src/App.ts
index c13b6fdc..5853f4d6 100644
--- a/back/src/App.ts
+++ b/back/src/App.ts
@@ -1,10 +1,6 @@
// lib/app.ts
import {IoSocketController} from "./Controller/IoSocketController"; //TODO fix import by "_Controller/..."
import {AuthenticateController} from "./Controller/AuthenticateController"; //TODO fix import by "_Controller/..."
-import express from "express";
-import {Application, Request, Response} from 'express';
-import bodyParser = require('body-parser');
-import * as http from "http";
import {MapController} from "./Controller/MapController";
import {PrometheusController} from "./Controller/PrometheusController";
import {AdminController} from "./Controller/AdminController";
diff --git a/back/src/Controller/AdminController.ts b/back/src/Controller/AdminController.ts
index c4905a8a..78280523 100644
--- a/back/src/Controller/AdminController.ts
+++ b/back/src/Controller/AdminController.ts
@@ -1,24 +1,26 @@
-import {Application, Request, Response} from "express";
import {OK} from "http-status-codes";
import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable";
import Axios from "axios";
+import {HttpRequest, HttpResponse} from "uWebSockets.js";
+import {parse} from "query-string";
+import {App} from "../Server/sifrr.server";
export class AdminController {
- App : Application;
-
- constructor(App : Application) {
- this.App = App;
+ constructor(private App : App) {
this.getLoginUrlByToken();
}
-
+
getLoginUrlByToken(){
- this.App.get("/register/:token", async (req: Request, res: Response) => {
+ this.App.get("/register/:token", async (res: HttpResponse, req: HttpRequest) => {
if (!ADMIN_API_URL) {
- return res.status(500).send('No admin backoffice set!');
+ return res.writeStatus("500 Internal Server Error").end('No admin backoffice set!');
}
- const token:string = req.params.token;
-
+
+ const query = parse(req.getQuery());
+
+ const token:string = query.token as string;
+
let response = null
try {
response = await Axios.get(ADMIN_API_URL+'/api/login-url/'+token, { headers: {"Authorization" : `${ADMIN_API_TOKEN}`} })
@@ -30,7 +32,7 @@ export class AdminController {
const organizationSlug = response.data.organizationSlug;
const worldSlug = response.data.worldSlug;
const roomSlug = response.data.roomSlug;
- return res.status(OK).send({organizationSlug, worldSlug, roomSlug});
+ return res.writeStatus("200 OK").end(JSON.stringify({organizationSlug, worldSlug, roomSlug}));
});
}
}
diff --git a/back/src/Controller/AuthenticateController.ts b/back/src/Controller/AuthenticateController.ts
index a65255a2..b7fd093c 100644
--- a/back/src/Controller/AuthenticateController.ts
+++ b/back/src/Controller/AuthenticateController.ts
@@ -1,6 +1,4 @@
-import {Application, Request, Response} from "express";
import Jwt from "jsonwebtoken";
-import {BAD_REQUEST, OK} from "http-status-codes";
import {SECRET_KEY, URL_ROOM_STARTED} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
import { uuid } from 'uuidv4';
import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js";
diff --git a/back/src/Controller/DebugController.ts b/back/src/Controller/DebugController.ts
index 54544f6c..e77b28f3 100644
--- a/back/src/Controller/DebugController.ts
+++ b/back/src/Controller/DebugController.ts
@@ -1,22 +1,25 @@
-import {Application, Request, Response} from "express";
-import {OK} from "http-status-codes";
import {ADMIN_API_TOKEN} from "../Enum/EnvironmentVariable";
import {IoSocketController} from "_Controller/IoSocketController";
import {stringify} from "circular-json";
+import {HttpRequest, HttpResponse} from "uWebSockets.js";
+import { parse } from 'query-string';
+import {App} from "../Server/sifrr.server";
export class DebugController {
- constructor(private App : Application, private ioSocketController: IoSocketController) {
+ constructor(private App : App, private ioSocketController: IoSocketController) {
this.getDump();
}
getDump(){
- this.App.get("/dump", (req: Request, res: Response) => {
- if (req.query.token !== ADMIN_API_TOKEN) {
+ this.App.get("/dump", (res: HttpResponse, req: HttpRequest) => {
+ const query = parse(req.getQuery());
+
+ if (query.token !== ADMIN_API_TOKEN) {
return res.status(401).send('Invalid token sent!');
}
- return res.status(OK).contentType('application/json').send(stringify(
+ return res.writeStatus('200 OK').writeHeader('Content-Type', 'application/json').end(stringify(
this.ioSocketController.getWorlds(),
(key: unknown, value: unknown) => {
if(value instanceof Map) {
diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts
index d9bdc950..cd3d5e52 100644
--- a/back/src/Controller/IoSocketController.ts
+++ b/back/src/Controller/IoSocketController.ts
@@ -121,7 +121,7 @@ export class IoSocketController {
*
* @param token
*/
- searchClientByToken(token: string): ExSocketInterface | null {
+/* searchClientByToken(token: string): ExSocketInterface | null {
const clients: ExSocketInterface[] = Object.values(this.Io.sockets.sockets) as ExSocketInterface[];
for (let i = 0; i < clients.length; i++) {
const client = clients[i];
@@ -131,7 +131,7 @@ export class IoSocketController {
return client;
}
return null;
- }
+ }*/
private authenticate(ws: WebSocket) {
//console.log(socket.handshake.query.token);
@@ -657,25 +657,23 @@ export class IoSocketController {
//socket.emit(SocketIoEvent.GROUP_CREATE_UPDATE, groupUpdateMessage.serializeBinary().buffer);
}
- private emitDeleteGroupEvent(socket: Socket, groupId: number): void {
+ private emitDeleteGroupEvent(client: ExSocketInterface, groupId: number): void {
const groupDeleteMessage = new GroupDeleteMessage();
groupDeleteMessage.setGroupid(groupId);
const subMessage = new SubMessage();
subMessage.setGroupdeletemessage(groupDeleteMessage);
- const client : ExSocketInterface = socket as ExSocketInterface;
emitInBatch(client, subMessage);
}
- private emitUserLeftEvent(socket: Socket, userId: number): void {
+ private emitUserLeftEvent(client: ExSocketInterface, userId: number): void {
const userLeftMessage = new UserLeftMessage();
userLeftMessage.setUserid(userId);
const subMessage = new SubMessage();
subMessage.setUserleftmessage(userLeftMessage);
- const client : ExSocketInterface = socket as ExSocketInterface;
emitInBatch(client, subMessage);
}
diff --git a/back/src/Server/server/baseapp.ts b/back/src/Server/server/baseapp.ts
index dbac5929..d723c33d 100644
--- a/back/src/Server/server/baseapp.ts
+++ b/back/src/Server/server/baseapp.ts
@@ -1,18 +1,9 @@
-import { readdirSync, statSync } from 'fs';
-import { join, relative } from 'path';
import { Readable } from 'stream';
import { us_listen_socket_close, TemplatedApp, HttpResponse, HttpRequest } from 'uWebSockets.js';
-//import { watch } from 'chokidar';
-import { wsConfig } from './livereload';
-import sendFile from './sendfile';
-import formData from './formdata';
-import loadroutes from './loadroutes';
-import { graphqlPost, graphqlWs } from './graphql';
import { stob } from './utils';
-import { SendFileOptions, Handler } from './types';
+import { Handler } from './types';
-const contTypes = ['application/x-www-form-urlencoded', 'multipart/form-data'];
const noOp = () => true;
const handleBody = (res: HttpResponse, req: HttpRequest) => {
@@ -24,7 +15,7 @@ const handleBody = (res: HttpResponse, req: HttpRequest) => {
this.onData((ab, isLast) => {
// uint and then slicing is bit faster than slice and then uint
- stream.push(new Uint8Array(ab.slice(ab.byteOffset, ab.byteLength)));
+ stream.push(new Uint8Array(ab.slice((ab as any).byteOffset, ab.byteLength)));
if (isLast) {
stream.push(null);
}
@@ -37,15 +28,10 @@ const handleBody = (res: HttpResponse, req: HttpRequest) => {
if (contType.indexOf('application/json') > -1)
res.json = async () => JSON.parse(await res.body());
- if (contTypes.map(t => contType.indexOf(t) > -1).indexOf(true) > -1)
- res.formData = formData.bind(res, contType);
};
class BaseApp {
- _staticPaths = new Map();
- //_watched = new Map();
_sockets = new Map();
- __livereloadenabled = false;
ws!: TemplatedApp['ws'];
get!: TemplatedApp['get'];
_post!: TemplatedApp['post'];
@@ -53,84 +39,6 @@ class BaseApp {
_patch!: TemplatedApp['patch'];
_listen!: TemplatedApp['listen'];
- file(pattern: string, filePath: string, options: SendFileOptions = {}) {
- pattern=pattern.replace(/\\/g,'/');
- if (this._staticPaths.has(pattern)) {
- if (options.failOnDuplicateRoute)
- throw Error(
- `Error serving '${filePath}' for '${pattern}', already serving '${
- this._staticPaths.get(pattern)[0]
- }' file for this pattern.`
- );
- else if (!options.overwriteRoute) return this;
- }
-
- if (options.livereload && !this.__livereloadenabled) {
- this.ws('/__sifrrLiveReload', wsConfig);
- this.file('/livereload.js', join(__dirname, './livereloadjs.js'));
- this.__livereloadenabled = true;
- }
-
- this._staticPaths.set(pattern, [filePath, options]);
- this.get(pattern, this._serveStatic);
- return this;
- }
-
- folder(prefix: string, folder: string, options: SendFileOptions, base: string = folder) {
- // not a folder
- if (!statSync(folder).isDirectory()) {
- throw Error('Given path is not a directory: ' + folder);
- }
-
- // ensure slash in beginning and no trailing slash for prefix
- if (prefix[0] !== '/') prefix = '/' + prefix;
- if (prefix[prefix.length - 1] === '/') prefix = prefix.slice(0, -1);
-
- // serve folder
- const filter = options ? options.filter || noOp : noOp;
- readdirSync(folder).forEach(file => {
- // Absolute path
- const filePath = join(folder, file);
- // Return if filtered
- if (!filter(filePath)) return;
-
- if (statSync(filePath).isDirectory()) {
- // Recursive if directory
- this.folder(prefix, filePath, options, base);
- } else {
- this.file(prefix + '/' + relative(base, filePath), filePath, options);
- }
- });
-
- /*if (options && options.watch) {
- if (!this._watched.has(folder)) {
- const w = watch(folder);
-
- w.on('unlink', filePath => {
- const url = '/' + relative(base, filePath);
- this._staticPaths.delete(prefix + url);
- });
-
- w.on('add', filePath => {
- const url = '/' + relative(base, filePath);
- this.file(prefix + url, filePath, options);
- });
-
- this._watched.set(folder, w);
- }
- }*/
- return this;
- }
-
- _serveStatic(res: HttpResponse, req: HttpRequest) {
- res.onAborted(noOp);
- const options = this._staticPaths.get(req.getUrl());
- if (typeof options === 'undefined') {
- res.writeStatus('404 Not Found');
- res.end();
- } else sendFile(res, req, options[0], options[1]);
- }
-
post(pattern: string, handler: Handler) {
if (typeof handler !== 'function')
throw Error(`handler should be a function, given ${typeof handler}.`);
@@ -163,21 +71,6 @@ class BaseApp {
return this;
}
- graphql(route: string, schema, graphqlOptions: any = {}, uwsOptions = {}, graphql) {
- const handler = graphqlPost(schema, graphqlOptions, graphql);
- this.post(route, handler);
- this.ws(route, graphqlWs(schema, graphqlOptions, uwsOptions, graphql));
- // this.get(route, handler);
- if (graphqlOptions && graphqlOptions.graphiqlPath)
- this.file(graphqlOptions.graphiqlPath, join(__dirname, './graphiql.html'));
- return this;
- }
-
- load(dir: string, options) {
- loadroutes.call(this, dir, options);
- return this;
- }
-
listen(h: string | number, p: Function | number = noOp, cb?: Function) {
if (typeof p === 'number' && typeof h === 'string') {
this._listen(h, p, socket => {
@@ -202,8 +95,6 @@ class BaseApp {
}
close(port: null | number = null) {
- //this._watched.forEach(v => v.close());
- //this._watched.clear();
if (port) {
this._sockets.has(port) && us_listen_socket_close(this._sockets.get(port));
this._sockets.delete(port);
diff --git a/back/src/Server/server/cluster.ts b/back/src/Server/server/cluster.ts
deleted file mode 100644
index 5b875327..00000000
--- a/back/src/Server/server/cluster.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-const noop = (a, b) => {};
-
-export default class Cluster {
- apps: any[];
- listens = {};
- // apps = [ { app: SifrrServerApp, port/ports: int } ]
- constructor(apps) {
- if (!Array.isArray(apps)) apps = [apps];
- this.apps = apps;
- }
-
- listen(onListen = noop) {
- for (let i = 0; i < this.apps.length; i++) {
- const config = this.apps[i];
- let { app, port, ports } = config;
- if (!Array.isArray(ports) || ports.length === 0) {
- ports = [port];
- }
- ports.forEach(p => {
- if (typeof p !== 'number') throw Error(`Port should be a number, given ${p}`);
- if (this.listens[p]) return;
-
- app.listen(p, socket => {
- onListen.call(app, socket, p);
- });
- this.listens[p] = app;
- });
- }
- return this;
- }
-
- closeAll() {
- Object.keys(this.listens).forEach(port => {
- this.close(port);
- });
- return this;
- }
-
- close(port = null) {
- if (port) {
- this.listens[port] && this.listens[port].close(port);
- delete this.listens[port];
- } else {
- this.closeAll();
- }
- return this;
- }
-}
diff --git a/back/src/Server/server/formdata.ts b/back/src/Server/server/formdata.ts
deleted file mode 100644
index 419e6c6b..00000000
--- a/back/src/Server/server/formdata.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import { createWriteStream } from 'fs';
-import { join, dirname } from 'path';
-import Busboy from 'busboy';
-import mkdirp from 'mkdirp';
-
-function formData(
- contType: string,
- options: busboy.BusboyConfig & {
- abortOnLimit?: boolean;
- tmpDir?: string;
- onFile?: (
- fieldname: string,
- file: NodeJS.ReadableStream,
- filename: string,
- encoding: string,
- mimetype: string
- ) => string;
- onField?: (fieldname: string, value: any) => void;
- filename?: (oldName: string) => string;
- } = {}
-) {
- options.headers = {
- 'content-type': contType
- };
-
- return new Promise((resolve, reject) => {
- const busb = new Busboy(options);
- const ret = {};
-
- this.bodyStream().pipe(busb);
-
- busb.on('limit', () => {
- if (options.abortOnLimit) {
- reject(Error('limit'));
- }
- });
-
- busb.on('file', function(fieldname, file, filename, encoding, mimetype) {
- const value = {
- filename,
- encoding,
- mimetype,
- filePath: undefined
- };
-
- if (typeof options.tmpDir === 'string') {
- if (typeof options.filename === 'function') filename = options.filename(filename);
- const fileToSave = join(options.tmpDir, filename);
- mkdirp(dirname(fileToSave));
-
- file.pipe(createWriteStream(fileToSave));
- value.filePath = fileToSave;
- }
- if (typeof options.onFile === 'function') {
- value.filePath =
- options.onFile(fieldname, file, filename, encoding, mimetype) || value.filePath;
- }
-
- setRetValue(ret, fieldname, value);
- });
-
- busb.on('field', function(fieldname, value) {
- if (typeof options.onField === 'function') options.onField(fieldname, value);
-
- setRetValue(ret, fieldname, value);
- });
-
- busb.on('finish', function() {
- resolve(ret);
- });
-
- busb.on('error', reject);
- });
-}
-
-function setRetValue(
- ret: { [x: string]: any },
- fieldname: string,
- value: { filename: string; encoding: string; mimetype: string; filePath?: string } | any
-) {
- if (fieldname.slice(-2) === '[]') {
- fieldname = fieldname.slice(0, fieldname.length - 2);
- if (Array.isArray(ret[fieldname])) {
- ret[fieldname].push(value);
- } else {
- ret[fieldname] = [value];
- }
- } else {
- if (Array.isArray(ret[fieldname])) {
- ret[fieldname].push(value);
- } else if (ret[fieldname]) {
- ret[fieldname] = [ret[fieldname], value];
- } else {
- ret[fieldname] = value;
- }
- }
-}
-
-export default formData;
diff --git a/back/src/Server/server/graphiql.html b/back/src/Server/server/graphiql.html
deleted file mode 100644
index 7ce03921..00000000
--- a/back/src/Server/server/graphiql.html
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Loading...
-
-
-
diff --git a/back/src/Server/server/graphql.ts b/back/src/Server/server/graphql.ts
deleted file mode 100644
index 63a2bdaa..00000000
--- a/back/src/Server/server/graphql.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-import { parse } from 'query-string';
-import { createAsyncIterator, forAwaitEach, isAsyncIterable } from 'iterall';
-import { HttpResponse, HttpRequest } from 'uWebSockets.js';
-// client -> server
-const GQL_START = 'start';
-const GQL_STOP = 'stop';
-// server -> client
-const GQL_DATA = 'data';
-const GQL_QUERY = 'query';
-
-async function getGraphqlParams(res: HttpResponse, req: HttpRequest) {
- // query and variables
- const queryParams = parse(req.getQuery());
- let { query, variables, operationName } = queryParams;
- if (typeof variables === 'string') variables = JSON.parse(variables);
-
- // body
- if (res && typeof res.json === 'function') {
- const data = await res.json();
- query = data.query || query;
- variables = data.variables || variables;
- operationName = data.operationName || operationName;
- }
- return {
- source: query,
- variableValues: variables,
- operationName
- };
-}
-
-function graphqlPost(schema, graphqlOptions: any = {}, graphql: any = {}) {
- const execute = graphql.graphql || require('graphql').graphql;
-
- return async (res: HttpResponse, req: HttpRequest) => {
- res.onAborted(console.error);
-
- res.writeHeader('content-type', 'application/json');
- res.end(
- JSON.stringify(
- await execute({
- schema,
- ...(await getGraphqlParams(res, req)),
- ...graphqlOptions,
- contextValue: {
- res,
- req,
- ...(graphqlOptions &&
- (graphqlOptions.contextValue ||
- (graphqlOptions.contextFxn && (await graphqlOptions.contextFxn(res, req)))))
- }
- })
- )
- );
- };
-}
-
-function stopGqsSubscription(operations, reqOpId) {
- if (!reqOpId) return;
- operations[reqOpId] && operations[reqOpId].return && operations[reqOpId].return();
- delete operations[reqOpId];
-}
-
-function graphqlWs(schema, graphqlOptions: any = {}, uwsOptions: any = {}, graphql: any = {}) {
- const subscribe = graphql.subscribe || require('graphql').subscribe;
- const execute = graphql.graphql || require('graphql').graphql;
-
- return {
- open: (ws, req) => {
- ws.req = req;
- ws.operations = {};
- ws.opId = 1;
- },
- message: async (ws, message) => {
- const { type, payload = {}, id: reqOpId } = JSON.parse(Buffer.from(message).toString('utf8'));
- let opId;
- if (reqOpId) {
- opId = reqOpId;
- } else {
- opId = ws.opId++;
- }
-
- const params = {
- schema,
- source: payload.query,
- variableValues: payload.variables,
- operationName: payload.operationName,
- contextValue: {
- ws,
- ...(graphqlOptions &&
- (graphqlOptions.contextValue ||
- (graphqlOptions.contextFxn && (await graphqlOptions.contextFxn(ws)))))
- },
- ...graphqlOptions
- };
-
- switch (type) {
- case GQL_START:
- stopGqsSubscription(ws.operations, opId);
-
- // eslint-disable-next-line no-case-declarations
- let asyncIterable = await subscribe(
- params.schema,
- graphql.parse(params.source),
- params.rootValue,
- params.contextValue,
- params.variableValues,
- params.operationName
- );
- asyncIterable = isAsyncIterable(asyncIterable)
- ? asyncIterable
- : createAsyncIterator([asyncIterable]);
-
- forAwaitEach(asyncIterable, result =>
- ws.send(
- JSON.stringify({
- id: opId,
- type: GQL_DATA,
- payload: result
- })
- )
- );
- break;
-
- case GQL_STOP:
- stopGqsSubscription(ws.operations, reqOpId);
- break;
-
- default:
- ws.send(JSON.stringify({ payload: await execute(params), type: GQL_QUERY, id: opId }));
- break;
- }
- },
- idleTimeout: 24 * 60 * 60,
- ...uwsOptions
- };
-}
-
-export { graphqlPost, graphqlWs };
diff --git a/back/src/Server/server/livereload.ts b/back/src/Server/server/livereload.ts
deleted file mode 100644
index 787c871b..00000000
--- a/back/src/Server/server/livereload.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { WebSocketBehavior, WebSocket } from 'uWebSockets.js';
-
-const websockets = {};
-let id = 0;
-
-const wsConfig: WebSocketBehavior = {
- open: (ws: WebSocket & { id: number }, req) => {
- websockets[id] = {
- dirty: false
- };
- ws.id = id;
- console.log('websocket connected: ', id);
- id++;
- },
- message: ws => {
- ws.send(JSON.stringify(websockets[ws.id].dirty));
- websockets[ws.id].dirty = false;
- },
- close: (ws, code, message) => {
- delete websockets[ws.id];
- console.log(
- `websocket disconnected with code ${code} and message ${message}:`,
- ws.id,
- websockets
- );
- }
-};
-
-const sendSignal = (type: string, path: string) => {
- console.log(type, 'signal for file: ', path);
- for (let i in websockets) websockets[i].dirty = true;
-};
-
-export default { websockets, wsConfig, sendSignal };
-export { websockets, wsConfig, sendSignal };
diff --git a/back/src/Server/server/livereloadjs.js b/back/src/Server/server/livereloadjs.js
deleted file mode 100644
index 04839578..00000000
--- a/back/src/Server/server/livereloadjs.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const loc = window.location;
-let path;
-if (loc.protocol === 'https:') {
- path = 'wss:';
-} else {
- path = 'ws:';
-}
-path += '//' + loc.host + '/__sifrrLiveReload';
-
-let ws,
- ttr = 500,
- timeout;
-
-function newWsConnection() {
- ws = new WebSocket(path);
- ws.onopen = function() {
- ttr = 500;
- checkMessage();
- console.log('watching for file changes through sifrr-server livereload mode.');
- };
- ws.onmessage = function(event) {
- if (JSON.parse(event.data)) {
- console.log('Files changed, refreshing page.');
- location.reload();
- }
- };
- ws.onerror = e => {
- console.error('Webosocket error: ', e);
- console.log('Retrying after ', ttr / 4, 'ms');
- ttr *= 4;
- };
- ws.onclose = e => {
- console.error(`Webosocket closed with code \${e.code} error \${e.message}`);
- };
-}
-
-function checkMessage() {
- if (!ws) return;
- if (ws.readyState === WebSocket.OPEN) ws.send('');
- else if (ws.readyState === WebSocket.CLOSED) newWsConnection();
-
- if (timeout) clearTimeout(timeout);
- timeout = setTimeout(checkMessage, ttr);
-}
-
-newWsConnection();
-setTimeout(checkMessage, ttr);
diff --git a/back/src/Server/server/loadroutes.ts b/back/src/Server/server/loadroutes.ts
deleted file mode 100644
index 3761d762..00000000
--- a/back/src/Server/server/loadroutes.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { statSync, readdirSync } from 'fs';
-import { join, extname } from 'path';
-
-function loadRoutes(dir, { filter = () => true, basePath = '' } = {}) {
- let files;
- const paths = [];
-
- if (statSync(dir).isDirectory()) {
- files = readdirSync(dir)
- .filter(filter)
- .map(file => join(dir, file));
- } else {
- files = [dir];
- }
-
- files.forEach(file => {
- if (statSync(file).isDirectory()) {
- // Recursive if directory
- paths.push(...loadRoutes.call(this, file, { filter, basePath }));
- } else if (extname(file) === '.js') {
- const routes = require(file);
- let basePaths = routes.basePath || [''];
- delete routes.basePath;
- if (typeof basePaths === 'string') basePaths = [basePaths];
-
- basePaths.forEach(basep => {
- for (const method in routes) {
- const methodRoutes = routes[method];
- for (let r in methodRoutes) {
- if (!Array.isArray(methodRoutes[r])) methodRoutes[r] = [methodRoutes[r]];
- this[method](basePath + basep + r, ...methodRoutes[r]);
- paths.push(basePath + basep + r);
- }
- }
- });
- }
- });
-
- return paths;
-}
-
-export default loadRoutes;
diff --git a/back/src/Server/server/mime.ts b/back/src/Server/server/mime.ts
deleted file mode 100644
index 396073cc..00000000
--- a/back/src/Server/server/mime.ts
+++ /dev/null
@@ -1,176 +0,0 @@
-const mimes = {
- '3gp': 'video/3gpp',
- a: 'application/octet-stream',
- ai: 'application/postscript',
- aif: 'audio/x-aiff',
- aiff: 'audio/x-aiff',
- asc: 'application/pgp-signature',
- asf: 'video/x-ms-asf',
- asm: 'text/x-asm',
- asx: 'video/x-ms-asf',
- atom: 'application/atom+xml',
- au: 'audio/basic',
- avi: 'video/x-msvideo',
- bat: 'application/x-msdownload',
- bin: 'application/octet-stream',
- bmp: 'image/bmp',
- bz2: 'application/x-bzip2',
- c: 'text/x-c',
- cab: 'application/vnd.ms-cab-compressed',
- cc: 'text/x-c',
- chm: 'application/vnd.ms-htmlhelp',
- class: 'application/octet-stream',
- com: 'application/x-msdownload',
- conf: 'text/plain',
- cpp: 'text/x-c',
- crt: 'application/x-x509-ca-cert',
- css: 'text/css',
- csv: 'text/csv',
- cxx: 'text/x-c',
- deb: 'application/x-debian-package',
- der: 'application/x-x509-ca-cert',
- diff: 'text/x-diff',
- djv: 'image/vnd.djvu',
- djvu: 'image/vnd.djvu',
- dll: 'application/x-msdownload',
- dmg: 'application/octet-stream',
- doc: 'application/msword',
- dot: 'application/msword',
- dtd: 'application/xml-dtd',
- dvi: 'application/x-dvi',
- ear: 'application/java-archive',
- eml: 'message/rfc822',
- eps: 'application/postscript',
- exe: 'application/x-msdownload',
- f: 'text/x-fortran',
- f77: 'text/x-fortran',
- f90: 'text/x-fortran',
- flv: 'video/x-flv',
- for: 'text/x-fortran',
- gem: 'application/octet-stream',
- gemspec: 'text/x-script.ruby',
- gif: 'image/gif',
- gz: 'application/x-gzip',
- h: 'text/x-c',
- hh: 'text/x-c',
- htm: 'text/html',
- html: 'text/html',
- ico: 'image/vnd.microsoft.icon',
- ics: 'text/calendar',
- ifb: 'text/calendar',
- iso: 'application/octet-stream',
- jar: 'application/java-archive',
- java: 'text/x-java-source',
- jnlp: 'application/x-java-jnlp-file',
- jpeg: 'image/jpeg',
- jpg: 'image/jpeg',
- js: 'application/javascript',
- json: 'application/json',
- log: 'text/plain',
- m3u: 'audio/x-mpegurl',
- m4v: 'video/mp4',
- man: 'text/troff',
- mathml: 'application/mathml+xml',
- mbox: 'application/mbox',
- mdoc: 'text/troff',
- me: 'text/troff',
- mid: 'audio/midi',
- midi: 'audio/midi',
- mime: 'message/rfc822',
- mjs: 'application/javascript',
- mml: 'application/mathml+xml',
- mng: 'video/x-mng',
- mov: 'video/quicktime',
- mp3: 'audio/mpeg',
- mp4: 'video/mp4',
- mp4v: 'video/mp4',
- mpeg: 'video/mpeg',
- mpg: 'video/mpeg',
- ms: 'text/troff',
- msi: 'application/x-msdownload',
- odp: 'application/vnd.oasis.opendocument.presentation',
- ods: 'application/vnd.oasis.opendocument.spreadsheet',
- odt: 'application/vnd.oasis.opendocument.text',
- ogg: 'application/ogg',
- p: 'text/x-pascal',
- pas: 'text/x-pascal',
- pbm: 'image/x-portable-bitmap',
- pdf: 'application/pdf',
- pem: 'application/x-x509-ca-cert',
- pgm: 'image/x-portable-graymap',
- pgp: 'application/pgp-encrypted',
- pkg: 'application/octet-stream',
- pl: 'text/x-script.perl',
- pm: 'text/x-script.perl-module',
- png: 'image/png',
- pnm: 'image/x-portable-anymap',
- ppm: 'image/x-portable-pixmap',
- pps: 'application/vnd.ms-powerpoint',
- ppt: 'application/vnd.ms-powerpoint',
- ps: 'application/postscript',
- psd: 'image/vnd.adobe.photoshop',
- py: 'text/x-script.python',
- qt: 'video/quicktime',
- ra: 'audio/x-pn-realaudio',
- rake: 'text/x-script.ruby',
- ram: 'audio/x-pn-realaudio',
- rar: 'application/x-rar-compressed',
- rb: 'text/x-script.ruby',
- rdf: 'application/rdf+xml',
- roff: 'text/troff',
- rpm: 'application/x-redhat-package-manager',
- rss: 'application/rss+xml',
- rtf: 'application/rtf',
- ru: 'text/x-script.ruby',
- s: 'text/x-asm',
- sgm: 'text/sgml',
- sgml: 'text/sgml',
- sh: 'application/x-sh',
- sig: 'application/pgp-signature',
- snd: 'audio/basic',
- so: 'application/octet-stream',
- svg: 'image/svg+xml',
- svgz: 'image/svg+xml',
- swf: 'application/x-shockwave-flash',
- t: 'text/troff',
- tar: 'application/x-tar',
- tbz: 'application/x-bzip-compressed-tar',
- tcl: 'application/x-tcl',
- tex: 'application/x-tex',
- texi: 'application/x-texinfo',
- texinfo: 'application/x-texinfo',
- text: 'text/plain',
- tif: 'image/tiff',
- tiff: 'image/tiff',
- torrent: 'application/x-bittorrent',
- tr: 'text/troff',
- txt: 'text/plain',
- vcf: 'text/x-vcard',
- vcs: 'text/x-vcalendar',
- vrml: 'model/vrml',
- war: 'application/java-archive',
- wav: 'audio/x-wav',
- wma: 'audio/x-ms-wma',
- wmv: 'video/x-ms-wmv',
- wmx: 'video/x-ms-wmx',
- wrl: 'model/vrml',
- wsdl: 'application/wsdl+xml',
- xbm: 'image/x-xbitmap',
- xhtml: 'application/xhtml+xml',
- xls: 'application/vnd.ms-excel',
- xml: 'application/xml',
- xpm: 'image/x-xpixmap',
- xsl: 'application/xml',
- xslt: 'application/xslt+xml',
- yaml: 'text/yaml',
- yml: 'text/yaml',
- zip: 'application/zip',
- default: 'text/html'
-};
-
-const getMime = (path: string): string => {
- const i = path.lastIndexOf('.');
- return mimes[path.substr(i + 1).toLowerCase()] || mimes['default'];
-};
-
-export { getMime, mimes };
diff --git a/back/src/Server/server/sendfile.ts b/back/src/Server/server/sendfile.ts
deleted file mode 100644
index 8310c4a7..00000000
--- a/back/src/Server/server/sendfile.ts
+++ /dev/null
@@ -1,172 +0,0 @@
-import { watch, statSync, createReadStream } from 'fs';
-import { createBrotliCompress, createGzip, createDeflate } from 'zlib';
-const watchedPaths = new Set();
-
-const compressions = {
- br: createBrotliCompress,
- gzip: createGzip,
- deflate: createDeflate
-};
-import { writeHeaders } from './utils';
-import { getMime } from './mime';
-const bytes = 'bytes=';
-import { stob } from './utils';
-import { sendSignal } from './livereload';
-import { SendFileOptions } from './types';
-import { HttpResponse, HttpRequest } from 'uWebSockets.js';
-
-function sendFile(res: HttpResponse, req: HttpRequest, path: string, options: SendFileOptions) {
- if (options && options.livereload && !watchedPaths.has(path)) {
- watchedPaths.add(path);
- watch(path, sendSignal);
- }
-
- sendFileToRes(
- res,
- {
- 'if-modified-since': req.getHeader('if-modified-since'),
- range: req.getHeader('range'),
- 'accept-encoding': req.getHeader('accept-encoding')
- },
- path,
- options
- );
-}
-
-function sendFileToRes(
- res: HttpResponse,
- reqHeaders: { [name: string]: string },
- path: string,
- {
- lastModified = true,
- headers = {},
- compress = false,
- compressionOptions = {
- priority: ['gzip', 'br', 'deflate']
- },
- cache = false
- }: { cache: any } & any = {}
-) {
- let { mtime, size } = statSync(path);
- mtime.setMilliseconds(0);
- const mtimeutc = mtime.toUTCString();
-
- headers = Object.assign({}, headers);
- // handling last modified
- if (lastModified) {
- // Return 304 if last-modified
- if (reqHeaders['if-modified-since']) {
- if (new Date(reqHeaders['if-modified-since']) >= mtime) {
- res.writeStatus('304 Not Modified');
- return res.end();
- }
- }
- headers['last-modified'] = mtimeutc;
- }
- headers['content-type'] = getMime(path);
-
- // write data
- let start = 0,
- end = size - 1;
-
- if (reqHeaders.range) {
- compress = false;
- const parts = reqHeaders.range.replace(bytes, '').split('-');
- start = parseInt(parts[0], 10);
- end = parts[1] ? parseInt(parts[1], 10) : end;
- headers['accept-ranges'] = 'bytes';
- headers['content-range'] = `bytes ${start}-${end}/${size}`;
- size = end - start + 1;
- res.writeStatus('206 Partial Content');
- }
-
- // for size = 0
- if (end < 0) end = 0;
-
- let readStream = createReadStream(path, { start, end });
- // Compression;
- let compressed: boolean | string = false;
- if (compress) {
- const l = compressionOptions.priority.length;
- for (let i = 0; i < l; i++) {
- const type = compressionOptions.priority[i];
- if (reqHeaders['accept-encoding'].indexOf(type) > -1) {
- compressed = type;
- const compressor = compressions[type](compressionOptions);
- readStream.pipe(compressor);
- readStream = compressor;
- headers['content-encoding'] = compressionOptions.priority[i];
- break;
- }
- }
- }
-
- res.onAborted(() => readStream.destroy());
- writeHeaders(res, headers);
- // check cache
- if (cache) {
- return cache.wrap(
- `${path}_${mtimeutc}_${start}_${end}_${compressed}`,
- cb => {
- stob(readStream)
- .then(b => cb(null, b))
- .catch(cb);
- },
- { ttl: 0 },
- (err, buffer) => {
- if (err) {
- res.writeStatus('500 Internal server error');
- res.end();
- throw err;
- }
- res.end(buffer);
- }
- );
- } else if (compressed) {
- readStream.on('data', buffer => {
- res.write(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength));
- });
- } else {
- readStream.on('data', buffer => {
- const chunk = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength),
- lastOffset = res.getWriteOffset();
-
- // First try
- const [ok, done] = res.tryEnd(chunk, size);
-
- if (done) {
- readStream.destroy();
- } else if (!ok) {
- // pause because backpressure
- readStream.pause();
-
- // Save unsent chunk for later
- res.ab = chunk;
- res.abOffset = lastOffset;
-
- // Register async handlers for drainage
- res.onWritable(offset => {
- const [ok, done] = res.tryEnd(res.ab.slice(offset - res.abOffset), size);
- if (done) {
- readStream.destroy();
- } else if (ok) {
- readStream.resume();
- }
- return ok;
- });
- }
- });
- }
- readStream
- .on('error', e => {
- res.writeStatus('500 Internal server error');
- res.end();
- readStream.destroy();
- throw e;
- })
- .on('end', () => {
- res.end();
- });
-}
-
-export default sendFile;
diff --git a/back/src/Server/server/types.ts b/back/src/Server/server/types.ts
index 09916b5f..3d0f48c7 100644
--- a/back/src/Server/server/types.ts
+++ b/back/src/Server/server/types.ts
@@ -6,21 +6,6 @@ export type UwsApp = {
prototype: TemplatedApp;
};
-export type SendFileOptions = {
- failOnDuplicateRoute?: boolean;
- overwriteRoute?: boolean;
- watch?: boolean;
- filter?: (path: string) => boolean;
- livereload?: boolean;
- lastModified?: boolean;
- headers?: { [name: string]: string };
- compress?: boolean;
- compressionOptions?: {
- priority?: 'gzip' | 'br' | 'deflate';
- };
- cache?: boolean;
-};
-
export type Handler = (res: HttpResponse, req: HttpRequest) => void;
export {};
diff --git a/back/src/Server/server/utils.ts b/back/src/Server/server/utils.ts
index 8f6db886..f7f3e4b5 100644
--- a/back/src/Server/server/utils.ts
+++ b/back/src/Server/server/utils.ts
@@ -1,21 +1,6 @@
-import { HttpResponse } from 'uWebSockets.js';
import { ReadStream } from 'fs';
-function writeHeaders(
- res: HttpResponse,
- headers: { [name: string]: string } | string,
- other?: string
-) {
- if (typeof headers === 'string') {
- res.writeHeader(headers, other.toString());
- } else {
- for (const n in headers) {
- res.writeHeader(n, headers[n].toString());
- }
- }
-}
-
-function extend(who: object, from: object, overwrite = true) {
+function extend(who: any, from: any, overwrite = true) {
const ownProps = Object.getOwnPropertyNames(Object.getPrototypeOf(from)).concat(
Object.keys(from)
);
@@ -31,7 +16,7 @@ function extend(who: object, from: object, overwrite = true) {
function stob(stream: ReadStream): Promise {
return new Promise(resolve => {
- const buffers = [];
+ const buffers: Buffer[] = [];
stream.on('data', buffers.push.bind(buffers));
stream.on('end', () => {
@@ -49,4 +34,4 @@ function stob(stream: ReadStream): Promise {
});
}
-export { writeHeaders, extend, stob };
+export { extend, stob };
diff --git a/back/src/Server/sifrr.server.ts b/back/src/Server/sifrr.server.ts
index 9a274378..47fba02c 100644
--- a/back/src/Server/sifrr.server.ts
+++ b/back/src/Server/sifrr.server.ts
@@ -2,29 +2,18 @@ import { parse } from 'query-string';
import { HttpRequest } from 'uWebSockets.js';
import App from './server/app';
import SSLApp from './server/sslapp';
-import { mimes, getMime } from './server/mime';
-import { writeHeaders } from './server/utils';
-import sendFile from './server/sendfile';
-import Cluster from './server/cluster';
-import livereload from './server/livereload';
import * as types from './server/types';
const getQuery = (req: HttpRequest) => {
return parse(req.getQuery());
};
-export { App, SSLApp, mimes, getMime, writeHeaders, sendFile, Cluster, livereload, getQuery };
+export { App, SSLApp, getQuery };
export * from './server/types';
export default {
App,
SSLApp,
- mimes,
- getMime,
- writeHeaders,
- sendFile,
- Cluster,
- livereload,
getQuery,
...types
};