1 module hunt.http.server.HttpServerHandler; 2 3 import hunt.http.server.HttpServerOptions; 4 import hunt.http.server.Http1ServerConnection; 5 import hunt.http.server.Http1ServerRequestHandler; 6 import hunt.http.server.Http2ServerConnection; 7 import hunt.http.server.Http2ServerRequestHandler; 8 import hunt.http.server.ServerHttpHandler; 9 import hunt.http.server.ServerSessionListener; 10 import hunt.http.server.WebSocketHandler; 11 12 import hunt.http.HttpConnection; 13 import hunt.http.HttpOptions; 14 import hunt.http.HttpVersion; 15 16 import hunt.net.secure.SecureSession; 17 import hunt.net.secure.SecureSessionFactory; 18 import hunt.net.Connection; 19 20 import hunt.Exceptions; 21 import hunt.logging; 22 import hunt.text.Common; 23 24 import std.range.primitives; 25 import std.string; 26 27 /** 28 * 29 */ 30 class HttpServerHandler : HttpConnectionHandler { 31 32 private ServerSessionListener listener; 33 private ServerHttpHandler serverHttpHandler; 34 private WebSocketHandler webSocketHandler; 35 private HttpServerOptions _options; 36 37 this(HttpServerOptions options, ServerSessionListener listener, 38 ServerHttpHandler serverHttpHandler, WebSocketHandler webSocketHandler) { 39 _options = options; 40 this.listener = listener; 41 this.serverHttpHandler = serverHttpHandler; 42 this.webSocketHandler = webSocketHandler; 43 } 44 45 override void connectionOpened(Connection connection) { 46 version(HUNT_HTTP_DEBUG_MORE) tracef("New http connection: %s", typeid(cast(Object) connection)); 47 48 version(WITH_HUNT_SECURITY) { 49 if (_options.isSecureConnectionEnabled()) { 50 buildSecureSession(connection); 51 } else { 52 buildNomalSession(connection); 53 } 54 } else { 55 buildNomalSession(connection); 56 } 57 58 super.connectionOpened(connection); 59 } 60 61 private void buildNomalSession(Connection connection) { 62 63 connection.setState(ConnectionState.Opening); 64 65 version (HUNT_HTTP_DEBUG) 66 infof("Building a new http connection..."); 67 string protocol = _options.getProtocol(); 68 69 if (!protocol.empty) { 70 Http1ServerConnection httpConnection = new Http1ServerConnection(_options, connection, 71 new Http1ServerRequestHandler(serverHttpHandler, _options), listener, webSocketHandler); 72 connection.setAttribute(HttpConnection.NAME, httpConnection); 73 serverHttpHandler.acceptConnection(httpConnection); 74 connection.setState(ConnectionState.Opened); 75 } else { 76 enum string HTTP_1_1 = HttpVersion.HTTP_1_1.asString(); 77 enum string HTTP_2 = HttpVersion.HTTP_2.asString(); 78 // HttpVersion httpVersion = HttpVersion.fromString(protocol); 79 // if (httpVersion == HttpVersion.Null) { 80 // string msg = "the protocol " ~ protocol ~ " is not support."; 81 // warning(msg); 82 // throw new IllegalArgumentException(msg); 83 // } 84 85 if (icmp(HTTP_1_1, protocol) == 0) { 86 Http1ServerConnection httpConnection = new Http1ServerConnection(_options, connection, 87 new Http1ServerRequestHandler(serverHttpHandler, _options), 88 listener, webSocketHandler); 89 connection.setAttribute(HttpConnection.NAME, httpConnection); 90 serverHttpHandler.acceptConnection(httpConnection); 91 connection.setState(ConnectionState.Opened); 92 } else if (icmp(HTTP_2, protocol) == 0) { 93 Http2ServerConnection httpConnection = new Http2ServerConnection(_options, 94 connection, listener); 95 connection.setAttribute(HttpConnection.NAME, httpConnection); 96 serverHttpHandler.acceptConnection(httpConnection); 97 connection.setState(ConnectionState.Opened); 98 99 } else { 100 string msg = "the protocol " ~ protocol ~ " is not support."; 101 version (HUNT_HTTP_DEBUG) { 102 warningf(msg); 103 } 104 connection.setState(ConnectionState.Error); 105 throw new IllegalArgumentException(msg); 106 } 107 } 108 } 109 110 version(WITH_HUNT_SECURITY) { 111 private void buildSecureSession(Connection connection) { 112 113 import hunt.net.secure.SecureUtils; 114 connection.setState(ConnectionState.Securing); 115 version(HUNT_HTTP_DEBUG) info("building SecureSession ..."); 116 117 SecureSession secureSession = SecureUtils.createServerSession(connection, (SecureSession sslSession) { 118 connection.setState(ConnectionState.Secured); 119 version (HUNT_DEBUG) 120 info("Secure connection created..."); 121 122 enum string HTTP_1_1 = HttpVersion.HTTP_1_1.asString(); 123 enum string HTTP_2 = HttpVersion.HTTP_2.asString(); 124 125 HttpConnection httpConnection; 126 string protocol = sslSession.getApplicationProtocol(); 127 if (protocol.empty) 128 protocol = _options.getProtocol(); 129 if (protocol.empty) 130 protocol = HTTP_1_1; 131 132 version (HUNT_HTTP_DEBUG) { 133 tracef("server connection %s SSL handshake finished. Application protocol: %s", 134 connection.getId(), protocol); 135 } 136 137 switch (protocol) { 138 case HTTP_1_1: 139 httpConnection = new Http1ServerConnection(_options, connection, 140 new Http1ServerRequestHandler(serverHttpHandler, _options), 141 listener, webSocketHandler); 142 break; 143 144 case HTTP_2: 145 httpConnection = new Http2ServerConnection(_options, connection,listener); 146 break; 147 148 default: 149 throw new IllegalStateException( 150 "SSL application protocol negotiates failure. The protocol " 151 ~ protocol ~ " is not supported"); 152 } 153 154 connection.setAttribute(HttpConnection.NAME, cast(Object)httpConnection); 155 version (HUNT_HTTP_DEBUG_MORE) infof("attach http connection: %s", typeid(httpConnection)); 156 157 serverHttpHandler.acceptConnection(httpConnection); 158 }); 159 160 connection.setAttribute(SecureSession.NAME, cast(Object)secureSession); 161 } 162 } 163 }