I need to implement a simple HTTP server using the HttpListener which redirects the browser to another web (after visiting http://127.0.0.1:8080) and then self-closes (after a successful response). I implemented it in this way:
var httpListener = new HttpListener();
try
{
httpListener.Prefixes.Add("http://127.0.0.1:8080/");
httpListener.Start();
var context = await httpListener.GetContextAsync();
context.Response.Redirect("https://stackoverflow.com/");
context.Response.Close();
}
catch (Exception ex)
{
// ...
}
finally
{
httpListener?.Close();
}
but it doesn't work very reliably - in ~50% of cases my browser ends up with "ERR_CONNECTION_REFUSED". It seems, that httpListener.Close() is called before the request is finished, so the browser loses the connection while receiving the HTTP data. I didn't find any way/callback to get notified when the request is fulfilled, so I can close the listener safely. I ended up with a workaround by adding the await Task.Delay(1000); before closing the HTTP listener, which works fine and my browser is always redirected:
var httpListener = new HttpListener();
try
{
httpListener.Prefixes.Add("http://127.0.0.1:8080/");
httpListener.Start();
var context = await httpListener.GetContextAsync();
context.Response.Redirect("https://stackoverflow.com/");
context.Response.Close();
await Task.Delay(1000); // Ugly workaround
}
catch (Exception ex)
{
// ...
}
finally
{
httpListener?.Close();
}
Is there a more elegant way to automatically close the HttpListener and be sure, that the request has been fulfilled?