90 lines
2.8 KiB
C#
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);
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|