@@ -97,10 +97,8 @@ private static void HandleClient(TcpClient client)
9797 }
9898
9999 //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 ) ;
104102 }
105103 catch
106104 {
@@ -112,145 +110,152 @@ private static void HandleClient(TcpClient client)
112110 private static void HandleHttpSessionRequest ( TcpClient client , string httpCmd , Stream clientStream ,
113111 CustomBinaryReader clientStreamReader , StreamWriter clientStreamWriter , string secureTunnelHostName )
114112 {
115- if ( string . IsNullOrEmpty ( httpCmd ) )
113+ while ( true )
116114 {
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+ }
124120
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 ;
129123
130- var httpMethod = httpCmdSplit [ 0 ] ;
131- var httpRemoteUri =
132- new Uri ( secureTunnelHostName == null ? httpCmdSplit [ 1 ] : ( secureTunnelHostName + httpCmdSplit [ 1 ] ) ) ;
133- var httpVersion = httpCmdSplit [ 2 ] ;
134124
135- Version version ;
136- if ( httpVersion == "HTTP/1.1" )
137- {
138- version = new Version ( 1 , 1 ) ;
139- }
140- else
125+ try
141126 {
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 ) ;
144129
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 ] ;
149134
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+ }
151144
152- string tmpLine ;
145+ if ( httpRemoteUri . Scheme == Uri . UriSchemeHttps )
146+ {
147+ args . IsHttps = true ;
148+ }
153149
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 > ( ) ;
159151
160- for ( var i = 0 ; i < args . RequestHeaders . Count ; i ++ )
161- {
162- var rawHeader = args . RequestHeaders [ i ] ;
152+ string tmpLine ;
163153
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+ }
164159
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 ++ )
167161 {
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+ }
172173 }
173- }
174174
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+ }
175201
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 ;
195203
204+ if ( args . CancelRequest )
205+ {
206+ Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
207+ return ;
208+ }
196209
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 ) ;
203211
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+ }
205227
206- if ( args . CancelRequest )
207- {
208- Dispose ( client , clientStream , clientStreamReader , clientStreamWriter , args ) ;
209- return ;
210- }
228+ HandleHttpSessionResponse ( args ) ;
211229
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
213239
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 ;
220244
221- args . ProxyRequest . BeginGetResponse ( HandleHttpSessionResponse , args ) ;
222245 }
223- else
246+ catch
224247 {
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 ;
232250 }
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 ) ;
246251 }
247252 }
248253
249254 private static void WriteConnectResponse ( StreamWriter clientStreamWriter , string httpVersion )
250255 {
251256 clientStreamWriter . WriteLine ( httpVersion + " 200 Connection established" ) ;
252257 clientStreamWriter . WriteLine ( "Timestamp: {0}" , DateTime . Now ) ;
253- clientStreamWriter . WriteLine ( "connection:close" ) ;
258+ // clientStreamWriter.WriteLine("connection:close");
254259 clientStreamWriter . WriteLine ( ) ;
255260 clientStreamWriter . Flush ( ) ;
256261 }
@@ -302,6 +307,8 @@ private static void SetRequestHeaders(List<HttpHeader> requestHeaders, HttpWebRe
302307 case "proxy-connection" :
303308 if ( requestHeaders [ i ] . Value . ToLower ( ) == "keep-alive" )
304309 webRequest . KeepAlive = true ;
310+ else if ( requestHeaders [ i ] . Value . ToLower ( ) == "close" )
311+ webRequest . KeepAlive = false ;
305312 break ;
306313 case "range" :
307314 var startEnd = requestHeaders [ i ] . Value . Replace ( Environment . NewLine , "" ) . Remove ( 0 , 6 ) . Split ( '-' ) ;
@@ -359,18 +366,18 @@ private static void SendClientRequestBody(SessionEventArgs args)
359366 int bytesToRead ;
360367 if ( args . ProxyRequest . ContentLength < BUFFER_SIZE )
361368 {
362- bytesToRead = ( int ) args . ProxyRequest . ContentLength ;
369+ bytesToRead = ( int ) args . ProxyRequest . ContentLength ;
363370 }
364371 else
365372 bytesToRead = BUFFER_SIZE ;
366373
367374
368- while ( totalbytesRead < ( int ) args . ProxyRequest . ContentLength )
375+ while ( totalbytesRead < ( int ) args . ProxyRequest . ContentLength )
369376 {
370377 var buffer = args . ClientStreamReader . ReadBytes ( bytesToRead ) ;
371378 totalbytesRead += buffer . Length ;
372379
373- var remainingBytes = ( int ) args . ProxyRequest . ContentLength - totalbytesRead ;
380+ var remainingBytes = ( int ) args . ProxyRequest . ContentLength - totalbytesRead ;
374381 if ( remainingBytes < bytesToRead )
375382 {
376383 bytesToRead = remainingBytes ;
@@ -414,7 +421,6 @@ private static void SendClientRequestBody(SessionEventArgs args)
414421 }
415422 }
416423
417-
418424 postStream . Close ( ) ;
419425 }
420426 catch
0 commit comments