@@ -47,9 +47,15 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
4747 try
4848 {
4949 TunnelConnectSessionEventArgs ? connectArgs = null ;
50-
50+
51+ var method = await HttpHelper . GetMethod ( clientStream , BufferPool , cancellationToken ) ;
52+ if ( clientStream . IsClosed )
53+ {
54+ return ;
55+ }
56+
5157 // Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request)
52- if ( await HttpHelper . IsConnectMethod ( clientStream , BufferPool , cancellationToken ) == 1 )
58+ if ( method == KnownMethod . Connect )
5359 {
5460 // read the first line HTTP command
5561 var requestLine = await clientStream . ReadRequestLine ( cancellationToken ) ;
@@ -75,6 +81,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
7581
7682 // filter out excluded host names
7783 bool decryptSsl = endPoint . DecryptSsl && connectArgs . DecryptSsl ;
84+ bool sendRawData = ! decryptSsl ;
7885
7986 if ( connectArgs . DenyConnect )
8087 {
@@ -113,6 +120,10 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
113120 await clientStream . WriteResponseAsync ( response , cancellationToken ) ;
114121
115122 var clientHelloInfo = await SslTools . PeekClientHello ( clientStream , BufferPool , cancellationToken ) ;
123+ if ( clientStream . IsClosed )
124+ {
125+ return ;
126+ }
116127
117128 bool isClientHello = clientHelloInfo != null ;
118129 if ( clientHelloInfo != null )
@@ -130,26 +141,29 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
130141
131142 bool http2Supported = false ;
132143
133- var alpn = clientHelloInfo . GetAlpn ( ) ;
134- if ( alpn != null && alpn . Contains ( SslApplicationProtocol . Http2 ) )
144+ if ( EnableHttp2 )
135145 {
136- // test server HTTP/2 support
137- try
138- {
139- // todo: this is a hack, because Titanium does not support HTTP protocol changing currently
140- var connection = await tcpConnectionFactory . GetServerConnection ( this , connectArgs ,
141- true , SslExtensions . Http2ProtocolAsList ,
142- true , cancellationToken ) ;
143-
144- http2Supported = connection . NegotiatedApplicationProtocol ==
145- SslApplicationProtocol . Http2 ;
146-
147- // release connection back to pool instead of closing when connection pool is enabled.
148- await tcpConnectionFactory . Release ( connection , true ) ;
149- }
150- catch ( Exception )
146+ var alpn = clientHelloInfo . GetAlpn ( ) ;
147+ if ( alpn != null && alpn . Contains ( SslApplicationProtocol . Http2 ) )
151148 {
152- // ignore
149+ // test server HTTP/2 support
150+ try
151+ {
152+ // todo: this is a hack, because Titanium does not support HTTP protocol changing currently
153+ var connection = await tcpConnectionFactory . GetServerConnection ( this , connectArgs ,
154+ true , SslExtensions . Http2ProtocolAsList ,
155+ true , cancellationToken ) ;
156+
157+ http2Supported = connection . NegotiatedApplicationProtocol ==
158+ SslApplicationProtocol . Http2 ;
159+
160+ // release connection back to pool instead of closing when connection pool is enabled.
161+ await tcpConnectionFactory . Release ( connection , true ) ;
162+ }
163+ catch ( Exception )
164+ {
165+ // ignore
166+ }
153167 }
154168 }
155169
@@ -224,36 +238,46 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
224238 $ "Couldn't authenticate host '{ connectHostname } ' with certificate '{ certName } '.", e , connectArgs ) ;
225239 }
226240
227- if ( await HttpHelper . IsConnectMethod ( clientStream , BufferPool , cancellationToken ) == - 1 )
241+ method = await HttpHelper . GetMethod ( clientStream , BufferPool , cancellationToken ) ;
242+ if ( clientStream . IsClosed )
228243 {
229- decryptSsl = false ;
244+ return ;
230245 }
231246
232- if ( ! decryptSsl )
247+ if ( method == KnownMethod . Invalid )
233248 {
249+ sendRawData = true ;
234250 await tcpConnectionFactory . Release ( prefetchConnectionTask , true ) ;
235251 prefetchConnectionTask = null ;
236252 }
237253 }
254+ else if ( clientHelloInfo == null )
255+ {
256+ method = await HttpHelper . GetMethod ( clientStream , BufferPool , cancellationToken ) ;
257+ if ( clientStream . IsClosed )
258+ {
259+ return ;
260+ }
261+ }
238262
239263 if ( cancellationTokenSource . IsCancellationRequested )
240264 {
241265 throw new Exception ( "Session was terminated by user." ) ;
242266 }
243267
244- // Hostname is excluded or it is not an HTTPS connect
245- if ( ! decryptSsl || ! isClientHello )
268+ if ( method == KnownMethod . Invalid )
246269 {
247- if ( ! isClientHello )
248- {
249- connectRequest . TunnelType = TunnelType . Websocket ;
250- }
270+ sendRawData = true ;
271+ }
251272
273+ // Hostname is excluded or it is not an HTTPS connect
274+ if ( sendRawData )
275+ {
252276 // create new connection to server.
253277 // If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
254278 // this connection should not be HTTPS.
255279 var connection = await tcpConnectionFactory . GetServerConnection ( this , connectArgs ,
256- true , SslExtensions . Http2ProtocolAsList ,
280+ true , null ,
257281 true , cancellationToken ) ;
258282
259283 try
@@ -302,7 +326,7 @@ await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool,
302326 }
303327 }
304328
305- if ( connectArgs != null && await HttpHelper . IsPriMethod ( clientStream , BufferPool , cancellationToken ) == 1 )
329+ if ( connectArgs != null && method == KnownMethod . Pri )
306330 {
307331 // todo
308332 string ? httpCmd = await clientStream . ReadLineAsync ( cancellationToken ) ;
0 commit comments