1 module hunt.http.server.HttpServerHandler;
2 
3 import hunt.http.server.Http1ServerConnection;
4 import hunt.http.server.Http1ServerRequestHandler;
5 import hunt.http.server.Http2ServerConnection;
6 import hunt.http.server.Http2ServerRequestHandler;
7 import hunt.http.server.ServerHttpHandler;
8 import hunt.http.server.ServerSessionListener;
9 import hunt.http.server.WebSocketHandler;
10 
11 import hunt.http.codec.http.model.HttpVersion;
12 import hunt.http.codec.http.stream.AbstractHttpHandler;
13 import hunt.http.codec.http.stream.Http2Configuration;
14 import hunt.http.codec.http.stream.HttpConnection;
15 
16 import hunt.net.secure.SecureSession;
17 import hunt.net.secure.SecureSessionFactory;
18 import hunt.net.Session;
19 
20 import hunt.lang.exception;
21 import hunt.logging;
22 import hunt.string;
23 
24 import std.range.primitives;
25 
26 class HttpServerHandler : AbstractHttpHandler {
27 
28     private ServerSessionListener listener;
29     private ServerHttpHandler serverHttpHandler;
30     private WebSocketHandler webSocketHandler;
31 
32     this(Http2Configuration config, ServerSessionListener listener,
33             ServerHttpHandler serverHttpHandler, WebSocketHandler webSocketHandler) {
34         super(config);
35         this.listener = listener;
36         this.serverHttpHandler = serverHttpHandler;
37         this.webSocketHandler = webSocketHandler;
38     }
39 
40     override void sessionOpened(Session session) {
41         version (HUNT_DEBUG)
42             tracef("New http session");
43         // tracef("New http session: %s", typeid(cast(Object) session));
44         version(WithTLS) {
45             if (config.isSecureConnectionEnabled()) {
46                 buildSecureSession(session);
47             } else {
48                 buildNomalSession(session);
49             }
50         } else {
51             buildNomalSession(session);
52         }
53     }
54 
55     private void buildNomalSession(Session session) {
56         string protocol = config.getProtocol();
57         if (!protocol.empty) {
58             Http1ServerConnection httpConnection = new Http1ServerConnection(config, session, null,
59                     new Http1ServerRequestHandler(serverHttpHandler), listener, webSocketHandler);
60             session.attachObject(httpConnection);
61             serverHttpHandler.acceptConnection(httpConnection);
62         } else {
63             enum string HTTP_1_1 = HttpVersion.HTTP_1_1.asString();
64             enum string HTTP_2 = HttpVersion.HTTP_2.asString();
65             import std.string;
66             // HttpVersion httpVersion = HttpVersion.fromString(protocol);
67             // if (httpVersion == HttpVersion.Null) {
68             //     string msg = "the protocol " ~ protocol ~ " is not support.";
69             //     warning(msg);
70             //     throw new IllegalArgumentException(msg);
71             // }
72 
73             if (icmp(HTTP_1_1, protocol) == 0) {
74                 Http1ServerConnection httpConnection = new Http1ServerConnection(config, session, null,
75                         new Http1ServerRequestHandler(serverHttpHandler),
76                         listener, webSocketHandler);
77                 session.attachObject(httpConnection);
78                 serverHttpHandler.acceptConnection(httpConnection);
79             } else if (icmp(HTTP_2, protocol) == 0) {
80                 Http2ServerConnection httpConnection = new Http2ServerConnection(config,
81                         session, null, listener);
82                 session.attachObject(httpConnection);
83                 serverHttpHandler.acceptConnection(httpConnection);
84             } else {
85                 string msg = "the protocol " ~ protocol ~ " is not support.";
86                 version (HUNT_DEBUG) {
87                     warningf(msg);
88                 }
89                 throw new IllegalArgumentException(msg);
90             }
91         }
92     }
93 
94     version(WithTLS)
95     private void buildSecureSession(Session session) {
96         string protocol = config.getProtocol();
97         SecureSessionFactory factory = config.getSecureSessionFactory();
98         SecureSession secureSession = factory.create(session, false, (SecureSession sslSession) {
99             version (HUNT_DEBUG)
100                 info("Secure session created...");
101             HttpConnection httpConnection;
102             string protocol = sslSession.getApplicationProtocol();
103             if (protocol.empty)
104                 protocol = "http/1.1";
105 
106             version (HUNT_DEBUG) {
107                 tracef("server session %s SSL handshake finished. Application protocol: %s",
108                     session.getSessionId(), protocol);
109             }
110 
111             switch (protocol) {
112             case "http/1.1":
113                 httpConnection = new Http1ServerConnection(config, session, sslSession,
114                     new Http1ServerRequestHandler(serverHttpHandler), listener, webSocketHandler);
115                 break;
116             case "h2":
117                 httpConnection = new Http2ServerConnection(config, session, sslSession, listener);
118                 break;
119             default:
120                 throw new IllegalStateException(
121                     "SSL application protocol negotiates failure. The protocol "
122                     ~ protocol ~ " is not supported");
123             }
124 
125             //infof("attach http connection: %s", typeid(httpConnection));
126             session.attachObject(cast(Object) httpConnection);
127             serverHttpHandler.acceptConnection(httpConnection);
128         });
129 
130         //infof("attach secure session: %s", typeid(secureSession));
131         session.attachObject(cast(Object) secureSession);
132     }
133 
134 }