WebRequestHandler 停止发送请求

本文关键字:请求 WebRequestHandler | 更新日期: 2023-09-27 17:58:43

我们编写了一个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被调用,但GetResponseCallback(getResponseCallback是其缓存委托(永远不会被调用。我们也不例外。没有网络流量(任何类型的(。


委托处理程序的代码:

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 网络监视器检查网络流量,它可以看到第一个请求(以及之前也使用此相同处理程序但没有遇到相同问题的几个请求(。

WebRequestHandler 停止发送请求

事实证明,我们正在泄漏一些先前调用返回的HttpResponseMessage对象,而不是对它们调用Dispose。(事实上,即使在我展示的代码片段中,我们也泄漏了firstFlight (

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