Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[HttpListener] Fix keep-alive connections

	We were removing the connection in the wrong place.
	Also unbind the context in other error situations like a read failure
	after the headers are in.
  • Loading branch information...
commit ed57d905707dd93ada957dbc180ed169b3bddb1e 1 parent fc3f496
@gonzalop gonzalop authored
View
2  mcs/class/System/System.Net/EndPointListener.cs
@@ -261,7 +261,7 @@ void CheckIfRemove ()
public void Close ()
{
sock.Close ();
- lock (unregistered) {
+ lock (unregistered.SyncRoot) {
foreach (HttpConnection c in unregistered.Keys)
c.Close (true);
unregistered.Clear ();
View
35 mcs/class/System/System.Net/HttpConnection.cs
@@ -141,6 +141,7 @@ public void BeginReadRequest ()
} catch {
timer.Change (Timeout.Infinite, Timeout.Infinite);
CloseSocket ();
+ Unbind ();
}
}
@@ -193,8 +194,10 @@ void OnReadInternal (IAsyncResult ares)
} catch {
if (ms != null && ms.Length > 0)
SendError ();
- if (sock != null)
+ if (sock != null) {
CloseSocket ();
+ Unbind ();
+ }
return;
}
@@ -202,6 +205,7 @@ void OnReadInternal (IAsyncResult ares)
//if (ms.Length > 0)
// SendError (); // Why bother?
CloseSocket ();
+ Unbind ();
return;
}
@@ -218,24 +222,30 @@ void OnReadInternal (IAsyncResult ares)
if (!epl.BindContext (context)) {
SendError ("Invalid host", 400);
Close (true);
+ return;
}
- if (last_listener == null)
- epl.RemoveConnection (this);
- else
- last_listener.RemoveConnection (this);
-
HttpListener listener = context.Listener;
- if (listener != null) {
+ if (last_listener != listener) {
+ RemoveConnection ();
listener.AddConnection (this);
- context_bound = true;
+ last_listener = listener;
}
- last_listener = listener;
+
+ context_bound = true;
listener.RegisterContext (context);
return;
}
stream.BeginRead (buffer, 0, BufferSize, onread_cb, this);
}
+ void RemoveConnection ()
+ {
+ if (last_listener == null)
+ epl.RemoveConnection (this);
+ else
+ last_listener.RemoveConnection (this);
+ }
+
enum InputState {
RequestLine,
Headers
@@ -371,7 +381,6 @@ public void SendError ()
void Unbind ()
{
if (context_bound) {
- context.Listener.RemoveConnection (this);
epl.UnbindContext (context);
context_bound = false;
}
@@ -393,8 +402,7 @@ void CloseSocket ()
} finally {
sock = null;
}
- if (last_listener == null)
- epl.RemoveConnection (this);
+ RemoveConnection ();
}
internal void Close (bool force_close)
@@ -447,8 +455,7 @@ internal void Close (bool force_close)
s.Close ();
}
Unbind ();
- if (last_listener == null)
- epl.RemoveConnection (this);
+ RemoveConnection ();
return;
}
}
View
6 mcs/class/System/System.Net/HttpListener.cs
@@ -161,7 +161,7 @@ void Cleanup (bool close_existing)
all [i].Connection.Close (true);
}
- lock (connections) {
+ lock (connections.SyncRoot) {
ICollection keys = connections.Keys;
var conns = new HttpConnection [keys.Count];
keys.CopyTo (conns, 0);
@@ -170,9 +170,7 @@ void Cleanup (bool close_existing)
conns [i].Close (true);
}
lock (ctx_queue) {
- ICollection keys = connections.Keys;
- var ctxs = new HttpListenerContext [keys.Count];
- keys.CopyTo (ctxs, 0);
+ var ctxs = (HttpListenerContext []) ctx_queue.ToArray (typeof (HttpListenerContext));
ctx_queue.Clear ();
for (int i = ctxs.Length - 1; i >= 0; i--)
ctxs [i].Connection.Close (true);
Please sign in to comment.
Something went wrong with that request. Please try again.