1 module hunt.http.server.Http1ServerRequestHandler; 2 3 import hunt.http.server.Http1ServerConnection; 4 import hunt.http.server.HttpServerOptions; 5 import hunt.http.server.HttpServerRequest; 6 import hunt.http.server.HttpServerResponse; 7 import hunt.http.server.ServerHttpHandler; 8 9 import hunt.http.codec.http.decode.HttpParser; 10 import hunt.http.codec.http.model; 11 12 import hunt.http.HttpField; 13 import hunt.http.HttpFields; 14 import hunt.http.HttpHeader; 15 import hunt.http.HttpMethod; 16 import hunt.http.HttpResponse; 17 import hunt.http.HttpVersion; 18 19 import hunt.io.ByteBuffer; 20 import hunt.text.Common; 21 22 import hunt.logging; 23 import std.string : icmp; 24 25 // alias RequestHandler = HttpParser.RequestHandler; 26 27 28 /** 29 * 30 */ 31 class Http1ServerRequestHandler : HttpRequestParsingHandler { 32 package HttpServerRequest request; 33 package HttpServerResponse response; 34 package Http1ServerConnection connection; 35 package Http1ServerResponseOutputStream outputStream; 36 package ServerHttpHandler serverHttpHandler; 37 package HttpFields trailer; 38 private HttpServerOptions _options; 39 40 this(ServerHttpHandler serverHttpHandler, HttpServerOptions options) { 41 this.serverHttpHandler = serverHttpHandler; 42 _options = options; 43 } 44 45 override bool startRequest(string method, string uri, HttpVersion ver) { 46 version (HUNT_HTTP_DEBUG) { 47 tracef("server received the request line, %s, %s, %s", method, uri, ver); 48 } 49 50 request = new HttpServerRequest(method, uri, ver, _options); 51 response = new HttpServerResponse(); 52 outputStream = new Http1ServerResponseOutputStream(response, connection); 53 54 return HttpMethod.PRI.isSame(method) && connection.directUpgradeHttp2(request); 55 } 56 57 override void parsedHeader(HttpField field) { 58 request.getFields().add(field); 59 } 60 61 override bool headerComplete() { 62 if (HttpMethod.CONNECT.asString().equalsIgnoreCase(request.getMethod())) { 63 return serverHttpHandler.acceptHttpTunnelConnection(request, 64 response, outputStream, connection); 65 } else { 66 string expectedValue = request.getFields().get(HttpHeader.EXPECT); 67 if ("100-continue".equalsIgnoreCase(expectedValue)) { 68 bool skipNext = serverHttpHandler.accept100Continue(request, 69 response, outputStream, connection); 70 if (skipNext) { 71 return true; 72 } else { 73 connection.response100Continue(); 74 return serverHttpHandler.headerComplete(request, response, 75 outputStream, connection); 76 } 77 } else { 78 return serverHttpHandler.headerComplete(request, response, 79 outputStream, connection); 80 } 81 } 82 } 83 84 override bool content(ByteBuffer item) { 85 return serverHttpHandler.content(item, request, response, outputStream, connection); 86 } 87 88 override bool contentComplete() { 89 assert(request !is null, "Execute startRequest first"); 90 return serverHttpHandler.contentComplete(request, response, outputStream, connection); 91 } 92 93 override void parsedTrailer(HttpField field) { 94 if (trailer is null) { 95 trailer = new HttpFields(); 96 request.setTrailerSupplier(() => trailer); 97 } 98 trailer.add(field); 99 } 100 101 override bool messageComplete() { 102 try { 103 if (connection.getUpgradeHttp2Complete() || connection.getUpgradeWebSocketComplete()) { 104 return true; 105 } else { 106 bool success = connection.upgradeProtocol(request, response, 107 outputStream, connection); 108 return success || serverHttpHandler.messageComplete(request, 109 response, outputStream, connection); 110 } 111 } catch (Exception ex) { 112 error("Upgrade failed: ", ex.msg); 113 return true; 114 } finally { 115 connection.getParser().reset(); 116 } 117 } 118 119 override void badMessage(int status, string reason) { 120 if(response is null) { 121 response = new HttpServerResponse(status, reason); 122 outputStream = new Http1ServerResponseOutputStream(response, connection); 123 } 124 serverHttpHandler.badMessage(status, reason, request, response, outputStream, connection); 125 } 126 127 void badMessage(BadMessageException failure) { 128 badMessage(failure.getCode(), failure.getReason()); 129 } 130 131 override void earlyEOF() { 132 serverHttpHandler.earlyEOF(request, response, outputStream, connection); 133 } 134 135 override int getHeaderCacheSize() { 136 return 1024; 137 } 138 139 }