using System; using System.Collections.Generic; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Laservall.Solidworks.Server { internal sealed class RequestRouter { public delegate Task RouteHandler(HttpListenerContext context, CancellationToken ct); private readonly List _routes = new List(); public void Map(string method, string path, RouteHandler handler) { _routes.Add(new RouteEntry { Method = method?.ToUpperInvariant(), Path = path, Handler = handler }); } public void Get(string path, RouteHandler handler) { Map("GET", path, handler); } public void Post(string path, RouteHandler handler) { Map("POST", path, handler); } public async Task RouteAsync(HttpListenerContext context, CancellationToken ct) { string requestPath = context.Request.Url.AbsolutePath.TrimEnd('/'); if (string.IsNullOrEmpty(requestPath)) { requestPath = "/"; } string method = context.Request.HttpMethod.ToUpperInvariant(); foreach (var route in _routes) { bool methodMatch = route.Method == null || route.Method == method; bool pathMatch = string.Equals(route.Path, requestPath, StringComparison.OrdinalIgnoreCase); if (methodMatch && pathMatch) { await route.Handler(context, ct); return; } } await SendNotFound(context.Response); } private static async Task SendNotFound(HttpListenerResponse response) { response.StatusCode = 404; response.ContentType = "application/json; charset=utf-8"; byte[] body = Encoding.UTF8.GetBytes("{\"error\":\"Not Found\"}"); response.ContentLength64 = body.Length; await response.OutputStream.WriteAsync(body, 0, body.Length); response.Close(); } private struct RouteEntry { public string Method; public string Path; public RouteHandler Handler; } } }