1 module hunt.http.server.Http1ServerDecoder; 2 3 import hunt.http.server.Http1ServerConnection; 4 import hunt.http.server.Http1ServerTunnelConnection; 5 import hunt.http.server.Http2ServerDecoder; 6 7 import hunt.http.codec.http.decode.HttpParser; 8 import hunt.http.codec.websocket.decode.WebSocketDecoder; 9 10 import hunt.http.HttpConnection; 11 import hunt.http.HttpConnection; 12 import hunt.net.codec.Decoder; 13 import hunt.http.HttpConnection; 14 import hunt.net.Connection; 15 16 import hunt.io.ByteBuffer; 17 import hunt.io.BufferUtils; 18 import hunt.Exceptions; 19 import hunt.logging; 20 import std.conv; 21 22 /** 23 */ 24 class Http1ServerDecoder : DecoderChain { 25 26 private WebSocketDecoder webSocketDecoder; 27 private Http2ServerDecoder http2ServerDecoder; 28 29 this(WebSocketDecoder webSocketDecoder, Http2ServerDecoder http2ServerDecoder) { 30 super(null); 31 this.webSocketDecoder = webSocketDecoder; 32 this.http2ServerDecoder = http2ServerDecoder; 33 } 34 35 override void decode(ByteBuffer buffer, Connection session) { 36 ByteBuffer buf = BufferUtils.toHeapBuffer(buffer); 37 38 Object attachment = session.getAttribute(HttpConnection.NAME); 39 version (HUNT_HTTP_DEBUG) { 40 tracef("session type: %s", attachment is null ? "null" : typeid(attachment).name); 41 } 42 43 AbstractHttpConnection abstractConnection = cast(AbstractHttpConnection) attachment; 44 if (abstractConnection is null) { 45 warningf("Bad connection instance: %s", attachment is null ? "null" : typeid(attachment).name); 46 return; 47 } 48 49 switch (abstractConnection.getConnectionType()) { 50 case HttpConnectionType.HTTP1: { 51 Http1ServerConnection http1Connection = cast(Http1ServerConnection) attachment; 52 if (http1Connection.getTunnelConnectionPromise() is null) { 53 HttpParser parser = http1Connection.getParser(); 54 version (HUNT_HTTP_DEBUG) trace("runing http1 parser for a buffer..."); 55 while (buf.hasRemaining()) { 56 parser.parseNext(buf); 57 if (http1Connection.getUpgradeHttp2Complete()) { 58 http2ServerDecoder.decode(buf, session); 59 break; 60 } else if (http1Connection.getUpgradeWebSocketComplete()) { 61 webSocketDecoder.decode(buf, session); 62 break; 63 } 64 } 65 version (HUNT_HTTP_DEBUG) trace("http1 parsing done for a buffer..."); 66 } else { 67 Http1ServerTunnelConnection tunnelConnection = http1Connection.createHttpTunnel(); 68 if (tunnelConnection.content != null) { 69 tunnelConnection.content(buf); 70 } 71 } 72 } 73 break; 74 case HttpConnectionType.HTTP2: { 75 http2ServerDecoder.decode(buf, session); 76 } 77 break; 78 case HttpConnectionType.WEB_SOCKET: { 79 webSocketDecoder.decode(buf, session); 80 } 81 break; 82 case HttpConnectionType.HTTP_TUNNEL: { 83 Http1ServerTunnelConnection tunnelConnection = 84 cast(Http1ServerTunnelConnection) session.getAttribute(HttpConnection.NAME); // session.getAttachment(); 85 if (tunnelConnection.content != null) { 86 tunnelConnection.content(buf); 87 } 88 } 89 break; 90 default: 91 throw new IllegalStateException("client does not support the protocol " ~ to!string( 92 abstractConnection.getConnectionType())); 93 } 94 } 95 }