2011-03-01 92 views
2

我一直在與這個問題爭鬥超過2個星期,現在已經無處可尋。WebClient.DownloadString()+ REST + HTTPS + Win2003 =掛起線程

首先是環境:Windows 2003 R2 SP2/SharePoint 2007 SP1/.NET 3.5。

基本上,我們正在調用Web服務來從遠程API收集數據。 API有幾個REST端點和幾個SOAP端點。端點是使用摘要身份驗證的HTTPS端點。當我們用SOAP端點進行調用時,似乎一切正常。但是接下來我們嘗試使用REST進行調用,當IIS確定線程沒有響應並且殺死線程時,線程掛起然後死亡。起初,我們認爲這是一個SSL問題(它仍然可能是),因爲我們在使用HTTP端點(到相同API的路由不是SSL)時看不到任何問題。

下面是我們使用,使REST調用的代碼:

private void Process(HttpContext context, String url, String restParam) 
{ 
    ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(validateCertificate); 

    WriteLogMessage("Start Process"); 
    String pattern = "{0}{1}"; 
    String address = String.Format(pattern, url, restParam); 

    WriteLogMessage("ADDRESS is" + address); 
    LSWebClient client = new LSWebClient(); 
    client.Timeout = 600000; 

    WriteLogMessage("TIMEOUT (client.Timeout) is " + client.Timeout.ToString()); 
    client.Credentials = new NetworkCredential(XYZConfigurationSettings.APIUserName, XYZConfigurationSettings.APIPassword); 

    try { 
     String result = client.DownloadString(address); 
     WriteLogMessage("End Process. RESULT length is " + (result != null ? result.Length : 0)); 
     context.Response.Write(result); 
    } 
    catch (Exception ex) 
    { 
     WriteLogMessage("EXCEPTION!!! Message----" + ex.Message + "---- StackTrace ----" + ex.StackTrace + ""); 
    } 
} 

private bool validateCertificate(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error) 
{ 
    WriteLogMessage("bypassAllCertificateStuff"); 
    return true; 
} 

所以,蹩腳的代碼以外,我們在這裏放了幾件事,試圖繞過我們想什麼是SSL證書問題。 (將請求超時設置爲10分鐘,使用自定義證書驗證等)。但是,這似乎沒有解決這個問題。

下面是我們記錄的結果:

2/28/2011 3:35:28 PM: Start 
2/28/2011 3:35:28 PM: Start Process 
2/28/2011 3:35:28 PM: ADDRESS ishttps://<host>/ws/rs/v1/taxonomy/TA/root/ 
2/28/2011 3:35:28 PM: TIMEOUT (client.Timeout) is 600000 
2/28/2011 3:35:50 PM: CheckValidationResult 
2/28/2011 3:35:50 PM: bypassAllCertificateStuff 
2/28/2011 3:41:51 PM: EXCEPTION!!! Message ----Thread was being aborted.---- StackTrace ---- at System.Net.Connection.CompleteStartConnection(Boolean async, HttpWebRequest httpWebRequest) 
    at System.Net.Connection.CompleteStartRequest(Boolean onSubmitThread, HttpWebRequest request, TriState needReConnect) 
    at System.Net.Connection.SubmitRequest(HttpWebRequest request) 
    at System.Net.ServicePoint.SubmitRequest(HttpWebRequest request, String connName) 
    at System.Net.HttpWebRequest.SubmitRequest(ServicePoint servicePoint) 
    at System.Net.HttpWebRequest.GetResponse() 
    at System.Net.WebClient.GetWebResponse(WebRequest request) 
    at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) 
    at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request) 
    at System.Net.WebClient.DownloadString(Uri address) 
    at System.Net.WebClient.DownloadString(String address) 
    at XYZ.DAO.Handlers.RestServiceHandler.Process(HttpContext context, String url, String restParam) 
    at XYZ.DAO.Handlers.RestServiceHandler.ProcessRequest(HttpContext context)---- 

我試圖用我的瀏覽器來查看返回數據,但瀏覽器IE6是,它不支持SSL。但是,我可以看到(在Fiddler/Charles代理中)它確實嘗試發出請求並收到401錯誤,但由於無法使用這些程序查看服務器流量,所以無法確切知道錯誤發生的步驟。

更糟糕的是,我無法在任何其他服務器上重現此問題(注意:它們都是Windows 2008服務器)。

因此,簡言之,這裏就是我發現:

SOAP - 工作
REST - 沒有工作

的Win2008 - 工作
Win2003的 - 沒有工作

HTTP - 工作
HTTPS - 無法工作

如果任何人有任何見解或任何其他調試/信息收集,我還沒有嘗試我會非常偉大。

回答

0

我發現是什麼原因導致了Web服務調用掛 - 問題是,我們是用重放攻擊保護,以及消化調用該服務的安全性:

  1. 我們的服務器就送一個初始的 請求無安全頭
  2. 該請求被迴應與一個 標準401挑戰提供一個 nonce使用。 (即現時的 攻擊後到期 10秒後)
  3. 我們的服務器,然後花了30秒, 使用 這個隨機數
  4. 所以服務器仍然後找到 過期現時和再次發出 產生第二響應另一個401挑戰。

該循環將持續到本地服務器的線程終止。但是,爲什麼我們的本地服務器正在花費30美元@#%!生成安全頭的秒數超出了我的範圍。我檢查了通過上述診斷提供的日誌,但沒有任何幫助。我要把它記錄下來,因爲服務器超負荷,沒有足夠的內存來處理它從溼紙袋裏走出來。

2

如果將以下內容添加到客戶端.config文件中,您應該可以獲得更多的跟蹤信息。

<system.diagnostics> 
    <sources> 
     <source name="System.Net" switchValue="Information, ActivityTracing"> 
      <listeners> 
       <add name="System.Net" 
        type="System.Diagnostics.TextWriterTraceListener" 
        initializeData="System.Net.trace.log" /> 
      </listeners> 
     </source> 
    </sources> 
</system.diagnostics>