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