Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module core.bindselector;
- private import std.typecons;
- private import std.variant;
- private import std.stdio;
- private import std.regexp;
- private import std.container;
- private import core.memory;
- private import user.controllers;
- private import core.urlsupport;
- private import core.request;
- private import lib.generic_controllers;
- // XXX Middlewares
- import core.middleware;
- import core.settings;
- import std.algorithm;
- struct InternalUrl {
- string regex;
- ControllerFunc controllerfunc;
- Variant[string] userparams;
- RegExp compiled = null;
- }
- /*
- * URLbinder is used to:
- * · Load and keep the URLs, controllers and controller data internally
- * · Compile the regexes so they can be tested quickly
- * · Select the correct controller from a given URL and call it with the right parameters
- */
- class URLbinder
- {
- // Url definition lists
- private SList!InternalUrl url_definition_list;
- // Middleware lists
- private SList!IRequestMW _request_mws;
- private SList!IResponseMW _response_mws;
- private SList!IControllerMW _controller_mws;
- private SList!IExceptionMW _exception_mws;
- this(UrlDefinition[] definitions) {
- /* Take the user url definitions and parse them into a single linked list */
- foreach_reverse (def; definitions) {
- url_definition_list.insertFront(InternalUrl(def.regex, def.controllerfunc, def.userparams, RegExp(def.regex)));
- }
- debug foreach (def; url_definition_list) writeln(def.regex);
- /+ XXX MIDDLEWARES: parseamos los middlewares de los settings y los metemos
- en la lista que corresponda segun su tipo +/
- _fill_middleware_lists(setting("Middlewares", null));
- }
- /++ Split the middleware list on several sublist by the type of interface implemented
- (note that a single middleware can be on several lists if it implementents several
- interfaces)
- +/
- private void _fill_middleware_lists(IMiddleware[] all_middlewares)
- {
- if (all_middlewares is null || all_middlewares.length == 0)
- return;
- foreach(IMiddleware mw; all_middlewares) {
- if (cast(IRequestMW) mw)
- _request_mws.insertFront(mw);
- if (cast(IResponseMW) mw)
- _response_mws.insertFront(mw);
- if (cast(IControllerMW) mw)
- _controller_mws.insertFront(mw);
- if (cast(IExceptionMW) mw)
- _exception_mws.insertFront(mw);
- }
- // XXX: Comprobar que son estas y no las otras las que hay que invertir
- if (!(_request_mws.empty()))
- reverse(_request_mws);
- if (!(_controller_mws.empty()))
- reverse(_controller_mws);
- }
- /* Takes a URL as input, search for the first matching regexp in
- * the url definitions and call the specified controller function
- * if found, or 404 if not
- */
- public string call_controller_from_url(string url, HttpRequest request) {
- // Call the request middlewares first, stops here is one returns an HttpResponse
- HttpResponse response = _apply_request_mws(request);
- if (response is null) {
- try {
- foreach (urldef; url_definition_list) {
- auto res = urldef.compiled.match(url);
- if (res.length > 0) {
- // Bingo, the url matches the regexp
- string[] urlparams;
- if (res.length > 1)
- urlparams = res[1..$];
- // Call the controllers middleware
- response = _apply_controller_mws(urldef.controllerfunc, request);
- if (response is null)
- try {
- response = urldef.controllerfunc(request, urlparams, urldef.userparams);
- } catch (Exception exc) {
- // Call the exception middlewares, re-raise if all return null
- response = _apply_exception_mws(exc, urldef.controllerfunc, request);
- if (response is null) throw exc;
- }
- }
- }
- } catch (Exception exc) {
- response = controller_500(request, url, exc);
- }
- if (response is null)
- response = controller_404(request, url);
- }
- // before returning the response call all the response middlewares on it
- return _apply_response_mws(response);
- }
- private HttpResponse _apply_request_mws(ref HttpRequest request)
- {
- HttpResponse response = null;
- foreach(IRequestMW reqmw; _request_mws) {
- response = reqmw.process_request(request);
- if (response !is null) break;
- }
- return response;
- }
- private HttpResponse _apply_controller_mws(ControllerFunc func, ref HttpRequest request)
- {
- HttpResponse response = null;
- foreach(IControllerMW contmw; _controller_mws) {
- response = contmw.process_controller(func, request);
- if (response !is null) break;
- }
- }
- private HttpResponse _apply_exception_mws(Exception exc, ControllerFunc func, HttpRequest request)
- {
- HttpResponse response = null;
- foreach(IExceptionMW excmw; _exception_mws) {
- response = excmw.process_exception(exc, func, request);
- if (response !is null) break;
- }
- }
- private HttpResponse _apply_response_mws(ref HttpResponse response)
- {
- foreach(IResponseMW respmw; _response_mws) {
- respmw.process_response(response);
- }
- return response;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement