1 /**
2 * Copyright © Yurai Web Framework 2021
3 * License: MIT (https://github.com/YuraiWeb/yurai/blob/main/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module yurai.core.server;
7 
8 import yurai.core.ihttprequest;
9 import yurai.core.ihttpresponse;
10 import yurai.external.iserver;
11 import yurai.services;
12 
13 void handleServer(IServer server, IHttpRequest request, IHttpResponse response)
14 {
15   import std.stdio : writeln, writefln;
16   if (!server)
17   {
18     return;
19   }
20 
21   bool fatalExit = false;
22 
23   Exception error = null;
24 
25   try
26   {
27     auto preMiddlewareServices = server.preServices;
28 
29     if (preMiddlewareServices)
30     {
31       bool handleMiddlewaresOnly = false;
32       bool exitMiddleware = false;
33 
34       foreach (service; preMiddlewareServices)
35       {
36         if (exitMiddleware)
37         {
38           break;
39         }
40 
41         auto state = service.handle(request);
42 
43         final switch (state)
44         {
45           case PreMiddlewareState.handleMiddlewaresOnly:
46             handleMiddlewaresOnly = true;
47             break;
48 
49           case PreMiddlewareState.exitFatal:
50             fatalExit = true;
51             throw new Exception("Fatal exit");
52 
53           case PreMiddlewareState.exit:
54             exitMiddleware = true;
55             break;
56 
57           case PreMiddlewareState.shouldContinue: break;
58         }
59       }
60 
61       if (handleMiddlewaresOnly || exitMiddleware)
62       {
63         return;
64       }
65     }
66 
67     auto contentMiddlewareServices = server.contentServices;
68 
69     if (contentMiddlewareServices)
70     {
71       bool exitMiddleware = false;
72 
73       foreach (service; contentMiddlewareServices)
74       {
75         if (exitMiddleware)
76         {
77           break;
78         }
79 
80         auto state = service.handle(request, response);
81 
82         final switch (state)
83         {
84           case ContentMiddlewareState.exitFatal:
85             fatalExit = true;
86             throw new Exception("Fatal exit");
87 
88           case ContentMiddlewareState.exit:
89             exitMiddleware = true;
90             break;
91 
92           case ContentMiddlewareState.shouldContinue: break;
93         }
94       }
95     }
96   }
97   catch (Exception e)
98   {
99       import std.stdio : writeln;
100 
101       writeln(e);
102 
103     if (fatalExit)
104     {
105       throw e;
106     }
107     else
108     {
109       error = e;
110     }
111   }
112   catch (Throwable t)
113   {
114     fatalExit = true;
115 
116     import std.stdio : writeln;
117 
118     writeln(t);
119 
120     throw t;
121   }
122   finally
123   {
124     if (!fatalExit)
125     {
126       auto postMiddlewareServices = server.postServices;
127 
128       if (postMiddlewareServices)
129       {
130         bool exitMiddleware = false;
131 
132         foreach (service; postMiddlewareServices)
133         {
134           if (exitMiddleware)
135           {
136             break;
137           }
138 
139           auto state = service.handle(request, response, error);
140 
141           final switch (state)
142           {
143             case PostMiddlewareState.exit:
144               exitMiddleware = true;
145               break;
146 
147             case PostMiddlewareState.shouldContinue: break;
148           }
149         }
150       }
151     }
152 
153     response.flush();
154   }
155 }