WebRequestHandler停止发送请求

时间:2013-02-11 10:46:17

标签: c# asp.net-web-api

我们编写了一个DelegatingHandler来处理我们正在调用的REST API的身份验证方案。但是,我们似乎陷入了内部WebRequestHandler停止发出请求的情况。

我正在寻找任何可能导致此处理程序停止工作的帮助或建议。

我已经看过了,我看不到WebRequestHandler可能有的任何内部状态 - 但是通过尝试发送消息的内部情况进行追踪,我可以在StartGettingResponse中看到(来自HttpClientHandler):

    {
        if (state.identity != null)
        {
            using (state.identity.Impersonate())
            {
                state.webRequest.BeginGetResponse(this.getResponseCallback, state);
                goto Label_0046;
            }
        }
        state.webRequest.BeginGetResponse(this.getResponseCallback, state);
    Label_0046:
        state.requestMessage.MarkRtcFlushComplete();
    }

identitynull。调用BeginGetResponse,但永远不会调用GetResponseCallbackgetResponseCallback是一个缓存的委托)。我们看到没有例外。没有网络流量(任何类型)。


我们的委托处理程序的代码:

if (request.Headers.Authorization == null)
{
    ClaimsIdentity ident = User == null ? null : User.Identity as ClaimsIdentity;
    if (PreAuthenticate)
    {
        var token = await GenerateAuthenticationToken(ident, guessedRealm,true);
        if (cancellationToken.IsCancellationRequested) return null;
        if (token != null)
        {
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
        }
    }
    var firstFlight = await base.SendAsync(request, cancellationToken);

    if (firstFlight.StatusCode != System.Net.HttpStatusCode.Unauthorized) return firstFlight;

    var wwwAuth = firstFlight.Headers.WwwAuthenticate;

    var bearerAuth = wwwAuth.SingleOrDefault(hv => hv.Scheme == "Bearer");

    var realmInfo = bearerAuth.Parameter;

    var realm = realmInfo.Substring(7).TrimEnd('"');

    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer",
        await GenerateAuthenticationToken(ident, realm,false)
    );
    if (cancellationToken.IsCancellationRequested) return null;
}
return await base.SendAsync(request, cancellationToken);

(错误检查和未删除的路径已删除 - PreAuthenticate除外false)。我们可以进入第一次调用SendAsync(如预期)返回401响应的情况。我们生成一个合适的授权令牌并将其作为标题附加。但是,第二次调用SendAsync永远不会导致任何网络流量发生。

我正在使用MS网络监视器来检查网络流量,它可以看到第一个请求(以及之前的几个请求也使用同一个处理程序,但没有遇到相同的问题)。

1 个答案:

答案 0 :(得分:0)

事实证明,我们泄漏了之前一些调用返回的HttpResponseMessage个对象,而没有调用它们上的Dispose。 (事实上​​,即使在我展示的代码段中,我们也会泄漏firstFlight

这种泄漏正在发生并不是特别明显,只有一两个泄漏就足以使后续请求在System.Net.Connection内部排队但从未实际发送过(我认为因为它强制执行HTTP连接限制)服务器)