using System; using System.Text.RegularExpressions; using System.Collections.Generic; using System.Text; using System.Linq; namespace ln.http.router { public class SimpleRouter : IHttpRouter { List routes = new List(); public SimpleRoute[] Routes => routes.ToArray(); public SimpleRouter() { } public void AddSimpleRoute(string simpleRoute, Func target) => AddSimpleRoute(simpleRoute, new RouterTarget(target)); public void AddSimpleRoute(string simpleRoute, Func target) => AddSimpleRoute(simpleRoute, new RouterTarget(target)); public void AddSimpleRoute(string simpleRoute, Func target) => AddSimpleRoute(simpleRoute, new RouterTarget(target)); public void AddSimpleRoute(string simpleRoute, IHttpRouter target) => AddSimpleRoute(simpleRoute, target, simpleRoute.Split('/').Length); public void AddSimpleRoute(string simpleRoute, IHttpRouter target, int priority) { string[] parts = simpleRoute.Split(new char[] { '/' }); string[] reparts = parts.Select((part) => { if (part.StartsWith(":", StringComparison.InvariantCulture)) if (part.EndsWith("*", StringComparison.InvariantCulture)) return string.Format("(?<{0}>[^/]+)(?<_>/.*)?", part.Substring(1, part.Length - 2)); else return string.Format("(?<{0}>[^/]+)", part.Substring(1)); else if (part.Equals("*")) return string.Format("(?<_>.*)"); else return string.Format("{0}", part); }).ToArray(); string reroute = string.Join("/", reparts); AddRoute(reroute, target, priority); } public void AddRoute(String route, IHttpRouter target) => AddRoute(route, target, 0); public void AddRoute(String route, IHttpRouter target,int priority) { lock (this) { routes.Add(new SimpleRoute(route, target, priority)); routes.Sort((SimpleRoute a, SimpleRoute b) => b.Priority - a.Priority); } } public void Remove(SimpleRoute simpleRoute) => routes.Remove(simpleRoute); public HttpResponse Route(HttpRoutingContext routingContext, HttpRequest httpRequest) { foreach (SimpleRoute simpleRoute in routes.ToArray()) { Match match = simpleRoute.Route.Match(routingContext.Path); if (match.Success) { string residual = ""; foreach (Group group in match.Groups) { httpRequest?.SetParameter(group.Name, group.Value); if (group.Name.Equals("_")) if (group.Value.StartsWith("/", StringComparison.InvariantCulture)) residual = group.Value; else residual = "/" + group.Value; } HttpResponse response = simpleRoute.Target.Route(routingContext.Routed(residual), httpRequest); if (response != null) return response; } } return null; } public class SimpleRoute { public int Priority { get; } public Regex Route { get; } public IHttpRouter Target { get; } public SimpleRoute(string regex, IHttpRouter target) : this(regex, target, 0) { } public SimpleRoute(string regex, IHttpRouter target,int priority) { Route = new Regex(regex); Target = target; Priority = priority; } } } }