using Microsoft.AspNetCore.Http; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.DI; using SPTarkov.Server.Core.Models.Common; namespace SPTarkov.Server.Core.Routers; [Injectable] public class HttpRouter { protected readonly IEnumerable _dynamicRoutes; protected readonly IEnumerable _staticRouters; public HttpRouter(IEnumerable staticRouters, IEnumerable dynamicRoutes) { _staticRouters = staticRouters; _dynamicRoutes = dynamicRoutes; } /* protected groupBy(list: T[], keyGetter: (t: T) => string): Map { const map: Map = new Map(); for (const item of list) { const key = keyGetter(item); const collection = map.get(key); if (!collection) { map.set(key, [item]); } else { collection.push(item); } } return map; } */ public async ValueTask GetResponse(HttpRequest req, MongoId sessionID, string? body) { var wrapper = new ResponseWrapper(""); var handled = await HandleRoute(req, sessionID, wrapper, _staticRouters, false, body); if (!handled) { await HandleRoute(req, sessionID, wrapper, _dynamicRoutes, true, body); } return wrapper.Output; } protected async ValueTask HandleRoute( HttpRequest request, MongoId sessionID, ResponseWrapper wrapper, IEnumerable routers, bool dynamic, string? body ) { var url = request.Path.Value; // remove retry from url if (url?.Contains("?retry=") ?? false) { url = url.Split("?retry=")[0]; } var matched = false; foreach (var route in routers) { if (route.CanHandle(url, dynamic)) { if (dynamic) { wrapper.Output = await (route as DynamicRouter).HandleDynamic(url, body, sessionID, wrapper.Output) as string; } else { wrapper.Output = await (route as StaticRouter).HandleStatic(url, body, sessionID, wrapper.Output) as string; } matched = true; } } return matched; } protected class ResponseWrapper(string? output) { public string? Output { get; set; } = output; } }