2013-02-11 162 views
0

我們編寫了一個DelegatingHandler,用於處理我們調用的REST API的身份驗證方案。但是,我們似乎進入了內部WebRequestHandler停止發出請求的情況。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(); 
    } 

identitynullBeginGetResponse被調用,但不會調用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); 

(錯誤檢查和路徑不隨之除去 - 除非PreAuthenticatefalse)。我們可以進入第一個撥打SendAsync的電話返回(如預期的)401響應的情況。我們生成一個合適的授權令牌並將其作爲標題附加。但第二次撥打電話SendAsync絕不會導致任何網絡流量發生。我正在使用MS網絡監視器來檢查網絡流量,它可以看到第一個請求(和幾個先前的請求也使用這個相同的處理程序,但不會遇到同樣的問題)。

回答

0

事實證明,我們正在泄漏一些以前的調用返回的HttpResponseMessage對象,而不是調用Dispose對象。 (事實上​​,即使是在代碼片段我已經證明,我們泄露firstFlight

這不是特別明顯,此泄漏發生,並且只有一個或兩個泄漏的是足夠的後續請求被System.Net.Connection內部排隊但從來沒有真正發送(我認爲是因爲它強制每個服務器的HTTP連接限制)