1 module hunt.http.client.Http1ClientDecoder;
2 
3 import hunt.http.client.Http1ClientConnection;
4 import hunt.http.client.Http2ClientDecoder;
5 
6 import hunt.http.codec.http.decode.HttpParser;
7 import hunt.http.codec.websocket.decode.WebSocketDecoder;
8 
9 import hunt.http.HttpConnection;
10 import hunt.http.HttpConnection;
11 import hunt.http.HttpConnection;
12 import hunt.net.codec.Decoder;
13 import hunt.net.Connection;
14 
15 import hunt.Exceptions;
16 
17 import hunt.io.ByteBuffer;
18 import hunt.io.channel;
19 
20 import hunt.logging;
21 import std.conv;
22 
23 
24 // import hunt.http.utils.io.BufferUtils.toHeapBuffer;
25 
26 class Http1ClientDecoder : DecoderChain {
27 
28     private WebSocketDecoder webSocketDecoder;
29     private Http2ClientDecoder http2ClientDecoder;
30 
31     this(WebSocketDecoder webSocketDecoder, Http2ClientDecoder http2ClientDecoder) {
32         super(null);
33         this.webSocketDecoder = webSocketDecoder;
34         this.http2ClientDecoder = http2ClientDecoder;
35     }
36 
37     override
38     DataHandleStatus decode(ByteBuffer buffer, Connection session) {
39         ByteBuffer buf = buffer; // toHeapBuffer(buffer);
40         Object attachment = session.getAttribute(HttpConnection.NAME); // session.getAttachment();
41         DataHandleStatus resultStatus = DataHandleStatus.Done;
42 
43         AbstractHttpConnection abstractConnection = cast(AbstractHttpConnection) attachment;
44         if(abstractConnection is null) {
45             throw new IllegalStateException("Client connection is null! The actual type is: " 
46                 ~ typeid(attachment).name);
47         }
48 
49         switch (abstractConnection.getConnectionType()) {
50             case HttpConnectionType.HTTP1: {
51                 Http1ClientConnection http1Connection = cast(Http1ClientConnection) abstractConnection;
52                 HttpParser parser = http1Connection.getParser();
53                 while (buf.hasRemaining()) {
54                     version(HUNT_HTTP_DEBUG) tracef("parsing buffer: %s", buf.toString());
55                     parser.parseNext(buf);
56                     if (http1Connection.getUpgradeHttp2Complete()) {
57                         resultStatus = http2ClientDecoder.decode(buf, session);
58                         break;
59                     } else if (http1Connection.getUpgradeWebSocketComplete()) {
60                         resultStatus = webSocketDecoder.decode(buf, session);
61                         break;
62                     }
63                 }
64             }
65             break;
66 
67             case HttpConnectionType.HTTP2: {
68                 resultStatus = http2ClientDecoder.decode(buf, session);
69             }
70             break;
71 
72             case HttpConnectionType.WEB_SOCKET: {
73                 resultStatus = webSocketDecoder.decode(buf, session);
74             }
75             break;
76 
77             default:
78                 string msg = "client does not support the protocol " ~ abstractConnection.getConnectionType().to!string();
79                 error(msg);
80                 throw new IllegalStateException(msg);
81         }
82 
83         return resultStatus;
84     }
85 
86 }