Laservall_solidworks_inject/Server/RequestRouter.cs

79 lines
2.3 KiB
C#
Raw Permalink Normal View History

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<RouteEntry> _routes = new List<RouteEntry>();
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;
}
}
}