是什么让这个HTTPS WebRequest即使在浏览器中运行也会超时?

这是我的要求:

var request = (HttpWebRequest) WebRequest.Create("https://mtgox.com/"); request.CookieContainer = new CookieContainer(); request.AllowAutoRedirect = false; request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate"; request.Headers[HttpRequestHeader.AcceptLanguage] = "en-gb,en;q=0.5"; request.Headers[HttpRequestHeader.AcceptCharset] = "ISO-8859-1,utf-8;q=0.7,*;q=0.7"; request.Timeout = 5000; request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0"; request.Method = "GET"; request.GetResponse(); 

使用HttpFox从Firefox复制标题。 我使用Fiddler2来validation至少对于HTTP请求,标头在Firefox请求和我的请求之间是完全相同的。

但是,当使用HTTPS 对此特定网站执行请求时,请求会超时。 它适用于其他网站。

我必须以与Firefox不同的方式执行它,因为它始终适用于Firefox。 但是,我无法使用Fiddler2调试它,因为每当Fiddler2转发这些请求时,它们也会超时 ,即使是由Firefox发起的。

它只是一个非常错误的网站吗? 上面的哪一部分让我离开了不是Firefox?

使用Microsoft网络监视器,我发现HttpWebRequest将陷入它应该发送回客户端密钥交换的阶段。 它根本没有。 服务器正式等待它,但它从未到来。

修复它的原因是强制HttpWebRequest使用SSL3而不是TLS(即使TLS应该在必要时自动变成SSL3):

 ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 

为什么会这样,我想我永远都不会知道 – 只是其中一个需要花费更多时间来解决的神秘事物比我认识的任何人都愿意花…

捕获的一个不同之处是:TLS变体在服务器Hello响应中有一个“警报”条目, SSL3交换中没有,也没有实际工作的所有TLS交换。 但奇怪的是,在成功执行请求的Firefox捕获中存在相同的警报。

最后,当我第一次发布这个问题时,似乎有一个临时的OCSP故障,这个问​​题已经解决了。 这增加了混乱,但不是核心问题。

使用HttpWebRequest / HttpWebReponse调用发生超时错误的典型原因是“不关闭响应对象/流”,这会使连接保持活动状态。 您必须在读取流的内容后关闭Stream对象或HttpWebResponse对象。 默认连接限制为2。

 HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); Stream stream = webResponse.GetResponseStream(); string responseString = ((TextReader)new StreamReader(stream)).ReadToEnd(); webResponse.Close(); 

或者,如果您在将由许多用户同时调用的Web服务中实现您的逻辑,那么您可能需要考虑增加HttpWebRequest对象中的连接限制。

 HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(url); webRequest.ServicePoint.ConnectionLimit = 20; 

Windows 7上的.NET框架实现了TLS扩展:服务器名称指示(RFC4366)。 根据您的post这个TLS警报是什么意思服务器响应“无法识别的名称”。 不知道为什么连接被报告超时,因为它确实没有。 您的网络跟踪应显示客户端在此[FIN,ACK]之后启动连接终止。 降级到SSL3可以避免调用SNI。

仅供参考:Windows XP上的相同.NET框架不使用TLS服务器名称指示扩展。 你的程序将在那里工作….

在我的例子中,我追溯到Apache中缺少ServerName指令的情况。 将ServerName添加到SSL配置解决了它,因为现在Web服务器不再不知道它的名称。

最近发现了同样的问题,并希望看看微软是否可以在较新的.net版本中修复此问题。 这是我测试的代码(为隐私而删除了域名):

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.xxSomeDomainNamexx.com/"); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader reader = new StreamReader(response.GetResponseStream()); Console.WriteLine(reader.ReadToEnd()); 

针对.net版本2.0,3.0和3.5进行了编译,所有人似乎都表现出与此处讨论过的人完全相同的行为。 然后我尝试编译4.0和4.5,并在两个地方收到适当的响应。

基于此,似乎微软可能已经在较新的.net版本中解决了这个问题。 对于后人,我还测试了enverpex建议的SecurityProtocol更改,它在2.0,3.0和3.5上运行良好。

我有与https请求相同的超时问题,但没有一个答案对我有帮助。 刚才我找到了解决问题的解决方案。 请注意,这仅适用于.net framework 4.5或更高版本。

 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; var response = WebRequest.Create("https://yoursecurewebservice").GetResponse(); var body = new StreamReader(response.GetResponseStream()).ReadToEnd(); Console.WriteLine(body); 

很可能HTTPS客户端无法validation此服务器提供的证书链,例如由于缺少根证书或无法访问的OCSP响应程序。 即,您可以在浏览器和您使用的HTTPS客户端中配置不同的配置。

作为其中一个选项,您可以使用我们的HTTPBlackbox组件的试用版,并尝试使用TElHTTPSClient进行连接。 它将为您提供详细的错误信息(如果出现错误),那么您将能够确定HttpWebRequest有什么问题。