79 lines
2.3 KiB
C#
79 lines
2.3 KiB
C#
|
|
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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|