Skip to content

Commit

Permalink
[HttpListener] Match exceptions from MS on cleanup.
Browse files Browse the repository at this point in the history
	When the listener is aborted or closed, we get different exceptions
	depending on whether there's a GetContext() call in progress or not.
  • Loading branch information
gonzalop committed Mar 22, 2011
1 parent b889755 commit f6ba4f7
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
9 changes: 7 additions & 2 deletions mcs/class/System/System.Net/HttpListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,9 @@ void Cleanup (bool close_existing)
}

lock (wait_queue) {
Exception exc = new ObjectDisposedException ("listener");
foreach (ListenerAsyncResult ares in wait_queue) {
ares.Complete ("Listener was closed.");
ares.Complete (exc);
}
wait_queue.Clear ();
}
Expand Down Expand Up @@ -218,6 +219,9 @@ public HttpListenerContext EndGetContext (IAsyncResult asyncResult)
ListenerAsyncResult ares = asyncResult as ListenerAsyncResult;
if (ares == null)
throw new ArgumentException ("Wrong IAsyncResult.", "asyncResult");
if (ares.EndCalled)
throw new ArgumentException ("Cannot reuse this IAsyncResult");
ares.EndCalled = true;

if (!ares.IsCompleted)
ares.AsyncWaitHandle.WaitOne ();
Expand Down Expand Up @@ -247,7 +251,8 @@ public HttpListenerContext GetContext ()
if (prefixes.Count == 0)
throw new InvalidOperationException ("Please, call AddPrefix before using this method.");

IAsyncResult ares = BeginGetContext (null, null);
ListenerAsyncResult ares = (ListenerAsyncResult) BeginGetContext (null, null);
ares.InGet = true;
return EndGetContext (ares);
}

Expand Down
13 changes: 8 additions & 5 deletions mcs/class/System/System.Net/ListenerAsyncResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,24 @@ class ListenerAsyncResult : IAsyncResult {
HttpListenerContext context;
object locker = new object ();
ListenerAsyncResult forward;
internal bool EndCalled;
internal bool InGet;

public ListenerAsyncResult (AsyncCallback cb, object state)
{
this.cb = cb;
this.state = state;
}

internal void Complete (string error)
internal void Complete (Exception exc)
{
if (forward != null) {
forward.Complete (error);
forward.Complete (exc);
return;
}
//FIXME: error_code?
exception = new HttpListenerException (0, error);
exception = exc;
if (InGet && (exc is ObjectDisposedException))
exception = new HttpListenerException (500, "Listener closed");
lock (locker) {
completed = true;
if (handle != null)
Expand Down Expand Up @@ -109,7 +112,7 @@ internal void Complete (HttpListenerContext context, bool synch)
ListenerAsyncResult next = forward;
for (int i = 0; next.forward != null; i++) {
if (i > 20)
Complete ("Too many authentication errors");
Complete (new HttpListenerException (400, "Too many authentication errors"));
next = next.forward;
}
} else {
Expand Down
2 changes: 0 additions & 2 deletions mcs/class/System/Test/System.Net/HttpListenerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ public void PropertiesWhenClosed3 ()
}

[Test]
[Category ("NotWorking")] // we throw a HttpListenerException
public void CloseWhileBegin ()
{
HttpListener listener = new HttpListener ();
Expand All @@ -297,7 +296,6 @@ public void CloseWhileBegin ()
}

[Test]
[Category ("NotWorking")] // we throw a HttpListenerException
public void AbortWhileBegin ()
{
HttpListener listener = new HttpListener ();
Expand Down

0 comments on commit f6ba4f7

Please sign in to comment.