Implemented http request templates to provide model directly to http module handlers

This commit is contained in:
2020-02-24 15:53:15 +01:00
parent f12d31f706
commit aa63e598f2
9 changed files with 65 additions and 59 deletions
+3 -3
View File
@@ -33,9 +33,9 @@ namespace MTSC.UnitTests
.AddWebsocketHandler(new Common.WebSockets.ServerModules.EchoModule()))
.AddHandler(new HttpHandler()
.AddHttpModule(new HttpRoutingModule()
.AddRoute(HttpMessage.HttpMethods.Get, "/", new Http200Module())
.AddRoute(HttpMessage.HttpMethods.Get, "/query", new TestQueryModule())
.AddRoute(HttpMessage.HttpMethods.Get, "/echo", new EchoModule()))
.AddRoute(HttpMessage.HttpMethods.Get, "", new Http200Module())
.AddRoute(HttpMessage.HttpMethods.Get, "query", new TestQueryModule())
.AddRoute(HttpMessage.HttpMethods.Get, "echo", new EchoModule()))
.WithFragmentsExpirationTime(TimeSpan.FromSeconds(1))
.WithMaximumSize(300))
.AddLogger(new ConsoleLogger())
+2 -2
View File
@@ -4,9 +4,9 @@ using MTSC.Server;
namespace MTSC.UnitTests
{
public class EchoModule : IHttpRoute
public class EchoModule : HttpRouteBase
{
HttpResponse IHttpRoute.HandleRequest(HttpRequest request, ClientData client, Server.Server server)
public override HttpResponse HandleRequest(HttpRequest request, ClientData client, Server.Server server)
{
return new HttpResponse { BodyString = request.BodyString, StatusCode = HttpMessage.StatusCodes.OK };
}
+2 -2
View File
@@ -5,9 +5,9 @@ using System.Web;
namespace MTSC.UnitTests
{
class TestQueryModule : IHttpRoute
class TestQueryModule : HttpRouteBase
{
HttpResponse IHttpRoute.HandleRequest(HttpRequest request, ClientData client, Server.Server server)
public override HttpResponse HandleRequest(HttpRequest request, ClientData client, Server.Server server)
{
var query = HttpUtility.ParseQueryString(request.RequestQuery);
if(query.Count == 2 &&
+1 -1
View File
@@ -10,7 +10,7 @@ namespace MTSC.Common.Http
/// <summary>
/// Class encapsulating a http request.
/// </summary>
public class HttpRequest : ITemplatedHttpRequest
public class HttpRequest
{
public HttpRequestHeaderDictionary Headers { get; } = new HttpRequestHeaderDictionary();
@@ -1,6 +0,0 @@
namespace MTSC.Common.Http
{
public interface ITemplatedHttpRequest
{
}
}
@@ -2,9 +2,9 @@
namespace MTSC.Common.Http.RoutingModules
{
public class Http200Module : IHttpRoute
public class Http200Module : HttpRouteBase
{
HttpResponse IHttpRoute.HandleRequest(HttpRequest request, ClientData client, Server.Server server)
public override HttpResponse HandleRequest(HttpRequest request, ClientData client, Server.Server server)
{
return new HttpResponse { StatusCode = HttpMessage.StatusCodes.OK };
}
@@ -0,0 +1,42 @@
using MTSC.Server;
using System;
namespace MTSC.Common.Http.RoutingModules
{
public abstract class HttpRouteBase
{
public HttpResponse CallHandleRequest(HttpRequest request, ClientData client, Server.Server server)
{
return this.HandleRequest(request, client, server);
}
public abstract HttpResponse HandleRequest(HttpRequest request, ClientData client, Server.Server server);
}
public abstract class HttpRouteBase<T> : HttpRouteBase
{
private Func<HttpRequest, T> template;
public HttpRouteBase(Func<HttpRequest, T> template)
{
this.template = template;
}
public HttpRouteBase()
{
}
public HttpRouteBase WithTemplateProvider(Func<HttpRequest, T> templateProvider)
{
this.template = templateProvider;
return this;
}
public override HttpResponse HandleRequest(HttpRequest request, ClientData client, Server.Server server)
{
return HandleRequest(template.Invoke(request), client, server);
}
public abstract HttpResponse HandleRequest(T request, ClientData client, Server.Server server);
}
}
@@ -1,9 +0,0 @@
using MTSC.Server;
namespace MTSC.Common.Http.RoutingModules
{
public interface IHttpRoute<T> where T : ITemplatedHttpRequest
{
HttpResponse HandleRequest(T request, ClientData client, Server.Server server);
}
}
@@ -10,59 +10,37 @@ namespace MTSC.Common.Http.ServerModules
public class HttpRoutingModule : IHttpModule
{
private static Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse> alwaysEnabled = (server, request, client) => RouteEnablerResponse.Accept;
private static Func<HttpRequest, HttpRequest> noTemplate = (request) => request;
private Dictionary<HttpMethods, Dictionary<string, (IHttpRoute<ITemplatedHttpRequest>,
Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse>, Func<HttpRequest, ITemplatedHttpRequest> template)>> moduleDictionary =
new Dictionary<HttpMethods, Dictionary<string, (IHttpRoute<ITemplatedHttpRequest>,
Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse>, Func<HttpRequest, ITemplatedHttpRequest>)>>();
private Dictionary<HttpMethods, Dictionary<string, (HttpRouteBase,
Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse>)>> moduleDictionary =
new Dictionary<HttpMethods, Dictionary<string, (HttpRouteBase,
Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse>)>>();
public HttpRoutingModule()
{
foreach (HttpMethods method in (HttpMethods[])Enum.GetValues(typeof(HttpMethods)))
{
moduleDictionary[method] = new Dictionary<string, (IHttpRoute<ITemplatedHttpRequest>,
Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse>, Func<HttpRequest, ITemplatedHttpRequest> template)>();
moduleDictionary[method] = new Dictionary<string, (HttpRouteBase,
Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse>)>();
}
}
public HttpRoutingModule AddRoute(
HttpMethods method,
string uri,
IHttpRoute<ITemplatedHttpRequest> routeModule)
HttpRouteBase routeModule)
{
moduleDictionary[method][uri] = (routeModule, alwaysEnabled, noTemplate);
moduleDictionary[method][uri] = (routeModule, alwaysEnabled);
return this;
}
public HttpRoutingModule AddRoute(
HttpMethods method,
string uri,
IHttpRoute<ITemplatedHttpRequest> routeModule,
HttpRouteBase routeModule,
Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse> routeEnabler)
{
moduleDictionary[method][uri] = (routeModule, routeEnabler, noTemplate);
return this;
}
public HttpRoutingModule AddRoute(
HttpMethods method,
string uri,
IHttpRoute<ITemplatedHttpRequest> routeModule,
Func<HttpRequest, ITemplatedHttpRequest> requestTemplate)
{
moduleDictionary[method][uri] = (routeModule, alwaysEnabled, requestTemplate);
return this;
}
public HttpRoutingModule AddRoute(
HttpMethods method,
string uri,
IHttpRoute<ITemplatedHttpRequest> routeModule,
Func<Server.Server, HttpRequest, ClientData, RouteEnablerResponse> routeEnabler,
Func<HttpRequest, ITemplatedHttpRequest> requestTemplate)
{
moduleDictionary[method][uri] = (routeModule, routeEnabler, requestTemplate);
moduleDictionary[method][uri] = (routeModule, routeEnabler);
return this;
}
@@ -81,13 +59,14 @@ namespace MTSC.Common.Http.ServerModules
*/
if (moduleDictionary[request.Method].ContainsKey(request.RequestURI))
{
(var module, var routeEnabler, var requestTemplate) = moduleDictionary[request.Method][request.RequestURI];
(var module, var routeEnabler) = moduleDictionary[request.Method][request.RequestURI];
var routeEnablerResponse = routeEnabler.Invoke(server, request, client);
if (routeEnablerResponse is RouteEnablerResponse.RouteEnablerResponseAccept)
{
try
{
response = module.HandleRequest(requestTemplate.Invoke(request), client, server);
response = module.CallHandleRequest(request, client, server);
//response = module.HandleRequest(requestTemplate.Invoke(request), client, server);
}
catch(Exception e)
{