【问题标题】:Simple HttpWebRequest over SSL (https) gives 404 Not Found under C#SSL (https) 上的简单 HttpWebRequest 在 C# 下找不到 404
【发布时间】:2009-04-20 12:22:38
【问题描述】:

我想向一个安全连接上的 php 编写的 Web 服务进行 POST。以下代码只是我经过几个小时的反复试验后编写的测试控制台应用程序。本质上,我发现了一些使用 HttpWebRequest 的不同方法,但它们都是一样的。

在网络浏览器上使用“http”测试我的 URI,应该返回一个空白的 html(带有一个空的正文)。这在浏览器和我的代码中可以正常工作。

我尝试了http://www.google.com,然后我得到了谷歌……(如预期的那样)。 当我将 URI 从 http 更改为 https 时,就会出现问题。 在 Web 浏览器 上使用“https”测试我的 URI,返回相同的空白 html(这是预期的)。 但是当我在代码中尝试相同的 URI 时,我得到一个 404 Not Found。

这是简单的代码(和 URI)(取消注释第二个以尝试 https):

try
{
  string lcUrl = "http://servicios.mensario.com/enviomasivo/apip/";
  //string lcUrl = "https://servicios.mensario.com/enviomasivo/apip/";

  // *** Establish the request
  HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl);

  // *** Set properties
  loHttp.Timeout = 10000;     // 10 secs
  loHttp.Method = "POST"; // I added this for testing, but using GET or commenting this out doesn't change anything.

  // Retrieve request info headers ******** HERE I GET THE EXCEPTION **********
  HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();

  // All this code only works when lcUrl is NOT https.
  Encoding enc = Encoding.GetEncoding(1252);  // Windows default Code Page

  StreamReader loResponseStream = new StreamReader(loWebResponse.GetResponseStream(), enc);

  string lcHtml = loResponseStream.ReadToEnd();

  loWebResponse.Close();
  loResponseStream.Close();
}
catch ( WebException ex )
{
  if ( ex.Status == WebExceptionStatus.ProtocolError )
  {
    HttpWebResponse response = ex.Response as HttpWebResponse;
    if ( response != null )
    {
      // Process response
      Console.WriteLine(ex.ToString());
    }
  }
}
Console.Read();
return;

例外是:

System.Net.WebException:远程服务器返回错误:(404)未找到。在 System.Net.HttpWebRequest.GetResponse()

注意:这里显示的http url是我必须使用的真实的,它不属于我,而是属于另一家公司。

如果响应正常,则 lcHtml 应包含以下内容:

<html>
<head>
 <title></title>
</head>

<body>
</body>
</html>

因为我在发布这个问题之前用谷歌搜索并 StackOverflowed 很多,我发现了一些想法。一种是添加“忽略证书”代码:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate( object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors )
  {
      return true; // **** Always accept
  };

这似乎没有任何改变。

其他用户说 SSL 协议类型可能是错误的......所以我尝试了这两个无济于事:

 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
 ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

有什么想法吗?

更新 我回去创建了一个简单的控制台应用程序。 唯一的代码是这样的:

WebRequest req = WebRequest.Create("http://servicios.mensario.com/enviomasivo/apip/");
WebResponse resp = req.GetResponse();

这行得通。没有错误。

但是,如果我将 URI 更改为 https:

WebRequest req = WebRequest.Create("https://servicios.mensario.com/enviomasivo/apip/");
WebResponse resp = req.GetResponse();

我收到一个错误(继续尝试)。

然而this php 代码似乎可以工作。我看到的唯一相关行代码是:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

西班牙语评论说:“有了这个我们可以忽略 SSL 证书”。

我认为这是关键。但是

System.Net.ServicePointManager.ServerCertificateValidationCallback…

…东西,似乎没有同样的效果。

提前致谢。

【问题讨论】:

  • +1 用于将术语“StackOverflowed”用作动词。

标签: .net-3.5 ssl httpwebrequest


【解决方案1】:

在使用 fiddler 和 firefox 进行一些实验后,您的 URL 似乎是问题所在。对我来说,这给出了 404:

https://servicios.mensario.com/enviomasivo/apip/

这不是:

https://servicios.mensario.com/enviomasivo/apip

注意,结尾的斜线。此外,您发布的 php 示例也没有结尾斜杠。

【讨论】:

  • 哦,天哪,你知道,我已经六次向(服务的)程序员询问 exact url。他给我发了一封带有斜线版本的电子邮件。我用非斜线尝试过一次,但我的代码是错误的,“为了安全起见”我离开了斜线,正如程序员所建议的那样。但是……改变之后,事情开始起作用了!你是我的英雄!非常感谢!!!
【解决方案2】:

您可以尝试这里描述的技巧: http://oregonstate.edu/~reeset/blog/archives/166

【讨论】:

  • 谢谢。我刚刚尝试过,但它没有改变任何东西。注意到这里描述的方法实际上很有趣,它现在被标记为过时并且回调是要走的路。这:ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
  • 嗯,太糟糕了,它什么也没做。您是否还在 Web 服务器日志文件中看到 404?
  • 我无权访问网络服务器日志文件 :( 这不是我的网络服务器。我想我一定是在这里做错了什么……不可能那么奇怪。
【解决方案3】:

这看起来不是代码问题,因为您提供的 URL 似乎无论如何都具有有效的 SSL 证书。

尝试使用“https://www.google.com”的两行 sn-p 工作,所以我建议设置一个 Web 调试代理,如 Fiddler,以便在 servicios.mensario.com/enviomasivo/ 上使用 HTTP 和 HTTPS 时比较 HTTP 请求字段阿皮普。您是否在该网站上使用反向代理?

【讨论】:

  • 嗨,maxam,我没有运行任何类型的代理。您是否尝试过针对 servicios.mensario.com/enviomasivo/apip 运行两行 sn-p ?你有404吗?谢谢。
  • 嗨,我已经安装了 Fiddler。使用“两行”vs HTTPS(我得到了例外),结果似乎还可以,但是提琴手说它是加密的。如果我解密(在提琴手中),结果似乎没问题: HTTP/1.1 404 /enviomasivo/apip/ Set-Cookie: JSESSIONID=13B63930D2DBA0520FB602D8006B6C44;路径=/enviomasivo;安全内容类型:text/html;charset=ISO-8859-1 日期:2009 年 4 月 21 日星期二 15:54:00 GMT 服务器:Apache-Coyote/1.1 内容长度:61
猜你喜欢
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多