routes for common file types

This commit is contained in:
timerix 2023-11-10 14:45:07 +06:00
parent 03e661a777
commit 91cf996fa9

View File

@ -3,11 +3,13 @@
public class Router
{
private Dictionary<string, Func<HttpListenerContext, int>> routes = new();
private Func<HttpListenerContext, int> rejectDelegate;
private readonly IOPath publicDirPath = "./public";
private readonly IOPath homepagePath = "./public/html/index.html";
private readonly IOPath pare404Path = "./public/html/404.html";
public Router()
{
routes.Add("/", ctx =>
routes.Add("UwU", ctx =>
{
var buffer = "<html><body><h1>UwU</h1></body></html>".ToBytes();
ctx.Response.ContentLength64 = buffer.Length;
@ -15,18 +17,64 @@ public class Router
ctx.Response.OutputStream.Flush();
return 200;
});
rejectDelegate = ctx =>
{
ctx.Response.ContentLength64 = 0;
return 500;
};
}
public bool TryResolve(HttpListenerContext ctx)
{
int status = routes.TryGetValue(ctx.Request.Url!.AbsolutePath, out var routeDelegate)
? routeDelegate(ctx)
: rejectDelegate(ctx);
int status;
if (routes.TryGetValue(ctx.Request.Url!.AbsolutePath, out var routeDelegate))
status = routeDelegate(ctx);
else if(ctx.Request.HttpMethod == "GET")
{
string urlPath = ctx.Request.Url.AbsolutePath;
var ext = Path.Extension(urlPath).Str;
IOPath filePath;
switch (ext)
{
case "html":
filePath = Path.Concat(publicDirPath, "html", urlPath);
ctx.Response.Headers.Set("Content-Type", "text/html");
break;
case "css":
filePath = Path.Concat(publicDirPath, "css", urlPath);
ctx.Response.Headers.Set("Content-Type", "text/css");
break;
case "js":
filePath = Path.Concat(publicDirPath, "js", urlPath);
ctx.Response.Headers.Set("Content-Type", "text/javascript");
break;
default:
if (urlPath == "/")
{
filePath = homepagePath;
ctx.Response.Headers.Set("Content-Type", "text/html");
break;
}
filePath = Path.Concat(publicDirPath, urlPath);
ctx.Response.Headers.Set("Content-Type", "binary/octet-stream");
ctx.Response.Headers.Set("Content-Disposition", "attachment filename="+filePath.LastName());
break;
}
if (File.Exists(filePath))
status = 200;
else
{
status = 404;
filePath = Path.Concat(publicDirPath, "html", pare404Path);
ctx.Response.Headers.Set("Content-Type", "text/html");
}
var fileStream = File.OpenRead(filePath);
ctx.Response.ContentLength64 = fileStream.Length;
fileStream.CopyTo(ctx.Response.OutputStream);
}
// reject all incorrect requests
else
{
status = 500;
ctx.Response.ContentLength64 = 0;
}
ctx.Response.StatusCode = status;
ctx.Response.OutputStream.Flush();
ctx.Response.OutputStream.Close();