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