@@ -97,10 +97,8 @@ private static void HandleClient(TcpClient client)
97
97
}
98
98
99
99
//Now create the request
100
- Task . Factory . StartNew (
101
- ( ) =>
102
- HandleHttpSessionRequest ( client , httpCmd , clientStream , clientStreamReader , clientStreamWriter ,
103
- httpRemoteUri . Scheme == Uri . UriSchemeHttps ? httpRemoteUri . OriginalString : null ) ) ;
100
+ HandleHttpSessionRequest ( client , httpCmd , clientStream , clientStreamReader , clientStreamWriter ,
101
+ httpRemoteUri . Scheme == Uri . UriSchemeHttps ? httpRemoteUri . OriginalString : null ) ;
104
102
}
105
103
catch
106
104
{
@@ -112,145 +110,152 @@ private static void HandleClient(TcpClient client)
112
110
private static void HandleHttpSessionRequest ( TcpClient client , string httpCmd , Stream clientStream ,
113
111
CustomBinaryReader clientStreamReader , StreamWriter clientStreamWriter , string secureTunnelHostName )
114
112
{
115
- if ( string . IsNullOrEmpty ( httpCmd ) )
113
+ while ( true )
116
114
{
117
- Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , null ) ;
118
- return ;
119
- }
120
-
121
- var args = new SessionEventArgs ( BUFFER_SIZE ) ;
122
- args . Client = client ;
123
-
115
+ if ( string . IsNullOrEmpty ( httpCmd ) )
116
+ {
117
+ Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , null ) ;
118
+ return ;
119
+ }
124
120
125
- try
126
- {
127
- //break up the line into three components (method, remote URL & Http Version)
128
- var httpCmdSplit = httpCmd . Split ( SpaceSplit , 3 ) ;
121
+ var args = new SessionEventArgs ( BUFFER_SIZE ) ;
122
+ args . Client = client ;
129
123
130
- var httpMethod = httpCmdSplit [ 0 ] ;
131
- var httpRemoteUri =
132
- new Uri ( secureTunnelHostName == null ? httpCmdSplit [ 1 ] : ( secureTunnelHostName + httpCmdSplit [ 1 ] ) ) ;
133
- var httpVersion = httpCmdSplit [ 2 ] ;
134
124
135
- Version version ;
136
- if ( httpVersion == "HTTP/1.1" )
137
- {
138
- version = new Version ( 1 , 1 ) ;
139
- }
140
- else
125
+ try
141
126
{
142
- version = new Version ( 1 , 0 ) ;
143
- }
127
+ //break up the line into three components (method, remote URL & Http Version)
128
+ var httpCmdSplit = httpCmd . Split ( SpaceSplit , 3 ) ;
144
129
145
- if ( httpRemoteUri . Scheme == Uri . UriSchemeHttps )
146
- {
147
- args . IsHttps = true ;
148
- }
130
+ var httpMethod = httpCmdSplit [ 0 ] ;
131
+ var httpRemoteUri =
132
+ new Uri ( secureTunnelHostName == null ? httpCmdSplit [ 1 ] : ( secureTunnelHostName + httpCmdSplit [ 1 ] ) ) ;
133
+ var httpVersion = httpCmdSplit [ 2 ] ;
149
134
150
- args . RequestHeaders = new List < HttpHeader > ( ) ;
135
+ Version version ;
136
+ if ( httpVersion == "HTTP/1.1" )
137
+ {
138
+ version = new Version ( 1 , 1 ) ;
139
+ }
140
+ else
141
+ {
142
+ version = new Version ( 1 , 0 ) ;
143
+ }
151
144
152
- string tmpLine ;
145
+ if ( httpRemoteUri . Scheme == Uri . UriSchemeHttps )
146
+ {
147
+ args . IsHttps = true ;
148
+ }
153
149
154
- while ( ! string . IsNullOrEmpty ( tmpLine = clientStreamReader . ReadLine ( ) ) )
155
- {
156
- var header = tmpLine . Split ( ColonSpaceSplit , 2 , StringSplitOptions . None ) ;
157
- args . RequestHeaders . Add ( new HttpHeader ( header [ 0 ] , header [ 1 ] ) ) ;
158
- }
150
+ args . RequestHeaders = new List < HttpHeader > ( ) ;
159
151
160
- for ( var i = 0 ; i < args . RequestHeaders . Count ; i ++ )
161
- {
162
- var rawHeader = args . RequestHeaders [ i ] ;
152
+ string tmpLine ;
163
153
154
+ while ( ! string . IsNullOrEmpty ( tmpLine = clientStreamReader . ReadLine ( ) ) )
155
+ {
156
+ var header = tmpLine . Split ( ColonSpaceSplit , 2 , StringSplitOptions . None ) ;
157
+ args . RequestHeaders . Add ( new HttpHeader ( header [ 0 ] , header [ 1 ] ) ) ;
158
+ }
164
159
165
- //if request was upgrade to web-socket protocol then relay the request without proxying
166
- if ( ( rawHeader . Name . ToLower ( ) == "upgrade" ) && ( rawHeader . Value . ToLower ( ) == "websocket" ) )
160
+ for ( var i = 0 ; i < args . RequestHeaders . Count ; i ++ )
167
161
{
168
- TcpHelper . SendRaw ( clientStreamReader . BaseStream , httpCmd , args . RequestHeaders ,
169
- httpRemoteUri . Host , httpRemoteUri . Port , httpRemoteUri . Scheme == Uri . UriSchemeHttps ) ;
170
- Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
171
- return ;
162
+ var rawHeader = args . RequestHeaders [ i ] ;
163
+
164
+
165
+ //if request was upgrade to web-socket protocol then relay the request without proxying
166
+ if ( ( rawHeader . Name . ToLower ( ) == "upgrade" ) && ( rawHeader . Value . ToLower ( ) == "websocket" ) )
167
+ {
168
+ TcpHelper . SendRaw ( clientStreamReader . BaseStream , httpCmd , args . RequestHeaders ,
169
+ httpRemoteUri . Host , httpRemoteUri . Port , httpRemoteUri . Scheme == Uri . UriSchemeHttps ) ;
170
+ Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
171
+ return ;
172
+ }
172
173
}
173
- }
174
174
175
+ //construct the web request that we are going to issue on behalf of the client.
176
+ args . ProxyRequest = ( HttpWebRequest ) WebRequest . Create ( httpRemoteUri ) ;
177
+ args . ProxyRequest . Proxy = null ;
178
+ args . ProxyRequest . UseDefaultCredentials = true ;
179
+ args . ProxyRequest . Method = httpMethod ;
180
+ args . ProxyRequest . ProtocolVersion = version ;
181
+ args . ClientStream = clientStream ;
182
+ args . ClientStreamReader = clientStreamReader ;
183
+ args . ClientStreamWriter = clientStreamWriter ;
184
+ args . ProxyRequest . AllowAutoRedirect = false ;
185
+ args . ProxyRequest . AutomaticDecompression = DecompressionMethods . None ;
186
+ args . RequestHostname = args . ProxyRequest . RequestUri . Host ;
187
+ args . RequestUrl = args . ProxyRequest . RequestUri . OriginalString ;
188
+ args . ClientPort = ( ( IPEndPoint ) client . Client . RemoteEndPoint ) . Port ;
189
+ args . ClientIpAddress = ( ( IPEndPoint ) client . Client . RemoteEndPoint ) . Address ;
190
+ args . RequestHttpVersion = version ;
191
+ args . RequestIsAlive = args . ProxyRequest . KeepAlive ;
192
+ args . ProxyRequest . AllowWriteStreamBuffering = true ;
193
+
194
+
195
+ //If requested interception
196
+ if ( BeforeRequest != null )
197
+ {
198
+ args . RequestEncoding = args . ProxyRequest . GetEncoding ( ) ;
199
+ BeforeRequest ( null , args ) ;
200
+ }
175
201
176
- //construct the web request that we are going to issue on behalf of the client.
177
- args . ProxyRequest = ( HttpWebRequest ) WebRequest . Create ( httpRemoteUri ) ;
178
- args . ProxyRequest . Proxy = null ;
179
- args . ProxyRequest . UseDefaultCredentials = true ;
180
- args . ProxyRequest . Method = httpMethod ;
181
- args . ProxyRequest . ProtocolVersion = version ;
182
- args . ClientStream = clientStream ;
183
- args . ClientStreamReader = clientStreamReader ;
184
- args . ClientStreamWriter = clientStreamWriter ;
185
- args . ProxyRequest . AllowAutoRedirect = false ;
186
- args . ProxyRequest . AutomaticDecompression = DecompressionMethods . None ;
187
- args . RequestHostname = args . ProxyRequest . RequestUri . Host ;
188
- args . RequestUrl = args . ProxyRequest . RequestUri . OriginalString ;
189
- args . ClientPort = ( ( IPEndPoint ) client . Client . RemoteEndPoint ) . Port ;
190
- args . ClientIpAddress = ( ( IPEndPoint ) client . Client . RemoteEndPoint ) . Address ;
191
- args . RequestHttpVersion = version ;
192
- args . RequestIsAlive = args . ProxyRequest . KeepAlive ;
193
- args . ProxyRequest . ConnectionGroupName = args . RequestHostname ;
194
- args . ProxyRequest . AllowWriteStreamBuffering = true ;
202
+ args . RequestLocked = true ;
195
203
204
+ if ( args . CancelRequest )
205
+ {
206
+ Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
207
+ return ;
208
+ }
196
209
197
- //If requested interception
198
- if ( BeforeRequest != null )
199
- {
200
- args . RequestEncoding = args . ProxyRequest . GetEncoding ( ) ;
201
- BeforeRequest ( null , args ) ;
202
- }
210
+ SetRequestHeaders ( args . RequestHeaders , args . ProxyRequest ) ;
203
211
204
- args . RequestLocked = true ;
212
+ //If request was modified by user
213
+ if ( args . RequestBodyRead )
214
+ {
215
+ args . ProxyRequest . ContentLength = args . RequestBody . Length ;
216
+ var newStream = args . ProxyRequest . GetRequestStream ( ) ;
217
+ newStream . Write ( args . RequestBody , 0 , args . RequestBody . Length ) ;
218
+ }
219
+ else
220
+ {
221
+ //If its a post/put request, then read the client html body and send it to server
222
+ if ( httpMethod . ToUpper ( ) == "POST" || httpMethod . ToUpper ( ) == "PUT" )
223
+ {
224
+ SendClientRequestBody ( args ) ;
225
+ }
226
+ }
205
227
206
- if ( args . CancelRequest )
207
- {
208
- Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
209
- return ;
210
- }
228
+ HandleHttpSessionResponse ( args ) ;
211
229
212
- SetRequestHeaders ( args . RequestHeaders , args . ProxyRequest ) ;
230
+ if ( args . ResponseHeaders . Any ( x => x . Name . ToLower ( ) == "proxy-connection" && x . Value . ToLower ( ) == "close" ) )
231
+ {
232
+ Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
233
+ return ;
234
+ }
235
+ //Now read the next request (if keep-Alive is enabled, otherwise exit this thread)
236
+ //If client is pipeling the request, this will be immediately hit before response for previous request was made
237
+ httpCmd = clientStreamReader . ReadLine ( ) ;
238
+ //Http request body sent, now wait for next request
213
239
214
- //If request was modified by user
215
- if ( args . RequestBodyRead )
216
- {
217
- args . ProxyRequest . ContentLength = args . RequestBody . Length ;
218
- var newStream = args . ProxyRequest . GetRequestStream ( ) ;
219
- newStream . Write ( args . RequestBody , 0 , args . RequestBody . Length ) ;
240
+ client = args . Client ;
241
+ clientStream = args . ClientStream ;
242
+ clientStreamReader = args . ClientStreamReader ;
243
+ args . ClientStreamWriter = clientStreamWriter ;
220
244
221
- args . ProxyRequest . BeginGetResponse ( HandleHttpSessionResponse , args ) ;
222
245
}
223
- else
246
+ catch
224
247
{
225
- //If its a post/put request, then read the client html body and send it to server
226
- if ( httpMethod . ToUpper ( ) == "POST" || httpMethod . ToUpper ( ) == "PUT" )
227
- {
228
- SendClientRequestBody ( args ) ;
229
- }
230
- //Http request body sent, now wait asynchronously for response
231
- args . ProxyRequest . BeginGetResponse ( HandleHttpSessionResponse , args ) ;
248
+ Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
249
+ throw ;
232
250
}
233
-
234
- //Now read the next request (if keep-Alive is enabled, otherwise exit this thread)
235
- //If client is pipeling the request, this will be immediately hit before response for previous request was made
236
- httpCmd = clientStreamReader . ReadLine ( ) ;
237
- //Http request body sent, now wait for next request
238
- Task . Factory . StartNew (
239
- ( ) =>
240
- HandleHttpSessionRequest ( args . Client , httpCmd , args . ClientStream , args . ClientStreamReader ,
241
- args . ClientStreamWriter , secureTunnelHostName ) ) ;
242
- }
243
- catch
244
- {
245
- Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
246
251
}
247
252
}
248
253
249
254
private static void WriteConnectResponse ( StreamWriter clientStreamWriter , string httpVersion )
250
255
{
251
256
clientStreamWriter . WriteLine ( httpVersion + " 200 Connection established" ) ;
252
257
clientStreamWriter . WriteLine ( "Timestamp: {0}" , DateTime . Now ) ;
253
- clientStreamWriter . WriteLine ( "connection:close" ) ;
258
+ // clientStreamWriter.WriteLine("connection:close");
254
259
clientStreamWriter . WriteLine ( ) ;
255
260
clientStreamWriter . Flush ( ) ;
256
261
}
@@ -302,6 +307,8 @@ private static void SetRequestHeaders(List<HttpHeader> requestHeaders, HttpWebRe
302
307
case "proxy-connection" :
303
308
if ( requestHeaders [ i ] . Value . ToLower ( ) == "keep-alive" )
304
309
webRequest . KeepAlive = true ;
310
+ else if ( requestHeaders [ i ] . Value . ToLower ( ) == "close" )
311
+ webRequest . KeepAlive = false ;
305
312
break ;
306
313
case "range" :
307
314
var startEnd = requestHeaders [ i ] . Value . Replace ( Environment . NewLine , "" ) . Remove ( 0 , 6 ) . Split ( '-' ) ;
@@ -359,18 +366,18 @@ private static void SendClientRequestBody(SessionEventArgs args)
359
366
int bytesToRead ;
360
367
if ( args . ProxyRequest . ContentLength < BUFFER_SIZE )
361
368
{
362
- bytesToRead = ( int ) args . ProxyRequest . ContentLength ;
369
+ bytesToRead = ( int ) args . ProxyRequest . ContentLength ;
363
370
}
364
371
else
365
372
bytesToRead = BUFFER_SIZE ;
366
373
367
374
368
- while ( totalbytesRead < ( int ) args . ProxyRequest . ContentLength )
375
+ while ( totalbytesRead < ( int ) args . ProxyRequest . ContentLength )
369
376
{
370
377
var buffer = args . ClientStreamReader . ReadBytes ( bytesToRead ) ;
371
378
totalbytesRead += buffer . Length ;
372
379
373
- var remainingBytes = ( int ) args . ProxyRequest . ContentLength - totalbytesRead ;
380
+ var remainingBytes = ( int ) args . ProxyRequest . ContentLength - totalbytesRead ;
374
381
if ( remainingBytes < bytesToRead )
375
382
{
376
383
bytesToRead = remainingBytes ;
@@ -414,7 +421,6 @@ private static void SendClientRequestBody(SessionEventArgs args)
414
421
}
415
422
}
416
423
417
-
418
424
postStream . Close ( ) ;
419
425
}
420
426
catch
0 commit comments