using System; using System.Text.RegularExpressions; using System.Collections.Generic; using System.Text; namespace ln.http { public class SimpleHttpRouter : IHttpRouter { List routes = new List(); public SimpleHttpRouter() { } 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[] { '/' },StringSplitOptions.RemoveEmptyEntries); StringBuilder stringBuilder = new StringBuilder("^"); foreach (string part in parts) { if (part.StartsWith(":", StringComparison.InvariantCulture)) stringBuilder.AppendFormat("/(?<{0}>[^/]+)", part.Substring(1)); else if (part.Equals("*")) stringBuilder.AppendFormat("/(?<_>.*)"); else stringBuilder.AppendFormat("/{0}", part); } stringBuilder.Append("/?$"); AddRoute(stringBuilder.ToString(), 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 HttpResponse Route(string path, HttpRequest httpRequest) { foreach (SimpleRoute simpleRoute in routes.ToArray()) { Match match = simpleRoute.Route.Match(path); if (match.Success) { string residual = ""; foreach (Group group in match.Groups) { httpRequest?.SetParameter(group.Name, group.Value); if (group.Name.Equals("_")) residual = group.Value; } return simpleRoute.Target.Route(residual,httpRequest); } } throw new KeyNotFoundException(); } 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; } } } }