tesses.http/Tesses.Http/MountableServer.cs

90 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Tesses.Http
{
/// <summary>
/// mount multiple servers at different url paths
/// </summary>
public sealed class MountableServer : IRequestHandler
{
Dictionary<string, IRequestHandler> _servers = new Dictionary<string, IRequestHandler>();
public MountableServer(IRequestHandler root)
{
_root = root;
}
IRequestHandler _root;
private (string Key,IRequestHandler Value) GetFromPath(ServerContext ctx)
{
string path = ctx.Request.GetQueryParameters(ctx.Request.CurrentUrl,new Dictionary<string, List<string>>());
//bool j = false;
foreach(var item in _servers.Reverse())
{
if(path.StartsWith(item.Key,StringComparison.Ordinal))
{
return (item.Key,RequestHandler.Guaranteed(ctx,item.Value));
}
if (path == item.Key.TrimEnd('/'))
{
path += "/";
return (item.Key,RequestHandler.Guaranteed(ctx,item.Value));
}
}
//Console.WriteLine("HERE WE ARE");
return ("/",RequestHandler.Guaranteed(ctx,_root));
}
/// <summary>
/// Mount the specified url and server.
/// Must mount like this
/// /somePath0
/// /somePath0/someSubPath0
/// /somePath0/someSubPath0/someSubSubPath0
/// /somePath0/someSubPath0/someSubSubPath1
/// /somePath0/someSubPath1
/// /somePath0/someSubPath1/someSubSubPath0
/// /somePath0/someSubPath1/someSubSubPath1
/// </summary>
/// <param name="url">URL.</param>
/// <param name="server">Server.</param>
public void Mount(string url,IRequestHandler server)
{
_servers.Add(url, server);
}
/// <summary>
/// Unmount a server
/// </summary>
/// <param name="url">Url</param>
public void Unmount(string url)
{
_servers.Remove(url);
}
/// <summary>
/// Unmount all servers
/// </summary>
public void UnmountAll()
{
_servers.Clear();
}
public async Task Handle(ServerContext ctx)
{
var v = GetFromPath(ctx);
string[] curUrl =ctx.Request.CurrentUrl.Split(new char[]{'?'},2,StringSplitOptions.RemoveEmptyEntries);
string url = '/' + curUrl[0].Substring(v.Key.Length).TrimStart('/');
if(curUrl.Length > 1)
{
url += $"?{curUrl[1]}";
}
ctx.Request.CurrentUrl = url;
await v.Value.Handle(ctx);
}
}
}