I'm writing an application that proxies some HTTP requests using the ASP.NET Web API and I am struggling to identify the source of an intermittent error.
It seems like a race condition... but I'm not entirely sure.
Before I go into detail here is the general communication flow of the application:
- The Client makes a HTTP request to Proxy 1. - Proxy 1 relays the contents of the HTTP request to Proxy 2. - Proxy 2 relays the contents of the HTTP request to the Target Web Application. - Target Web App responds to the HTTP request and the response is streamed (chunked transfer) to Proxy 2. - Proxy 2 returns the response to Proxy 1 which in turn responds to the original calling Client.
The Proxy applications are written in ASP.NET Web API RTM using .NET 4.5. The code to perform the relay looks like so:
出现间歇性错误的内容如下:
当抛出异常时,Visual Studio无法捕获异常。 但是,可以在Global.asax Application_Error事件中捕获错误。 不幸的是,异常没有堆栈跟踪信息。
代理应用程序托管在Azure Web角色中。
如果能够帮助识别罪犯将不胜感激。
Before I go into detail here is the general communication flow of the application:
- The Client makes a HTTP request to Proxy 1. - Proxy 1 relays the contents of the HTTP request to Proxy 2. - Proxy 2 relays the contents of the HTTP request to the Target Web Application. - Target Web App responds to the HTTP request and the response is streamed (chunked transfer) to Proxy 2. - Proxy 2 returns the response to Proxy 1 which in turn responds to the original calling Client.
The Proxy applications are written in ASP.NET Web API RTM using .NET 4.5. The code to perform the relay looks like so:
//Controller entry point.
public HttpResponseMessage Post()
{
using (var client = new HttpClient())
{
var request = BuildRelayHttpRequest(this.Request);
//HttpCompletionOption.ResponseHeadersRead - so that I can start streaming the response as soon
//As it begins to filter in.
var relayResult = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;
var returnMessage = BuildResponse(relayResult);
return returnMessage;
}
}
private static HttpRequestMessage BuildRelayHttpRequest(HttpRequestMessage incomingRequest)
{
var requestUri = BuildRequestUri();
var relayRequest = new HttpRequestMessage(incomingRequest.Method, requestUri);
if (incomingRequest.Method != HttpMethod.Get && incomingRequest.Content != null)
{
relayRequest.Content = incomingRequest.Content;
}
//Copies all safe HTTP headers (mainly content) to the relay request
CopyHeaders(relayRequest, incomingRequest);
return relayRequest;
}
private static HttpRequestMessage BuildResponse(HttpResponseMessage responseMessage)
{
var returnMessage = Request.CreateResponse(responseMessage.StatusCode);
returnMessage.ReasonPhrase = responseMessage.ReasonPhrase;
returnMessage.Content = CopyContentStream(responseMessage);
//Copies all safe HTTP headers (mainly content) to the response
CopyHeaders(returnMessage, responseMessage);
}
private static PushStreamContent CopyContentStream(HttpResponseMessage sourceContent)
{
var content = new PushStreamContent(async (stream, context, transport) =>
await sourceContent.Content.ReadAsStreamAsync()
.ContinueWith(t1 => t1.Result.CopyToAsync(stream)
.ContinueWith(t2 => stream.Dispose())));
return content;
}
出现间歇性错误的内容如下:
通常情况下,此错误会在代理应用程序的前几个请求中发生,之后不再出现。异步模块或处理程序在仍有异步操作挂起时已完成。
当抛出异常时,Visual Studio无法捕获异常。 但是,可以在Global.asax Application_Error事件中捕获错误。 不幸的是,异常没有堆栈跟踪信息。
代理应用程序托管在Azure Web角色中。
如果能够帮助识别罪犯将不胜感激。