HttpClient.SendAsync HttpException: The Client Disconnected

4

I have an ASP.NET web API application hosted in a Windows Azure Web Role. The purpose of this application is to proxy Http Requests to other web enabled endpoints - such as a Service Bus Relay and return their response.

On occasion our application throws an exception when sending a request with a significant (>5MB) payload. This might happen 1 in 20 requests with a large payload.

Exception Details: System.AggregateException: One or more errors occurred. ---> System.Web.HttpException: The client disconnected.
at System.Web.Hosting.IIS7WorkerRequest.EndRead(IAsyncResult asyncResult) at System.Web.HttpBufferlessInputStream.EndRead(IAsyncResult asyncResult) at System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar) --- End of inner exception stack trace --- ---> (Inner Exception #0) System.Web.HttpException (0x800703E3): The client disconnected. at System.Web.Hosting.IIS7WorkerRequest.EndRead(IAsyncResult asyncResult) at System.Web.HttpBufferlessInputStream.EndRead(IAsyncResult asyncResult) at System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar)<--- ; TraceSource 'w3wp.exe' event

We send these Http Requests using the System.Net.HttpClient in .NET 4.5.

public class ProxyController : ApiController
{
    private static readonly HttpClient HttpClient = new HttpClient();
    private static readonly Uri BaseUri = new Uri("http://webendpoint.com");

    public HttpResponseMessage Post()
    {
        var newUri = new Uri(BaseUri, Request.RequestUri.PathAndQuery);
        var request = new HttpRequestMessage(HttpMethod.Post, newUri)
                {
                    Content = this.Request.Content
                };

        var task = HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
        task.Wait();
        var response = task.Result;
        return new HttpResponseMessage(response.StatusCode)
        {
            Content = new PushStreamContent((stream, content, ctx) =>
            {
                var tempStream = response.Content.ReadAsStreamAsync().Result;
                tempStream.CopyToAsync(stream).Wait();
                stream.Flush();
                stream.Close();
            })
        };
    }
}

Any thoughts on what could be causing this problem?

c#
asp.net
asp.net-web-api
dotnet-httpclient
asked on Stack Overflow May 23, 2013 by Gavin Osborn • edited May 23, 2013 by Gavin Osborn

1 Answer

1

Try returning a Task version, then replace the sync code with async. No more ".Results" stuff, instead use the "await" keyword and put the "asyc" keyword on your method. Something like this:

public class ProxyController : ApiController
{
    private static readonly HttpClient HttpClient = new HttpClient();
    private static readonly Uri BaseUri = new Uri("http://webendpoint.com");

    public async Task<HttpResponseMessage> Post()
    {
        var newUri = new Uri(BaseUri, Request.RequestUri.PathAndQuery);
        var request = new HttpRequestMessage(HttpMethod.Post, newUri)
        {
            Content = Request.Content
        };

        var response = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

        return new HttpResponseMessage(response.StatusCode)
        {
            Content = new PushStreamContent(async (stream, content, ctx) =>
            {
                var tempStream = await response.Content.ReadAsStreamAsync();
                await tempStream.CopyToAsync(stream);
                stream.Flush();
                stream.Close();
            })
        };
    }
}
answered on Stack Overflow Nov 5, 2014 by Paul Fryer

User contributions licensed under CC BY-SA 3.0