diff --git a/nanoFramework.System.Net.Http/Http/System.Net.HttpWebRequest.cs b/nanoFramework.System.Net.Http/Http/System.Net.HttpWebRequest.cs
index 46db3e94..e1597a03 100644
--- a/nanoFramework.System.Net.Http/Http/System.Net.HttpWebRequest.cs
+++ b/nanoFramework.System.Net.Http/Http/System.Net.HttpWebRequest.cs
@@ -73,36 +73,40 @@ public class HttpWebRequest : WebRequest
/// Unused
static private void CheckPersistentConnections(object unused)
{
+ // Persistent connections have not been properly implemented yet.
int count = m_ConnectedStreams.Count;
+
// The fastest way to exit out - if there are no sockets in the list - exit out.
if (count > 0)
{
DateTime curTime = DateTime.UtcNow;
+
lock (m_ConnectedStreams)
{
count = m_ConnectedStreams.Count;
- for (int i = count-1; i >= 0; i--)
+ for (int i = count - 1; i >= 0; i--)
{
InputNetworkStreamWrapper streamWrapper = (InputNetworkStreamWrapper)m_ConnectedStreams[i];
- TimeSpan timePassed = streamWrapper.m_lastUsed - curTime;
+ TimeSpan timePassed = curTime - streamWrapper.m_lastUsed;
// If the socket is old, then close and remove from the list.
- if (timePassed.Milliseconds > HttpConstants.DefaultKeepAliveMilliseconds)
+ if (timePassed.TotalMilliseconds > HttpConstants.DefaultKeepAliveMilliseconds)
{
m_ConnectedStreams.RemoveAt(i);
-
+
// Closes the socket to release resources.
streamWrapper.Dispose();
}
}
// turn off the timer if there are no active streams
- if(m_ConnectedStreams.Count > 0)
+ if (m_ConnectedStreams.Count > 0)
{
- m_DropOldConnectionsTimer.Change( HttpConstants.DefaultKeepAliveMilliseconds, System.Threading.Timeout.Infinite );
+ m_DropOldConnectionsTimer.Change(HttpConstants.DefaultKeepAliveMilliseconds, System.Threading.Timeout.Infinite);
}
+
}
}
}
@@ -1336,8 +1340,8 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
// But first we need to know that socket is not closed.
try
{
- // If socket is closed ( from this or other side ) the call throws exception.
- if (inputStream.m_Socket.Poll(1, SelectMode.SelectWrite))
+ // If socket is closed (from this or other side) the call throws exception.
+ if (inputStream.m_Socket.Poll(-1, SelectMode.SelectWrite))
{
// No exception, good we can condtinue and re-use connected stream.
@@ -1352,7 +1356,6 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
{
removeStreamList.Add(inputStream);
}
-
}
catch (Exception)
{
@@ -1415,13 +1418,15 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
}
// If socket was not found in waiting connections, then we create new one.
- Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ Socket socket = null;
+ socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
catch{}
+
try
{
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
@@ -1436,6 +1441,9 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
}
catch (SocketException e)
{
+ // need to close socket, otherwise this will cause an out of memory exception
+ socket.Close();
+
throw new WebException("connection failed", e, WebExceptionStatus.ConnectFailure, null);
}
@@ -1476,14 +1484,18 @@ private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targe
retStream.m_rmAddrAndPort = m_originalUrl.Host + ":" + m_originalUrl.Port;
}
- lock (m_ConnectedStreams)
+ // Check keepAlive before creating persistent connection - persistent connections are not currently supported
+ if (m_keepAlive)
{
- m_ConnectedStreams.Add(retStream);
-
- // if the current stream list is empty then start the timer that drops unused connections.
- if (m_ConnectedStreams.Count == 1)
+ lock (m_ConnectedStreams)
{
- m_DropOldConnectionsTimer.Change(HttpConstants.DefaultKeepAliveMilliseconds, System.Threading.Timeout.Infinite);
+ m_ConnectedStreams.Add(retStream);
+
+ // if the current stream list is empty then start the timer that drops unused connections.
+ if (m_ConnectedStreams.Count == 1)
+ {
+ m_DropOldConnectionsTimer.Change(HttpConstants.DefaultKeepAliveMilliseconds, System.Threading.Timeout.Infinite);
+ }
}
}
}
@@ -1499,14 +1511,16 @@ private void SubmitRequest()
// We have connected socket. Create request stream
// If proxy is set - connect to proxy server.
- if(m_requestStream == null)
+ if (m_requestStream == null)
{
if (m_proxy == null)
- { // Direct connection to target server.
+ {
+ // Direct connection to target server.
m_requestStream = EstablishConnection(m_originalUrl, m_originalUrl);
}
- else // Connection through proxy. We create network stream connected to proxy
+ else
{
+ // Connection through proxy. We create network stream connected to proxy
Uri proxyUri = m_proxy.GetProxy(m_originalUrl);
if (m_originalUrl.Scheme == "https")
@@ -1522,6 +1536,13 @@ private void SubmitRequest()
}
}
+ if (m_requestStream == null)
+ {
+ // Connection could not be established
+ m_requestSent = false;
+ return;
+ }
+
// We have connected stream. Set the timeout from HttpWebRequest
m_requestStream.WriteTimeout = m_readWriteTimeout;
m_requestStream.ReadTimeout = m_readWriteTimeout;
@@ -1725,6 +1746,12 @@ public override WebResponse GetResponse()
SubmitRequest();
}
+ // Need to check m_requestSent after SubmitRequest()
+ if (!m_requestSent)
+ {
+ return response;
+ }
+
CoreResponseData respData = null;
// reset the total response bytes for the new request.
@@ -1765,8 +1792,9 @@ public override WebResponse GetResponse()
m_responseStatus = response.StatusCode;
m_responseCreated = true;
+ m_requestStream.m_InUse = false; // Persistent connections are not yet supported, but they wouldn't work without this.
}
- catch(SocketException se)
+ catch (SocketException se)
{
if (m_requestStream != null)
{
@@ -1777,12 +1805,11 @@ public override WebResponse GetResponse()
this.m_requestStream.m_Socket.Close();
}
}
-
- throw new WebException("", se);
+ throw new WebException("GetResponse() failed", se);
}
- catch(Exception e)
+ catch (Exception e)
{
- throw new WebException("", e);
+ throw new WebException("GetResponse() failed", e);
}
diff --git a/nanoFramework.System.Net.Http/Http/System.Net._OutputNetworkStreamWrapper.cs b/nanoFramework.System.Net.Http/Http/System.Net._OutputNetworkStreamWrapper.cs
index d5b827eb..46f0b1da 100644
--- a/nanoFramework.System.Net.Http/Http/System.Net._OutputNetworkStreamWrapper.cs
+++ b/nanoFramework.System.Net.Http/Http/System.Net._OutputNetworkStreamWrapper.cs
@@ -144,8 +144,9 @@ public override void Flush()
// Calls HttpListenerResponse.SendHeaders. HttpListenerResponse.SendHeaders sets m_headersSend to null.
m_headersSend();
}
-
- m_Stream.Flush();
+
+ // Need to check for null before using here
+ m_Stream?.Flush();
}
///