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 if(!_options.canUpgrade()) { 103 return true; 104 } 105 106 try { 107 if (connection.getUpgradeHttp2Complete() || connection.getUpgradeWebSocketComplete()) { 108 return true; 109 } else { 110 bool success = connection.upgradeProtocol(request, response, 111 outputStream, connection); 112 return success || serverHttpHandler.messageComplete(request, 113 response, outputStream, connection); 114 } 115 } catch (Exception ex) { 116 error("Upgrade failed: ", ex.msg); 117 return true; 118 } finally { 119 connection.getParser().reset(); 120 } 121 } 122 123 override void badMessage(int status, string reason) { 124 if(response is null) { 125 response = new HttpServerResponse(status, reason); 126 outputStream = new Http1ServerResponseOutputStream(response, connection); 127 } 128 serverHttpHandler.badMessage(status, reason, request, response, outputStream, connection); 129 } 130 131 void badMessage(BadMessageException failure) { 132 badMessage(failure.getCode(), failure.getReason()); 133 } 134 135 override void earlyEOF() { 136 serverHttpHandler.earlyEOF(request, response, outputStream, connection); 137 } 138 139 override int getHeaderCacheSize() { 140 return 1024; 141 } 142 143 }