为什么HttpClient.SendAsync会抛出异常?

时间:2016-03-04 19:20:06

标签: c# dotnet-httpclient

我有一个C#应用程序,它充当外部REST API的伪HTTP代理。我正在使用System.Net.HttpListener侦听请求,并使用System.Net.Http.HttpClient向上游转发请求。一旦我收到回复,我就会发回给原始请求者(客户端)。如果我在执行此操作时遇到异常,则会向客户端返回400状态代码,并返回一个包含exception.ToString()的简单网页。它天真地假设,如果它无法到达要求的位置,那就是客户端的错,因为URL很糟糕等等。

这基本上就是我正在做的事情:

private async Task ProcessRequestAsync(HttpListenerContext context)
{
    try {
        HttpRequestMessage requestMessage = new HttpRequestMessage();

        //Some code to set up the requestMessage

        HttpResponseMessage responseMessage = await client.SendAsync(requestMessage).ConfigureAwait(false);

        //Some code to set up the context.Response

        using (Stream s = context.Response.OutputStream) {
            byte[] replyContent = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
            s.Write(replyContent, 0, replyContent.Length);
        }

    } catch (Exception e) {
        try {
            Trace.TraceWarning("Unable to handle request.\r\n{0}", e.ToString());
            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
            context.Response.StatusDescription = "Bad Request";
            context.Request.Headers.Clear();
            context.Response.ContentEncoding = Encoding.UTF8;
            context.Response.ContentType = "text/html";
            context.Response.ProtocolVersion = context.Request.ProtocolVersion;
            context.Response.KeepAlive = false;
            context.Response.SendChunked = false;
            using (Stream s = context.Response.OutputStream) {
                byte[] content = Encoding.UTF8.GetBytes(
                    "<!DOCTYPE html>\r\n" +
                    "<html lang=\"en\">\r\n" +
                    "    <head>\r\n" +
                    "        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\" />\r\n" +
                    "        <title>Error</title>\r\n" +
                    "    </head>\r\n" +
                    "    <body>\r\n" +
                    "        <h1>Error: Unable to handle request.</h1>\r\n" +
                    "        <pre>" + e.ToString().Replace("&", "&amp;")
                                                  .Replace("<", "&lt;")
                                                  .Replace(">", "&gt;") + "</pre>\r\n" +
                    "    </body>\r\n" +
                    "</html>\r\n");
                context.Response.ContentLength64 = content.Length;
                s.Write(content, 0, content.Length);
            }
        } catch (Exception f) {
            Trace.TraceError("Could not send response back to requester.\r\n{0}", f.ToString());
        }
    }
}

问题是有时502(坏网关)状态将引发异常并导致客户端接收HTTP状态代码400,但有时它不会,客户端获取正确的502状态代码。如果我得到一个,我想总是返回正确的HTTP状态代码。

以下是例外:

System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The remote server returned an error: (502) Bad Gateway.
   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
   --- End of inner exception stack trace ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Runner.Runner.<ProcessRequestAsync>d__9.MoveNext()

编辑:

以下是调用ProcessRequestAsync的代码。 server是我的HttpListener的名称,此代码作为Windows服务运行。

public void Start()
{
    server.Start();
    Task.Run(async () => {
        while (true)
            try {
                var context = await server.GetContextAsync();
                // I'm using Task.Run here without await so I can
                // immediately listen for another request
                Task.Run(() => ProcessRequestAsync(context));
            } catch (HttpListenerException) {
                break; // Listener stopped.
            } catch (InvalidOperationException) {
                break; // Listener stopped.
            }
    });
}

0 个答案:

没有答案