using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Tesses.Http { /// /// mount multiple servers at different url paths /// public sealed class MountableServer : IRequestHandler { Dictionary _servers = new Dictionary(); 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>()); //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)); } /// /// 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 /// /// URL. /// Server. public void Mount(string url,IRequestHandler server) { _servers.Add(url, server); } /// /// Unmount a server /// /// Url public void Unmount(string url) { _servers.Remove(url); } /// /// Unmount all servers /// 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); } } }