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 }