98 lines
3.9 KiB
C#
98 lines
3.9 KiB
C#
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<SimpleRoute> routes = new List<SimpleRoute>();
|
|
public SimpleRoute[] Routes => routes.ToArray();
|
|
|
|
public SimpleRouter()
|
|
{
|
|
}
|
|
|
|
public void AddSimpleRoute(string simpleRoute, Func<HttpRoutingContext, HttpRequest, HttpResponse> target) => AddSimpleRoute(simpleRoute, new RouterTarget(target));
|
|
public void AddSimpleRoute(string simpleRoute, Func<string, HttpRequest, HttpResponse> target) => AddSimpleRoute(simpleRoute, new RouterTarget(target));
|
|
public void AddSimpleRoute(string simpleRoute, Func<HttpRequest, HttpResponse> 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;
|
|
}
|
|
}
|
|
}
|
|
}
|