1 module hunt.http.codec.CommonDecoder;
2 
3 import hunt.container.ByteBuffer;
4 import hunt.lang.exception;
5 import hunt.logging;
6 
7 import hunt.net.AbstractConnection;
8 import hunt.net.ConnectionType;
9 import hunt.net.DecoderChain;
10 import hunt.net.Session;
11 import hunt.net.secure.SecureSession;
12 
13 /**
14  * 
15  */
16 class CommonDecoder : DecoderChain {
17 
18     this(DecoderChain next) {
19         super(next);
20     }
21 
22     override void decode(ByteBuffer buf, Session session) {
23         version(HUNT_METRIC) {
24             import core.time;
25             import hunt.datetime;
26             MonoTime startTime = MonoTime.currTime;
27             debug infof("start decoding ...");
28         }
29         Object attachment = session.getAttachment();
30         version(HUNT_DEBUG) {
31             tracef("decoding with %s", typeid(attachment).name);
32         }
33 
34         AbstractConnection connection = cast(AbstractConnection) attachment;
35         SecureSession secureSession = cast(SecureSession) attachment;
36 
37         if (connection !is null) {
38             if (connection.isEncrypted()) {
39                 ByteBuffer plaintext = connection.decrypt(buf);
40                 if (plaintext !is null && plaintext.hasRemaining() && next !is null) {
41                     next.decode(plaintext, session);
42                 } else warning("The next decoder is null.");
43             } else {
44                 if (next !is null) {
45                     next.decode(buf, session);
46                 } else warning("The next decoder is null.");
47             }
48         } else if (secureSession !is null) { // TLS handshake
49             ByteBuffer plaintext = secureSession.read(buf);
50 
51             if (plaintext !is null && plaintext.hasRemaining()) {
52                 version(HUNT_DEBUG) {
53                     tracef("The session %s handshake finished and received cleartext size %s",
54                             session.getSessionId(), plaintext.remaining());
55                 }
56 
57                 // The attachment has been reset.
58                 connection = cast(AbstractConnection) session.getAttachment();
59                 if (connection !is null) {
60                     if (next !is null) 
61                         next.decode(plaintext, session);
62                     else 
63                         warning("The next decoder is null.");
64                 } else {
65                         warningf("connection is null");
66                     throw new IllegalStateException("the connection has not been created: ", );
67                 }
68             } else {
69                 version(HUNT_DEBUG) {
70                     if (secureSession.isHandshakeFinished()) {
71                         tracef("The ssl session %s need more data", session.getSessionId());
72                     } else {
73                         tracef("The ssl session %s is shaking hand", session.getSessionId());
74                     }
75                 }
76             }
77         } else {
78             version(HUNT_DEBUG) warning("No handler for decoding");
79         }
80 
81         version(HUNT_METRIC) {
82             Duration timeElapsed = MonoTime.currTime - startTime;
83             warningf("decoding done for session %d in: %d microseconds",
84                 session.getSessionId, timeElapsed.total!(TimeUnit.Microsecond)());
85         }
86     }
87 }