Compare commits
No commits in common. "8d55c1c533515f67cfcea24b7d7cbbe8f1802f2d" and "c77b3e074263dbe3658cff01a6153d6ffd7a66c6" have entirely different histories.
8d55c1c533
...
c77b3e0742
@ -1 +1 @@
|
||||
Subproject commit 4eaade6e929dde58a47ef1a1c7c87861e9c72a8e
|
||||
Subproject commit bb96774c37ef7b636139872b972e5252076bc913
|
||||
@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<!--package info-->
|
||||
<PackageId>DTLib.Logging.Microsoft</PackageId>
|
||||
<Version>1.1.3</Version>
|
||||
<Version>1.1.2</Version>
|
||||
<Authors>Timerix</Authors>
|
||||
<Description>DTLib logger wrapper with dependency injection</Description>
|
||||
<RepositoryType>GIT</RepositoryType>
|
||||
@ -11,7 +11,7 @@
|
||||
<Configuration>Release</Configuration>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<!--compilation properties-->
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
<!--language features-->
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>disable</Nullable>
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
<!--external dependencies-->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--DTLib dependencies-->
|
||||
@ -28,6 +28,6 @@
|
||||
<ProjectReference Include="..\DTLib\DTLib.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
||||
<PackageReference Include="DTLib" Version="1.7.4" />
|
||||
<PackageReference Include="DTLib" Version="1.7.2" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<!--package info-->
|
||||
<PackageId>DTLib.Web</PackageId>
|
||||
<Version>1.4.0</Version>
|
||||
<Version>1.3.0</Version>
|
||||
<Authors>Timerix</Authors>
|
||||
<Description>HTTP Server with simple routing</Description>
|
||||
<RepositoryType>GIT</RepositoryType>
|
||||
@ -11,7 +11,7 @@
|
||||
<Configuration>Release</Configuration>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<!--compilation properties-->
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<!--language features-->
|
||||
<LangVersion>latest</LangVersion>
|
||||
@ -25,6 +25,6 @@
|
||||
<ProjectReference Include="..\DTLib\DTLib.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
||||
<PackageReference Include="DTLib" Version="1.7.4" />
|
||||
<PackageReference Include="DTLib" Version="1.7.2" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@ -1,18 +1,15 @@
|
||||
namespace DTLib.Web;
|
||||
|
||||
/// <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods"/>
|
||||
[Flags]
|
||||
public enum HttpMethod : ushort
|
||||
public enum HttpMethod
|
||||
{
|
||||
NONE = 0,
|
||||
GET = 1,
|
||||
POST = 2,
|
||||
PUT = 4,
|
||||
DELETE = 8,
|
||||
PATCH = 16,
|
||||
HEAD = 32,
|
||||
OPTIONS = 64,
|
||||
TRACE = 128,
|
||||
CONNECT = 256,
|
||||
ANY = 65535
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
DELETE,
|
||||
PATCH,
|
||||
HEAD,
|
||||
OPTIONS,
|
||||
TRACE,
|
||||
CONNECT
|
||||
}
|
||||
@ -2,5 +2,5 @@ namespace DTLib.Web.Routes;
|
||||
|
||||
public interface IRouter
|
||||
{
|
||||
Task Resolve(HttpListenerContext ctx, ContextLogger requestLogger);
|
||||
Task<HttpStatusCode> Resolve(HttpListenerContext ctx, ContextLogger requestLogger);
|
||||
}
|
||||
@ -3,63 +3,42 @@ namespace DTLib.Web.Routes;
|
||||
public class SimpleRouter : IRouter
|
||||
{
|
||||
/// route for any url that doesn't have its own handler
|
||||
public record RouteWithMethod(HttpMethod method, IRouteHandler routeHandler)
|
||||
{
|
||||
public bool CheckMethod(HttpMethod requestMethod) => (requestMethod & method) != 0;
|
||||
|
||||
public bool CheckMethod(string requestMethodStr)
|
||||
=> Enum.TryParse<HttpMethod>(requestMethodStr, out var requestMethod)
|
||||
&& CheckMethod(requestMethod);
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, RouteWithMethod> _routes = new();
|
||||
public IRouteHandler? DefaultRoute { get; set; }
|
||||
|
||||
private readonly Dictionary<string, IRouteHandler> _routes = new();
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public RouteWithMethod? DefaultRoute { get; set; }
|
||||
|
||||
public SimpleRouter(ILogger logger)
|
||||
{
|
||||
_logger = new ContextLogger(nameof(SimpleRouter), logger);
|
||||
}
|
||||
|
||||
public void MapRoute(string url, HttpMethod method, IRouteHandler route)
|
||||
=> _routes.Add(url, new RouteWithMethod(method, route));
|
||||
public void MapRoute(string url, HttpMethod method, IRouteHandler route) => _routes.Add($"{url}:{method}", route);
|
||||
|
||||
public void MapRoute(string url, HttpMethod method,
|
||||
Func<HttpListenerContext, ContextLogger, Task<HttpStatusCode>> route)
|
||||
=> MapRoute(url, method, new DelegateRouteHandler(route));
|
||||
|
||||
public async Task Resolve(HttpListenerContext ctx, ContextLogger requestLogger)
|
||||
|
||||
public async Task<HttpStatusCode> Resolve(HttpListenerContext ctx, ContextLogger requestLogger)
|
||||
{
|
||||
HttpStatusCode status = HttpStatusCode.InternalServerError;
|
||||
try
|
||||
{
|
||||
string? requestPath = ctx.Request.Url?.AbsolutePath;
|
||||
if (string.IsNullOrEmpty(requestPath))
|
||||
requestPath = "/";
|
||||
|
||||
if(!_routes.TryGetValue(requestPath!, out var routeWithMethod))
|
||||
routeWithMethod = DefaultRoute;
|
||||
|
||||
string? requestPath = ctx.Request.Url?.AbsolutePath;
|
||||
if (string.IsNullOrEmpty(requestPath))
|
||||
requestPath = "/";
|
||||
if (!_routes.TryGetValue($"{requestPath}:{ctx.Request.HttpMethod}", out var route))
|
||||
route = DefaultRoute;
|
||||
|
||||
if (routeWithMethod is null)
|
||||
{
|
||||
_logger.LogWarn(nameof(SimpleRouter),
|
||||
$"couldn't resolve request path {ctx.Request.HttpMethod} {requestPath}");
|
||||
status = HttpStatusCode.NotFound;
|
||||
}
|
||||
else if (!routeWithMethod.CheckMethod(ctx.Request.HttpMethod))
|
||||
{
|
||||
_logger.LogWarn(nameof(SimpleRouter),
|
||||
$"received request with invalid method {ctx.Request.HttpMethod} {requestPath}");
|
||||
status = HttpStatusCode.MethodNotAllowed;
|
||||
}
|
||||
else status = await routeWithMethod.routeHandler.HandleRequest(ctx, requestLogger);
|
||||
}
|
||||
finally
|
||||
HttpStatusCode status;
|
||||
if (route == null)
|
||||
{
|
||||
ctx.Response.StatusCode = (int)status;
|
||||
await ctx.Response.OutputStream.FlushAsync();
|
||||
ctx.Response.OutputStream.Close();
|
||||
_logger.LogWarn(nameof(SimpleRouter), $"couldn't resolve request path {requestPath}");
|
||||
status = HttpStatusCode.NotFound;
|
||||
}
|
||||
else status = await route.HandleRequest(ctx, requestLogger);
|
||||
|
||||
ctx.Response.StatusCode = (int)status;
|
||||
await ctx.Response.OutputStream.FlushAsync();
|
||||
ctx.Response.OutputStream.Close();
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@ -58,11 +58,9 @@ public class WebApp
|
||||
requestLogger.LogInfo($"{ctx.Request.HttpMethod} {ctx.Request.RawUrl} from {ctx.Request.RemoteEndPoint}...");
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
await _router.Resolve(ctx, requestLogger);
|
||||
var status = await _router.Resolve(ctx, requestLogger);
|
||||
stopwatch.Stop();
|
||||
requestLogger.LogInfo($"responded {ctx.Response.StatusCode}" +
|
||||
$" ({(HttpStatusCode)ctx.Response.StatusCode})" +
|
||||
$" in {stopwatch.ElapsedMilliseconds}ms");
|
||||
requestLogger.LogInfo($"responded {(int)status} ({status}) in {stopwatch.ElapsedMilliseconds}ms");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 3e1a2c00e63c473a8db67ddfc18cf9d73ee4840a
|
||||
Subproject commit 9360dfe30549732bb95d16268218a6458d2229b3
|
||||
@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<!--package info-->
|
||||
<PackageId>DTLib</PackageId>
|
||||
<Version>1.7.4</Version>
|
||||
<Version>1.7.3</Version>
|
||||
<Authors>Timerix</Authors>
|
||||
<Description>Library for all my C# projects</Description>
|
||||
<RepositoryType>GIT</RepositoryType>
|
||||
@ -31,6 +31,6 @@
|
||||
<ProjectReference Include="..\DTLib.Demystifier\DTLib.Demystifier.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
|
||||
<PackageReference Include="DTLib.Demystifier" Version="1.1.1" />
|
||||
<PackageReference Include="DTLib.Demystifier" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user