1 /** 2 * Модуль реализует концепцию Middleware 3 * 4 * Copyright: (c) 2015-2017, Milofon Project. 5 * License: Subject to the terms of the BSD license, as written in the included LICENSE.txt file. 6 * Authors: Maksim Galanin 7 */ 8 module dango.controller.middleware; 9 10 private 11 { 12 import std.container.slist : SList; 13 14 import vibe.http.server; 15 } 16 17 18 alias MiddlewareHandler(P...) = void delegate(P); 19 20 21 interface Middleware(P...) 22 { 23 bool processRequest(P args); 24 25 bool processResponse(P args); 26 27 bool processException(P args); 28 } 29 30 31 abstract class BaseMiddleware(P...) : Middleware!P 32 { 33 bool processRequest(P args) 34 { 35 return true; 36 } 37 38 39 bool processResponse(P args) 40 { 41 return true; 42 } 43 44 45 bool processException(P args) 46 { 47 return true; 48 } 49 } 50 51 52 abstract class MiddlewareController(P...) 53 { 54 alias Handler = MiddlewareHandler!P; 55 56 protected 57 { 58 Middleware!P[] _middlewares; 59 } 60 61 62 void addMiddleware(Middleware!P middleware) 63 { 64 _middlewares ~= middleware; 65 } 66 67 68 bool requestHandler(P args) 69 { 70 foreach (mdw; _middlewares) 71 { 72 if (!mdw.processRequest(args)) 73 return false; 74 } 75 76 return true; 77 } 78 79 80 void responseHandler(P args) 81 { 82 foreach_reverse (mdw; _middlewares) 83 { 84 if (!mdw.processResponse(args)) 85 return; 86 } 87 } 88 89 90 void exceptionHandler(Exception e, P args) 91 { 92 foreach_reverse (mdw; _middlewares) 93 { 94 if (!mdw.processException(args)) 95 return; 96 } 97 } 98 } 99 100 101 class HTTPMiddlewareController : MiddlewareController!(HTTPServerRequest, HTTPServerResponse), HTTPServerRequestHandler 102 { 103 private 104 { 105 HTTPServerRequestHandler _handler; 106 } 107 108 109 this(HTTPServerRequestHandler handler) 110 { 111 _handler = handler; 112 } 113 114 115 void handleRequest(HTTPServerRequest req, HTTPServerResponse res) @safe 116 { 117 () @trusted { 118 if (!requestHandler(req, res)) 119 return; 120 121 try 122 _handler.handleRequest(req, res); 123 catch (Exception e) 124 { 125 exceptionHandler(e, req, res); 126 return; 127 } 128 129 responseHandler(req, res); 130 } (); 131 } 132 } 133