Server/project/src/routers/HttpRouter.ts

92 lines
2.6 KiB
TypeScript
Raw Normal View History

import { IncomingMessage } from "node:http";
2023-11-13 17:43:37 +01:00
import { injectAll, injectable } from "tsyringe";
import { DynamicRouter, Router, StaticRouter } from "@spt/di/Router";
2023-03-03 16:23:46 +01:00
@injectable()
export class HttpRouter
{
constructor(
@injectAll("StaticRoutes") protected staticRouters: StaticRouter[],
2023-11-13 17:12:17 +01:00
@injectAll("DynamicRoutes") protected dynamicRoutes: DynamicRouter[],
2023-03-03 16:23:46 +01:00
)
2023-11-13 17:12:17 +01:00
{}
2023-03-03 16:23:46 +01:00
2023-11-13 17:12:17 +01:00
protected groupBy<T>(list: T[], keyGetter: (t: T) => string): Map<string, T[]>
2023-03-03 16:23:46 +01:00
{
const map: Map<string, T[]> = new Map();
2023-10-31 18:46:14 +01:00
for (const item of list)
2023-03-03 16:23:46 +01:00
{
const key = keyGetter(item);
const collection = map.get(key);
if (!collection)
{
map.set(key, [item]);
}
else
{
collection.push(item);
}
2023-10-31 18:46:14 +01:00
}
2023-03-03 16:23:46 +01:00
return map;
}
public async getResponse(req: IncomingMessage, info: any, sessionID: string): Promise<string>
2023-03-03 16:23:46 +01:00
{
const wrapper: ResponseWrapper = new ResponseWrapper("");
let url = req.url;
// remove retry from url
2023-03-18 10:19:20 +01:00
if (url?.includes("?retry="))
2023-03-03 16:23:46 +01:00
{
url = url.split("?retry=")[0];
}
const handled = await this.handleRoute(url, info, sessionID, wrapper, this.staticRouters, false);
2023-03-03 16:23:46 +01:00
if (!handled)
{
await this.handleRoute(url, info, sessionID, wrapper, this.dynamicRoutes, true);
2023-03-03 16:23:46 +01:00
}
// TODO: Temporary hack to change ItemEventRouter response sessionID binding to what client expects
if (wrapper.output?.includes('"profileChanges":{'))
2023-03-03 16:23:46 +01:00
{
wrapper.output = wrapper.output.replace(sessionID, sessionID);
2023-03-03 16:23:46 +01:00
}
return wrapper.output;
}
protected async handleRoute(
2023-11-13 17:12:17 +01:00
url: string,
info: any,
sessionID: string,
wrapper: ResponseWrapper,
routers: Router[],
dynamic: boolean,
): Promise<boolean>
2023-03-03 16:23:46 +01:00
{
let matched = false;
for (const route of routers)
{
if (route.canHandle(url, dynamic))
{
if (dynamic)
{
wrapper.output = await (route as DynamicRouter).handleDynamic(url, info, sessionID, wrapper.output);
2023-03-03 16:23:46 +01:00
}
else
{
wrapper.output = await (route as StaticRouter).handleStatic(url, info, sessionID, wrapper.output);
2023-03-03 16:23:46 +01:00
}
matched = true;
}
}
return matched;
}
}
class ResponseWrapper
{
constructor(public output: string)
2023-03-03 16:23:46 +01:00
{}
2023-11-13 17:12:17 +01:00
}