1 module hunt.http.routing.impl.RoutingContextImpl; 2 3 import hunt.http.routing.impl.RouterImpl; 4 5 import hunt.http.routing.handler; 6 import hunt.http.routing.Router; 7 import hunt.http.routing.RouterManager; 8 import hunt.http.routing.RoutingContext; 9 10 import hunt.http.HttpConnection; 11 import hunt.http.HttpMetaData; 12 import hunt.http.HttpOutputStream; 13 14 import hunt.http.server.HttpServerContext; 15 import hunt.http.server.HttpServerRequest; 16 import hunt.http.server.HttpServerResponse; 17 import hunt.http.server.HttpSession; 18 19 import hunt.collection; 20 import hunt.concurrency.Promise; 21 import hunt.Exceptions; 22 import hunt.Functions; 23 import hunt.io.BufferUtils; 24 import hunt.logging; 25 import hunt.stream.Common; 26 import hunt.util.Common; 27 28 import std.algorithm; 29 import std.container; 30 import std.string; 31 import std.variant; 32 33 /** 34 * 35 */ 36 class RoutingContextImpl : RoutingContext { 37 private HttpServerRequest request; 38 private NavigableSet!(RouterMatchResult) routers; 39 private RouterMatchResult current; 40 private HttpSessionHandler httpSessionHandler; 41 private Variant[string] _attributes; 42 // private TemplateHandlerSPI templateHandlerSPI = TemplateHandlerSPILoader.getInstance().getTemplateHandlerSPI(); 43 private bool asynchronousRead = false; 44 // private ConcurrentLinkedDeque<Promise<?>> handlerPromiseQueue; 45 private HttpServerContext _context; 46 private string _groupName = "default"; 47 48 this(HttpServerContext context, NavigableSet!(RouterMatchResult) routers) { 49 _context = context; 50 request = _context.httpRequest(); 51 this.routers = routers; 52 } 53 54 override Variant getAttribute(string key) { 55 return _attributes.get(key, Variant()); 56 } 57 58 override void setAttribute(string key, Variant value) { 59 _attributes[key] = value; 60 } 61 62 override Variant removeAttribute(string key) { 63 Variant v = _attributes[key]; 64 _attributes.remove(key); 65 return v; 66 } 67 68 override Variant[string] getAttributes() { 69 return _attributes; 70 } 71 72 override HttpServerRequest getRequest() { 73 return request; 74 } 75 76 override HttpServerResponse getResponse() { 77 return _context.httpResponse(); 78 } 79 80 override void response(HttpServerResponse response) { 81 _context.httpResponse = response; 82 } 83 84 // override 85 // HttpResponse getAsyncResponse() { 86 // return request.getAsyncResponse(); 87 // } 88 89 override OutputStream outputStream() { 90 return _context.outputStream(); 91 } 92 93 override string getRouterParameter(string name) { 94 if(current is null) { 95 throw new Exception("Call next() first."); 96 } 97 return current.getParameters().get(name); 98 } 99 100 // override 101 // RoutingContext onContent(Action1!ByteBuffer handler) { 102 // getRequest().onContent(handler); 103 // asynchronousRead = true; 104 // return this; 105 // } 106 107 // override 108 // RoutingContext onContentComplete(Action1!HttpRequest handler) { 109 // getRequest().onContentComplete(handler); 110 // asynchronousRead = true; 111 // return this; 112 // } 113 114 // override 115 // RoutingContext onMessageComplete(Action1!HttpRequest handler) { 116 // getRequest().onMessageComplete(handler); 117 // asynchronousRead = true; 118 // return this; 119 // } 120 121 override bool isAsynchronousRead() { 122 return asynchronousRead; 123 } 124 125 override void enableAsynchronousRead() { 126 asynchronousRead = true; 127 } 128 129 override void next() { 130 current = routers.pollFirst(); 131 if (current is null) { 132 version(HUNT_HTTP_DEBUG) warning("No router found."); 133 return; 134 } 135 136 Router r = current.getRouter(); 137 version (HUNT_HTTP_DEBUG) { 138 infof("current router: %d", r.getId()); 139 } 140 141 Map!(string, string) routeParameters = current.getParameters(); 142 if(routeParameters !is null) { 143 foreach(string key, string value; routeParameters) { 144 // if(key.startsWith("param")) continue; 145 version(HUNT_HTTP_DEBUG) tracef("Adding route parameters, name=%s, value=%s", key, value); 146 request.putQueryParameter(key, value); 147 } 148 } 149 150 r.handle(this); 151 return; 152 } 153 154 override bool hasNext() { 155 return !routers.isEmpty(); 156 } 157 158 // override 159 // <T> RoutingContext complete(Promise<T> promise) { 160 // ConcurrentLinkedDeque<Promise<T>> queue = createHandlerPromiseQueueIfAbsent(); 161 // queue.push(promise); 162 // return this; 163 // } 164 165 // override 166 // <T> bool next(Promise<T> promise) { 167 // return complete(promise).next(); 168 // } 169 170 // override 171 // <T> void succeed(T t) { 172 // Optional.ofNullable(handlerPromiseQueue) 173 // .map(ConcurrentLinkedDeque::pop) 174 // .map(p -> (Promise<T>) p) 175 // .ifPresent(p -> p.succeeded(t)); 176 // } 177 178 // override 179 // void fail(Throwable x) { 180 // Optional.ofNullable(handlerPromiseQueue) 181 // .map(ConcurrentLinkedDeque::pop) 182 // .ifPresent(p -> p.failed(x)); 183 // } 184 185 // private <T> ConcurrentLinkedDeque<Promise<T>> createHandlerPromiseQueueIfAbsent() { 186 // if (handlerPromiseQueue == null) { 187 // handlerPromiseQueue = new ConcurrentLinkedDeque<>(); 188 // } 189 // return (ConcurrentLinkedDeque) handlerPromiseQueue; 190 // } 191 192 override HttpConnection httpConnection() { 193 return _context.connection(); 194 } 195 196 override int getConnectionId() { 197 return _context.getConnectionId(); 198 } 199 200 void close() { 201 _context.end(); 202 } 203 204 override string getParameter(string name) { 205 // if(httpRequestBody is null) { 206 // return null; 207 // } else { 208 // return httpRequestBody.getParameter(name); 209 // } 210 return getRequest().getParameter(name); 211 } 212 213 override List!string getParameterValues(string name) { 214 // if(httpRequestBody is null) 215 // return new EmptyList!string(); 216 // else 217 // return httpRequestBody.getParameterValues(name); 218 return getRequest().getParameterValues(name); 219 } 220 221 override Map!(string, List!string) getParameterMap() { 222 // if(httpRequestBody is null) 223 // return null; 224 // else 225 // return httpRequestBody.getParameterMap(); 226 227 return getRequest().getParameterMap(); 228 } 229 230 // override 231 // Collection!Part getParts() { 232 // // return Optional.ofNullable(httpRequestBody) 233 // // .map(HttpServerRequest::getParts) 234 // // .orElse(Collections.emptyList()); 235 // if(httpRequestBody is null) 236 // return null; 237 // else 238 // return httpRequestBody.getParts(); 239 // } 240 241 // override 242 // Part getPart(string name) { 243 // // return Optional.ofNullable(httpRequestBody) 244 // // .map(s -> s.getPart(name)) 245 // // .orElse(null); 246 // if(httpRequestBody is null) 247 // return null; 248 // else 249 // return httpRequestBody.getPart(name); 250 // } 251 252 // override 253 // InputStream getInputStream() { 254 // return Optional.ofNullable(httpRequestBody) 255 // .map(HttpServerRequest::getInputStream) 256 // .orElse(null); 257 // } 258 259 // override 260 // BufferedReader getBufferedReader() { 261 // return Optional.ofNullable(httpRequestBody) 262 // .map(HttpServerRequest::getBufferedReader) 263 // .orElse(null); 264 // } 265 266 override string getStringBody(string charset) { 267 // if(httpRequestBody is null) 268 // return request.getStringBody(charset); 269 // else 270 // return httpRequestBody.getStringBody(charset); 271 272 return getRequest().getStringBody(charset); 273 } 274 275 override string getStringBody() { 276 // if(httpRequestBody is null) 277 // return request.getStringBody(); 278 // else 279 // return httpRequestBody.getStringBody(); 280 return getRequest().getStringBody(); 281 } 282 283 // override 284 // <T> T getJsonBody(Class<T> clazz) { 285 // return Optional.ofNullable(httpRequestBody) 286 // .map(s -> s.getJsonBody(clazz)) 287 // .orElseGet(() -> request.getJsonBody(clazz)); 288 // } 289 290 // override 291 // <T> T getJsonBody(GenericTypeReference<T> typeReference) { 292 // return Optional.ofNullable(httpRequestBody) 293 // .map(s -> s.getJsonBody(typeReference)) 294 // .orElseGet(() -> request.getJsonBody(typeReference)); 295 296 // } 297 298 // override 299 // JsonObject getJsonObjectBody() { 300 // return Optional.ofNullable(httpRequestBody) 301 // .map(HttpServerRequest::getJsonObjectBody) 302 // .orElseGet(request::getJsonObjectBody); 303 // } 304 305 // override 306 // JsonArray getJsonArrayBody() { 307 // return Optional.ofNullable(httpRequestBody) 308 // .map(HttpServerRequest::getJsonArrayBody) 309 // .orElseGet(request::getJsonArrayBody); 310 // } 311 312 // override void setHttpBody(HttpServerRequest requestBody) { 313 // this.httpRequestBody = requestBody; 314 // } 315 316 override HttpSession getSessionById(string id) { 317 if (httpSessionHandler is null) { 318 return null; 319 } else { 320 return httpSessionHandler.getSessionById(id); 321 } 322 } 323 324 override HttpSession getSession() { 325 if (httpSessionHandler is null) { 326 return null; 327 } else { 328 return httpSessionHandler.getSession(); 329 } 330 } 331 332 override HttpSession getSession(bool create) { 333 if (httpSessionHandler is null) { 334 return null; 335 } else { 336 return httpSessionHandler.getSession(create); 337 } 338 } 339 340 override HttpSession getAndCreateSession(int maxAge) { 341 if (httpSessionHandler is null) { 342 return null; 343 } else { 344 return httpSessionHandler.getAndCreateSession(maxAge); 345 } 346 } 347 348 override int getSessionSize() { 349 if (httpSessionHandler is null) { 350 return 0; 351 } else { 352 return httpSessionHandler.getSessionSize(); 353 } 354 } 355 356 override bool removeSessionById(string id) { 357 if (httpSessionHandler is null) { 358 return false; 359 } else { 360 return httpSessionHandler.removeSessionById(id); 361 } 362 } 363 364 override bool removeSession() { 365 if (httpSessionHandler is null) { 366 return false; 367 } else { 368 return httpSessionHandler.removeSession; 369 } 370 } 371 372 override bool updateSession(HttpSession httpSession) { 373 if (httpSessionHandler is null) { 374 return false; 375 } else { 376 return httpSessionHandler.updateSession(httpSession); 377 } 378 } 379 380 override bool isRequestedSessionIdFromURL() { 381 if (httpSessionHandler is null) { 382 return false; 383 } else { 384 return httpSessionHandler.isRequestedSessionIdFromURL(); 385 } 386 } 387 388 override bool isRequestedSessionIdFromCookie() { 389 if (httpSessionHandler is null) { 390 return false; 391 } else { 392 return httpSessionHandler.isRequestedSessionIdFromCookie(); 393 } 394 } 395 396 override string getRequestedSessionId() { 397 if (httpSessionHandler is null) { 398 return null; 399 } else { 400 return httpSessionHandler.getRequestedSessionId(); 401 } 402 } 403 404 override string getSessionIdParameterName() { 405 if (httpSessionHandler is null) { 406 return null; 407 } else { 408 return httpSessionHandler.getSessionIdParameterName(); 409 } 410 } 411 412 void setHttpSessionHandler(HttpSessionHandler httpSessionHandler) { 413 this.httpSessionHandler = httpSessionHandler; 414 } 415 416 // override 417 // void renderTemplate(string resourceName, Object scope) { 418 // templateHandlerSPI.renderTemplate(this, resourceName, scope); 419 // } 420 421 // override 422 // void renderTemplate(string resourceName, Object[] scopes) { 423 // templateHandlerSPI.renderTemplate(this, resourceName, scopes); 424 // } 425 426 // override 427 // void renderTemplate(string resourceName, List<Object> scopes) { 428 // templateHandlerSPI.renderTemplate(this, resourceName, scopes); 429 // } 430 431 override RoutingContext write(string value) { 432 _context.write(value); 433 return this; 434 } 435 436 override RoutingContext write(byte[] b, int off, int len) { 437 _context.write(b, off, len); 438 return this; 439 } 440 441 override RoutingContext end() { 442 _context.end(); 443 return this; 444 } 445 446 override void flush() { 447 _context.flush(); 448 } 449 450 override bool isCommitted() { 451 return _context.isCommitted(); 452 } 453 454 override string groupName() { 455 return _groupName; 456 } 457 458 override void groupName(string name) { 459 _groupName = name; 460 } 461 }