C# WebClient.DownloadString()和#x2B;休息+;HTTPS+;Win2003=挂线

C# WebClient.DownloadString()和#x2B;休息+;HTTPS+;Win2003=挂线,c#,rest,.net-3.5,ssl,https,C#,Rest,.net 3.5,Ssl,Https,我已经和这个问题斗争了两个多星期了,但还是一事无成 首先是环境:Windows 2003 R2 SP2/SharePoint 2007 SP1/.NET 3.5 基本上,我们正在进行web服务调用以从远程API收集数据。该API有几个REST端点和几个SOAP端点。端点是具有摘要身份验证的HTTPS端点。当我们使用SOAP端点进行调用时,一切似乎都正常工作。但是,我们尝试使用REST进行调用,当IIS确定线程不再响应并杀死它时,线程挂起,然后可怕地死亡。起初,我们认为这是一个SSL问题(现在可能

我已经和这个问题斗争了两个多星期了,但还是一事无成

首先是环境: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)----
2011年2月28日下午3:35:28:开始
2011年2月28日下午3:35:28:启动流程
2011年2月28日下午3:35:28:地址ishttps:///ws/rs/v1/taxonomy/TA/root/
2011年2月28日下午3:35:28:超时(client.TIMEOUT)为600000
2011年2月28日下午3:35:50:CheckValidationResult
2011年2月28日下午3:35:50:绕过所有证书
2011年2月28日下午3:41:51:例外!!!消息-----线程被中止。---StackTrace---at System.Net.Connection.CompleteTastarConnection(布尔异步,HttpWebRequest HttpWebRequest)
在System.Net.Connection.CompleteStartRequest(布尔onSubmitThread、HttpWebRequest请求、三态needReConnect)
在System.Net.Connection.SubmitRequest(HttpWebRequest请求)中
位于System.Net.ServicePoint.SubmitRequest(HttpWebRequest请求,字符串名称)
位于System.Net.HttpWebRequest.SubmitRequest(ServicePoint ServicePoint)
在System.Net.HttpWebRequest.GetResponse()中
位于System.Net.WebClient.GetWebResponse(WebRequest请求)
在System.Net.WebClient.DownloadBits(WebRequest请求、流写入流、CompletionDelegate CompletionDelegate、AsyncOperation asyncOp)
位于System.Net.WebClient.DownloadDataInternal(Uri地址、WebRequest和request)
位于System.Net.WebClient.DownloadString(Uri地址)
位于System.Net.WebClient.DownloadString(字符串地址)
在XYZ.DAO.Handlers.RestServiceHandler.Process(HttpContext上下文、字符串url、字符串restParam)
位于XYZ.DAO.Handlers.RestServiceHandler.ProcessRequest(HttpContext上下文)----
我尝试使用浏览器查看返回数据,但浏览器是IE6,它不支持SSL。但是,我可以看到(在Fiddler/Charles proxy中),它确实尝试发出请求并收到401错误,但由于我无法看到使用这些程序的服务器通信量,因此我无法确切地说出错误发生的步骤

更糟糕的是,我无法在我拥有的任何其他服务器上重现此问题(注意:它们都是Windows 2008服务器)

总之,我发现:

SOAP-work
休息-不工作

Win2008-工作
Win2003-不工作

HTTP-work
HTTPS-无工作


如果任何人有任何见解或任何其他调试/信息收集,而我没有尝试过,我将非常感谢。

如果将以下内容添加到client.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>

我找到了导致web服务调用挂起的原因-问题是我们调用的服务使用了重播攻击保护和摘要安全:

  • 我们的服务器将发送一个初始值 请求SAN安全标头
  • 对这一请求作出了答复 标准401挑战提供 暂时使用。(该临时期限到期 测试后10秒后 挑战)
  • 然后,我们的服务器花了30秒来恢复 使用以下命令生成第二个响应: 现在
  • 这样远程服务器就可以找到 过期的临时文件和一次又一次的问题 另一个挑战
  • 该循环将继续,直到本地服务器的线程终止。但是,为什么我们的本地服务器占用30$@#%!我无法用几秒钟来生成安全标头。我检查了通过上面的诊断提供的日志,但没有一个有多大帮助。我将把这归咎于服务器过载,并且没有足够的内存来处理湿纸袋中的数据