@@ -73,36 +73,40 @@ public class HttpWebRequest : WebRequest
7373 /// <param name="unused">Unused</param>
7474 static private void CheckPersistentConnections ( object unused )
7575 {
76+ // Persistent connections have not been properly implemented yet.
7677 int count = m_ConnectedStreams . Count ;
78+
7779 // The fastest way to exit out - if there are no sockets in the list - exit out.
7880 if ( count > 0 )
7981 {
8082 DateTime curTime = DateTime . UtcNow ;
83+
8184 lock ( m_ConnectedStreams )
8285 {
8386 count = m_ConnectedStreams . Count ;
8487
85- for ( int i = count - 1 ; i >= 0 ; i -- )
88+ for ( int i = count - 1 ; i >= 0 ; i -- )
8689 {
8790 InputNetworkStreamWrapper streamWrapper = ( InputNetworkStreamWrapper ) m_ConnectedStreams [ i ] ;
8891
89- TimeSpan timePassed = streamWrapper . m_lastUsed - curTime ;
92+ TimeSpan timePassed = curTime - streamWrapper . m_lastUsed ;
9093
9194 // If the socket is old, then close and remove from the list.
92- if ( timePassed . Milliseconds > HttpConstants . DefaultKeepAliveMilliseconds )
95+ if ( timePassed . TotalMilliseconds > HttpConstants . DefaultKeepAliveMilliseconds )
9396 {
9497 m_ConnectedStreams . RemoveAt ( i ) ;
95-
98+
9699 // Closes the socket to release resources.
97100 streamWrapper . Dispose ( ) ;
98101 }
99102 }
100103
101104 // turn off the timer if there are no active streams
102- if ( m_ConnectedStreams . Count > 0 )
105+ if ( m_ConnectedStreams . Count > 0 )
103106 {
104- m_DropOldConnectionsTimer . Change ( HttpConstants . DefaultKeepAliveMilliseconds , System . Threading . Timeout . Infinite ) ;
107+ m_DropOldConnectionsTimer . Change ( HttpConstants . DefaultKeepAliveMilliseconds , System . Threading . Timeout . Infinite ) ;
105108 }
109+
106110 }
107111 }
108112 }
@@ -1336,8 +1340,8 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
13361340 // But first we need to know that socket is not closed.
13371341 try
13381342 {
1339- // If socket is closed ( from this or other side ) the call throws exception.
1340- if ( inputStream . m_Socket . Poll ( 1 , SelectMode . SelectWrite ) )
1343+ // If socket is closed (from this or other side) the call throws exception.
1344+ if ( inputStream . m_Socket . Poll ( - 1 , SelectMode . SelectWrite ) )
13411345 {
13421346 // No exception, good we can condtinue and re-use connected stream.
13431347
@@ -1352,7 +1356,6 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
13521356 {
13531357 removeStreamList . Add ( inputStream ) ;
13541358 }
1355-
13561359 }
13571360 catch ( Exception )
13581361 {
@@ -1415,13 +1418,15 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
14151418 }
14161419
14171420 // If socket was not found in waiting connections, then we create new one.
1418- Socket socket = new Socket ( AddressFamily . InterNetwork , SocketType . Stream , ProtocolType . Tcp ) ;
1421+ Socket socket = null ;
1422+ socket = new Socket ( AddressFamily . InterNetwork , SocketType . Stream , ProtocolType . Tcp ) ;
14191423
14201424 try
14211425 {
14221426 socket . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . ReuseAddress , true ) ;
14231427 }
14241428 catch { }
1429+
14251430 try
14261431 {
14271432 socket . SetSocketOption ( SocketOptionLevel . Tcp , SocketOptionName . NoDelay , true ) ;
@@ -1436,6 +1441,9 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
14361441 }
14371442 catch ( SocketException e )
14381443 {
1444+ // need to close socket, otherwise this will cause an out of memory exception
1445+ socket . Close ( ) ;
1446+
14391447 throw new WebException ( "connection failed" , e , WebExceptionStatus . ConnectFailure , null ) ;
14401448 }
14411449
@@ -1476,14 +1484,18 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
14761484 retStream . m_rmAddrAndPort = m_originalUrl . Host + ":" + m_originalUrl . Port ;
14771485 }
14781486
1479- lock ( m_ConnectedStreams )
1487+ // Check keepAlive before creating persistent connection - persistent connections are not currently supported
1488+ if ( m_keepAlive )
14801489 {
1481- m_ConnectedStreams . Add ( retStream ) ;
1482-
1483- // if the current stream list is empty then start the timer that drops unused connections.
1484- if ( m_ConnectedStreams . Count == 1 )
1490+ lock ( m_ConnectedStreams )
14851491 {
1486- m_DropOldConnectionsTimer . Change ( HttpConstants . DefaultKeepAliveMilliseconds , System . Threading . Timeout . Infinite ) ;
1492+ m_ConnectedStreams . Add ( retStream ) ;
1493+
1494+ // if the current stream list is empty then start the timer that drops unused connections.
1495+ if ( m_ConnectedStreams . Count == 1 )
1496+ {
1497+ m_DropOldConnectionsTimer . Change ( HttpConstants . DefaultKeepAliveMilliseconds , System . Threading . Timeout . Infinite ) ;
1498+ }
14871499 }
14881500 }
14891501 }
@@ -1499,14 +1511,16 @@ private void SubmitRequest()
14991511 // We have connected socket. Create request stream
15001512 // If proxy is set - connect to proxy server.
15011513
1502- if ( m_requestStream == null )
1514+ if ( m_requestStream == null )
15031515 {
15041516 if ( m_proxy == null )
1505- { // Direct connection to target server.
1517+ {
1518+ // Direct connection to target server.
15061519 m_requestStream = EstablishConnection ( m_originalUrl , m_originalUrl ) ;
15071520 }
1508- else // Connection through proxy. We create network stream connected to proxy
1521+ else
15091522 {
1523+ // Connection through proxy. We create network stream connected to proxy
15101524 Uri proxyUri = m_proxy . GetProxy ( m_originalUrl ) ;
15111525
15121526 if ( m_originalUrl . Scheme == "https" )
@@ -1522,6 +1536,13 @@ private void SubmitRequest()
15221536 }
15231537 }
15241538
1539+ if ( m_requestStream == null )
1540+ {
1541+ // Connection could not be established
1542+ m_requestSent = false ;
1543+ return ;
1544+ }
1545+
15251546 // We have connected stream. Set the timeout from HttpWebRequest
15261547 m_requestStream . WriteTimeout = m_readWriteTimeout ;
15271548 m_requestStream . ReadTimeout = m_readWriteTimeout ;
@@ -1725,6 +1746,12 @@ public override WebResponse GetResponse()
17251746 SubmitRequest ( ) ;
17261747 }
17271748
1749+ // Need to check m_requestSent after SubmitRequest()
1750+ if ( ! m_requestSent )
1751+ {
1752+ return response ;
1753+ }
1754+
17281755 CoreResponseData respData = null ;
17291756
17301757 // reset the total response bytes for the new request.
@@ -1765,8 +1792,9 @@ public override WebResponse GetResponse()
17651792 m_responseStatus = response . StatusCode ;
17661793
17671794 m_responseCreated = true ;
1795+ m_requestStream . m_InUse = false ; // Persistent connections are not yet supported, but they wouldn't work without this.
17681796 }
1769- catch ( SocketException se )
1797+ catch ( SocketException se )
17701798 {
17711799 if ( m_requestStream != null )
17721800 {
@@ -1777,12 +1805,11 @@ public override WebResponse GetResponse()
17771805 this . m_requestStream . m_Socket . Close ( ) ;
17781806 }
17791807 }
1780-
1781- throw new WebException ( "" , se ) ;
1808+ throw new WebException ( "GetResponse() failed" , se ) ;
17821809 }
1783- catch ( Exception e )
1810+ catch ( Exception e )
17841811 {
1785- throw new WebException ( "" , e ) ;
1812+ throw new WebException ( "GetResponse() failed " , e ) ;
17861813 }
17871814
17881815
0 commit comments