@@ -47,9 +47,15 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
47
47
try
48
48
{
49
49
TunnelConnectSessionEventArgs ? connectArgs = null ;
50
-
50
+
51
+ var method = await HttpHelper . GetMethod ( clientStream , BufferPool , cancellationToken ) ;
52
+ if ( clientStream . IsClosed )
53
+ {
54
+ return ;
55
+ }
56
+
51
57
// 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 )
53
59
{
54
60
// read the first line HTTP command
55
61
var requestLine = await clientStream . ReadRequestLine ( cancellationToken ) ;
@@ -75,6 +81,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
75
81
76
82
// filter out excluded host names
77
83
bool decryptSsl = endPoint . DecryptSsl && connectArgs . DecryptSsl ;
84
+ bool sendRawData = ! decryptSsl ;
78
85
79
86
if ( connectArgs . DenyConnect )
80
87
{
@@ -113,6 +120,10 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
113
120
await clientStream . WriteResponseAsync ( response , cancellationToken ) ;
114
121
115
122
var clientHelloInfo = await SslTools . PeekClientHello ( clientStream , BufferPool , cancellationToken ) ;
123
+ if ( clientStream . IsClosed )
124
+ {
125
+ return ;
126
+ }
116
127
117
128
bool isClientHello = clientHelloInfo != null ;
118
129
if ( clientHelloInfo != null )
@@ -130,26 +141,29 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
130
141
131
142
bool http2Supported = false ;
132
143
133
- var alpn = clientHelloInfo . GetAlpn ( ) ;
134
- if ( alpn != null && alpn . Contains ( SslApplicationProtocol . Http2 ) )
144
+ if ( EnableHttp2 )
135
145
{
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 ) )
151
148
{
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
+ }
153
167
}
154
168
}
155
169
@@ -224,36 +238,46 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
224
238
$ "Couldn't authenticate host '{ connectHostname } ' with certificate '{ certName } '.", e , connectArgs ) ;
225
239
}
226
240
227
- if ( await HttpHelper . IsConnectMethod ( clientStream , BufferPool , cancellationToken ) == - 1 )
241
+ method = await HttpHelper . GetMethod ( clientStream , BufferPool , cancellationToken ) ;
242
+ if ( clientStream . IsClosed )
228
243
{
229
- decryptSsl = false ;
244
+ return ;
230
245
}
231
246
232
- if ( ! decryptSsl )
247
+ if ( method == KnownMethod . Invalid )
233
248
{
249
+ sendRawData = true ;
234
250
await tcpConnectionFactory . Release ( prefetchConnectionTask , true ) ;
235
251
prefetchConnectionTask = null ;
236
252
}
237
253
}
254
+ else if ( clientHelloInfo == null )
255
+ {
256
+ method = await HttpHelper . GetMethod ( clientStream , BufferPool , cancellationToken ) ;
257
+ if ( clientStream . IsClosed )
258
+ {
259
+ return ;
260
+ }
261
+ }
238
262
239
263
if ( cancellationTokenSource . IsCancellationRequested )
240
264
{
241
265
throw new Exception ( "Session was terminated by user." ) ;
242
266
}
243
267
244
- // Hostname is excluded or it is not an HTTPS connect
245
- if ( ! decryptSsl || ! isClientHello )
268
+ if ( method == KnownMethod . Invalid )
246
269
{
247
- if ( ! isClientHello )
248
- {
249
- connectRequest . TunnelType = TunnelType . Websocket ;
250
- }
270
+ sendRawData = true ;
271
+ }
251
272
273
+ // Hostname is excluded or it is not an HTTPS connect
274
+ if ( sendRawData )
275
+ {
252
276
// create new connection to server.
253
277
// If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
254
278
// this connection should not be HTTPS.
255
279
var connection = await tcpConnectionFactory . GetServerConnection ( this , connectArgs ,
256
- true , SslExtensions . Http2ProtocolAsList ,
280
+ true , null ,
257
281
true , cancellationToken ) ;
258
282
259
283
try
@@ -302,7 +326,7 @@ await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool,
302
326
}
303
327
}
304
328
305
- if ( connectArgs != null && await HttpHelper . IsPriMethod ( clientStream , BufferPool , cancellationToken ) == 1 )
329
+ if ( connectArgs != null && method == KnownMethod . Pri )
306
330
{
307
331
// todo
308
332
string ? httpCmd = await clientStream . ReadLineAsync ( cancellationToken ) ;
0 commit comments