1 module hunt.framework.provider.HttpServiceProvider; 2 3 import hunt.framework.controller.Controller; 4 import hunt.framework.config.ApplicationConfig; 5 import hunt.framework.config.ConfigManager; 6 import hunt.framework.http.HttpErrorResponseHandler; 7 import hunt.framework.Init; 8 import hunt.framework.provider.ServiceProvider; 9 import hunt.framework.routing; 10 11 import hunt.http.routing.RoutingContext; 12 import hunt.http.routing.RouterManager; 13 import hunt.http.server.HttpServer; 14 import hunt.http.server.HttpServerOptions; 15 import hunt.http.server.WebSocketHandler; 16 import hunt.http.WebSocketPolicy; 17 import hunt.http.WebSocketCommon; 18 19 import hunt.logging; 20 21 import poodinis; 22 23 import core.time; 24 import std.array; 25 import std.exception; 26 import std.conv; 27 import std.container.array; 28 import std.file; 29 import std.path; 30 import std.socket; 31 import std.stdio; 32 import std.string; 33 import std.uni; 34 35 /** 36 * 37 */ 38 class HttpServiceProvider : ServiceProvider { 39 40 override void register() { 41 container.register!HttpServer.initializedBy(&buildServer).singleInstance(); 42 } 43 44 private HttpServer buildServer() { 45 DefaultErrorResponseHandler.Default = new HttpErrorResponseHandler(); 46 ConfigManager manager = container.resolve!ConfigManager; 47 ApplicationConfig appConfig = container.resolve!ApplicationConfig(); 48 auto staticFilesConfig = appConfig.staticfiles; 49 // SimpleWebSocketHandler webSocketHandler = new SimpleWebSocketHandler(); 50 // webSocketHandler.setWebSocketPolicy(_webSocketPolicy); 51 52 //if(conf.webSocketFactory) 53 // _wfactory = conf.webSocketFactory; 54 55 // Building http server 56 // HttpServerOptions options = new HttpServerOptions(); 57 HttpServer.Builder hsb = HttpServer.builder() 58 .setListener(appConfig.http.port, appConfig.http.address) 59 .workerThreadSize(appConfig.http.workerThreads) 60 .maxRequestSize(cast(int)appConfig.http.maxHeaderSize) 61 .maxFileSize(cast(int)appConfig.upload.maxSize) 62 .ioThreadSize(appConfig.http.ioThreads) 63 .canUpgrade(appConfig.http.canUpgrade) 64 .resourceCacheTime(staticFilesConfig.cacheTime.seconds); 65 66 version(WITH_HUNT_TRACE) { 67 hsb.localServiceName(appConfig.application.name) 68 .isB3HeaderRequired(appConfig.trace.b3Required); 69 } 70 71 72 RouteConfigManager routeConfig = container.resolve!RouteConfigManager(); 73 RouteItem[][RouteGroup] allRoutes = routeConfig.allRoutes; 74 75 foreach(RouteGroup group, RouteItem[] routes; allRoutes) { 76 foreach (RouteItem item; routes) { 77 addRoute(hsb, item, group); 78 } 79 80 RouteGroupType groupType = RouteGroupType.Host; 81 if (group.type == "path") { 82 groupType = RouteGroupType.Path; 83 } 84 // if(!isRootStaticPathAdded) { 85 // default static files 86 hsb.resource("/", staticFilesConfig.location, staticFilesConfig.canList, group.value, groupType); 87 // } 88 } 89 90 // default static files 91 hsb.resource("/", staticFilesConfig.location, staticFilesConfig.canList); 92 // hsb.setDefaultRequest((RoutingContext ctx) { 93 // string content = "The resource " ~ ctx.getURI().getPath() ~ " is not found"; 94 // string title = "404 - Not Found"; 95 96 // ctx.responseHeader(HttpHeader.CONTENT_TYPE, "text/html"); 97 98 // ctx.write("<!DOCTYPE html>") 99 // .write("<html>") 100 // .write("<head>") 101 // .write("<title>") 102 // .write(title) 103 // .write("</title>") 104 // .write("</head>") 105 // .write("<body>") 106 // .write("<h1> " ~ title ~ " </h1>") 107 // .write("<p>" ~ content ~ "</p>") 108 // .write("</body>") 109 // .end("</html>"); 110 // }); 111 112 return hsb.build(); 113 } 114 115 116 private void addRoute(HttpServer.Builder hsb, RouteItem item, RouteGroup group) { 117 ResourceRouteItem resourceItem = cast(ResourceRouteItem) item; 118 119 // add route for static files 120 if (resourceItem !is null) { 121 // if(resourceItem.path == "/") isRootStaticPathAdded = true; 122 if (group is null || group.type == RouteGroup.DEFAULT) { 123 hsb.resource(resourceItem.path, resourceItem.resourcePath, 124 resourceItem.canListing); 125 } else if (group.type == RouteGroup.HOST || group.type == RouteGroup.DOMAIN) { 126 hsb.resource(resourceItem.path, resourceItem.resourcePath, 127 resourceItem.canListing, group.value, RouteGroupType.Host); 128 } else if (group.type == RouteGroup.PATH) { 129 hsb.resource(resourceItem.path, resourceItem.resourcePath, 130 resourceItem.canListing, group.value, RouteGroupType.Path); 131 } else { 132 errorf("Unknown route group type: %s", group.type); 133 } 134 } else { // add route for controller action 135 string handlerKey = makeRouteHandlerKey(cast(ActionRouteItem) item, group); 136 RoutingHandler handler = getRouteHandler(handlerKey); 137 // warning(item.toString()); 138 if (handler is null) { 139 version(HUNT_DEBUG) { 140 warningf("No handler found for group route {%s}, key: %s", item.toString(), handlerKey); 141 } 142 } else { 143 version(HUNT_FM_DEBUG) 144 tracef("handler found for group route {%s}, key: %s", item.toString(), handlerKey); 145 string[] methods = item.methods; 146 version(HUNT_DEBUG) { 147 string methodsString = "[*]"; 148 if(!methods.empty) 149 methodsString = methods.to!string(); 150 } 151 152 RouterContex contex = new RouterContex(); 153 contex.routeGroup = group; 154 contex.routeItem = item; 155 156 if (group is null || group.type == RouteGroup.DEFAULT) { 157 version(HUNT_DEBUG) infof("adding %s %s into DEFAULT", methodsString, item.path); 158 hsb.addRoute([item.path], methods, handler, null, 159 RouteGroupType.Default, RouterContex.stringof, contex); 160 } else if (group.type == RouteGroup.HOST || group.type == RouteGroup.DOMAIN) { 161 version(HUNT_DEBUG) infof("adding %s %s into DOMAIN", methodsString, item.path); 162 hsb.addRoute([item.path], methods, handler, group.value, 163 RouteGroupType.Host, RouterContex.stringof, contex); 164 } else if (group.type == RouteGroup.PATH) { 165 version(HUNT_DEBUG) infof("adding %s %s into PATH", methodsString, item.path); 166 hsb.addRoute([item.path], methods, handler, group.value, 167 RouteGroupType.Path, RouterContex.stringof, contex); 168 } else { 169 errorf("Unknown route group type: %s", group.type); 170 } 171 } 172 } 173 } 174 }