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 }