Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 5.81 KB | None | 0 0
  1. module core.bindselector;
  2.  
  3. private import std.typecons;
  4. private import std.variant;
  5. private import std.stdio;
  6. private import std.regexp;
  7. private import std.container;
  8. private import core.memory;
  9.  
  10. private import user.controllers;
  11. private import core.urlsupport;
  12. private import core.request;
  13. private import lib.generic_controllers;
  14.  
  15. // XXX Middlewares
  16. import core.middleware;
  17. import core.settings;
  18. import std.algorithm;
  19.  
  20.  
  21. struct InternalUrl {
  22.     string regex;
  23.     ControllerFunc controllerfunc;
  24.     Variant[string] userparams;
  25.     RegExp compiled = null;
  26. }
  27.  
  28. /*
  29.  * URLbinder is used to:
  30.  * · Load and keep the URLs, controllers and controller data internally
  31.  * · Compile the regexes so they can be tested quickly
  32.  * · Select the correct controller from a given URL and call it with the right parameters
  33.  */
  34.  
  35. class URLbinder
  36. {
  37.  
  38.     // Url definition lists
  39.     private SList!InternalUrl url_definition_list;
  40.    
  41.     // Middleware lists
  42.     private SList!IRequestMW _request_mws;
  43.     private SList!IResponseMW _response_mws;
  44.     private SList!IControllerMW _controller_mws;
  45.     private SList!IExceptionMW _exception_mws;
  46.  
  47.  
  48.     this(UrlDefinition[] definitions) {
  49.  
  50.         /* Take the user url definitions and parse them into a single linked list */    
  51.         foreach_reverse (def; definitions) {
  52.             url_definition_list.insertFront(InternalUrl(def.regex, def.controllerfunc, def.userparams, RegExp(def.regex)));
  53.         }
  54.         debug foreach (def; url_definition_list) writeln(def.regex);
  55.  
  56.         /+ XXX MIDDLEWARES: parseamos los middlewares de los settings y los metemos
  57.         en la lista que corresponda segun su tipo +/
  58.         _fill_middleware_lists(setting("Middlewares", null));
  59.     }
  60.  
  61.     /++ Split the middleware list on several sublist by the type of interface implemented
  62.     (note that a single middleware can be on several lists if it implementents several
  63.     interfaces)
  64.     +/
  65.     private void _fill_middleware_lists(IMiddleware[] all_middlewares)
  66.     {
  67.         if (all_middlewares is null || all_middlewares.length == 0)
  68.             return;
  69.  
  70.         foreach(IMiddleware mw; all_middlewares) {
  71.             if (cast(IRequestMW) mw)
  72.                 _request_mws.insertFront(mw);
  73.             if (cast(IResponseMW) mw)
  74.                 _response_mws.insertFront(mw);
  75.             if (cast(IControllerMW) mw)
  76.                 _controller_mws.insertFront(mw);
  77.             if (cast(IExceptionMW) mw)
  78.                 _exception_mws.insertFront(mw);
  79.         }
  80.  
  81.         // XXX: Comprobar que son estas y no las otras las que hay que invertir
  82.         if (!(_request_mws.empty()))
  83.             reverse(_request_mws);
  84.         if (!(_controller_mws.empty()))
  85.             reverse(_controller_mws);
  86.     }
  87.  
  88.  
  89.     /* Takes a URL as input, search for the first matching regexp in
  90.      * the url definitions and call the specified controller function
  91.      * if found, or 404 if not
  92.      */
  93.     public string call_controller_from_url(string url, HttpRequest request) {
  94.         // Call the request middlewares first, stops here is one returns an HttpResponse
  95.         HttpResponse response = _apply_request_mws(request);
  96.  
  97.         if (response is null) {
  98.             try {
  99.                 foreach (urldef; url_definition_list) {
  100.                     auto res = urldef.compiled.match(url);
  101.  
  102.                     if (res.length > 0) {
  103.                         // Bingo, the url matches the regexp
  104.                         string[] urlparams;
  105.  
  106.                         if (res.length > 1)
  107.                             urlparams = res[1..$];
  108.  
  109.                         // Call the controllers middleware
  110.                         response = _apply_controller_mws(urldef.controllerfunc, request);
  111.                         if (response is null)
  112.                             try {
  113.                                 response = urldef.controllerfunc(request, urlparams, urldef.userparams);
  114.                             } catch (Exception exc) {
  115.                                 // Call the exception middlewares, re-raise if all return null
  116.                                 response = _apply_exception_mws(exc, urldef.controllerfunc, request);
  117.                                 if (response is null) throw exc;
  118.                             }
  119.                     }
  120.                 }
  121.             } catch (Exception exc) {
  122.                 response = controller_500(request, url, exc);
  123.             }
  124.  
  125.             if (response is null)
  126.                 response = controller_404(request, url);
  127.         }
  128.  
  129.         // before returning the response call all the response middlewares on it
  130.         return _apply_response_mws(response);
  131.     }
  132.  
  133.     private HttpResponse _apply_request_mws(ref HttpRequest request)
  134.     {
  135.         HttpResponse response = null;
  136.         foreach(IRequestMW reqmw; _request_mws) {
  137.             response = reqmw.process_request(request);
  138.             if (response !is null) break;
  139.         }
  140.         return response;
  141.     }
  142.  
  143.     private HttpResponse _apply_controller_mws(ControllerFunc func, ref HttpRequest request)
  144.     {
  145.         HttpResponse response = null;
  146.         foreach(IControllerMW contmw; _controller_mws) {
  147.             response = contmw.process_controller(func, request);
  148.             if (response !is null) break;
  149.         }
  150.     }
  151.  
  152.     private HttpResponse _apply_exception_mws(Exception exc, ControllerFunc func, HttpRequest request)
  153.     {
  154.         HttpResponse response = null;
  155.         foreach(IExceptionMW excmw; _exception_mws) {
  156.             response = excmw.process_exception(exc, func, request);
  157.             if (response !is null) break;
  158.         }
  159.     }
  160.  
  161.     private HttpResponse _apply_response_mws(ref HttpResponse response)
  162.     {
  163.         foreach(IResponseMW respmw; _response_mws) {
  164.             respmw.process_response(response);
  165.         }
  166.         return response;
  167.     }
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement