Add static serving

This commit is contained in:
GHXX 2024-01-15 19:56:14 +01:00
parent 8545ed80e9
commit 0814bc6b2d

View File

@ -187,13 +187,18 @@ public sealed class HttpServer {
private async Task ProcessRequestAsync(HttpListenerContext ctx) {
using RequestContext rc = new RequestContext(ctx);
try {
var decUri = WebUtility.UrlDecode(ctx.Request.RawUrl)!; // TODO add path escape countermeasures+unittests
var decUri = WebUtility.UrlDecode(ctx.Request.RawUrl)!; // TODO add path escape countermeasure-unittests
var splitted = decUri.Split('?', 2, StringSplitOptions.None);
var reqPath = NormalizeUrlPath(WebUtility.UrlDecode(splitted.First()));
string requestMethod = ctx.Request.HttpMethod.ToUpperInvariant();
bool wasStaticlyServed = false;
void LogRequest() {
requestLogger.Information($"{rc.ListenerContext.Response.StatusCode} {(wasStaticlyServed ? "static" : "endpnt")} {requestMethod} {decUri}");
}
try {
if (simpleEndpointMethodInfos.TryGetValue((reqPath, ctx.Request.HttpMethod.ToUpperInvariant()), out var endpointInvocationInfo)) {
if (simpleEndpointMethodInfos.TryGetValue((reqPath, requestMethod), out var endpointInvocationInfo)) {
var mi = endpointInvocationInfo.methodInfo;
var qparams = endpointInvocationInfo.queryParameters;
var args = splitted.Length == 2 ? splitted[1] : null;
@ -242,13 +247,27 @@ public sealed class HttpServer {
await (Task) (mi.Invoke(null, convertedQParamValues) ?? throw new NullReferenceException("Website func returned null unexpectedly"));
} else {
if (requestMethod == "GET")
foreach (var (k, v) in staticServePaths) {
if (k.StartsWith(reqPath)) { // do a static serve
// TODO finish and add path traversal checking
if (reqPath.StartsWith(k)) { // do a static serve
wasStaticlyServed = true;
var relativeStaticReqPath = reqPath[k.Length..];
var staticResponsePath = Path.Combine(v, relativeStaticReqPath);
if (Path.GetRelativePath(v, staticResponsePath).Contains("..")) {
requestLogger.Warning($"Blocked GET request to {reqPath} as somehow the target file does not lie inside the static serve folder? Are you using symlinks?");
await rc.SetStatusCodeAndDisposeAsync(HttpStatusCode.NotFound);
return;
}
break;
if (File.Exists(staticResponsePath)) {
rc.SetStatusCode(HttpStatusCode.OK);
using var f = File.OpenRead(v);
await f.CopyToAsync(rc.ListenerContext.Response.OutputStream);
} else {
await rc.SetStatusCodeAndDisposeAsync(HttpStatusCode.NotFound);
}
return;
}
}
@ -260,6 +279,8 @@ public sealed class HttpServer {
await HandleDefaultErrorPageAsync(rc, 500);
mainLogger.Fatal($"Caught otherwise uncaught exception while ProcessingRequest:\n{ex}");
}
LogRequest();
}