Простой HttpWebRequest через SSL (https) дает 404 не найден в C#

Я хочу сделать POST для написанного на PHP веб-службы, которая находится на безопасном соединении. Следующий код является просто тестовым консольным приложением, которое я написал после нескольких часов проб и ошибок. По сути, я обнаружил несколько разных методов использования HttpWebRequest, но все они - одно и то же.

Тестирование моего URI с помощью 'http' в веб-браузере должно вернуть пустой HTML (с пустым телом). Это работает нормально в браузере и в моем коде.

Я попробовал http://www.google.com/ и получил Google... (как и ожидалось). Проблема возникает, когда я изменяю URI с http на https. Тестирование моего URI с помощью "https" в веб-браузере возвращает тот же пустой 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) Not Found. в System.Net.HttpWebRequest.GetResponse()

примечание: URL-адрес http, показанный здесь, является реальным, который я должен использовать, он принадлежит не мне, а другой компании.

Если ответ был в порядке, вот что должен содержать lcHtml:

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

<body>
</body>
</html>

Так как я много гуглил и Stackrued до публикации этого вопроса, я нашел несколько идей. Одним из них является добавление кода "игнорировать сертификаты":

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();

Я получаю ошибку (иди и попробуй).

Однако этот PHP-код, кажется, работает. Единственная соответствующая строка кода, которую я вижу по-другому:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

Комментарий на испанском говорит: "При этом мы можем игнорировать сертификат SSL".

Я думаю, что это ключ. Но

System.Net.ServicePointManager.ServerCertificateValidationCallback…

… Вещи, похоже, не имеют такого же эффекта.

Заранее спасибо.

3 ответа

Решение

После некоторых экспериментов с использованием fiddler и firefox кажется, что ваш URL - это проблема. Для меня это дает 404:

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

и это не так:

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

Обратите внимание, окончание косой черты. Кроме того, пример php, который вы разместили, также не имеет конечной косой черты.

Вы можете попробовать трюк, описанный здесь: http://oregonstate.edu/~reeset/blog/archives/166

Это не похоже на проблему с кодом, так как URL, который вы дали, похоже, в любом случае имеет действительный сертификат SSL.

Работа вашего двухстрочного фрагмента с " https://www.google.com/" работает, поэтому я предлагаю настроить прокси-сервер для отладки, такой как Fiddler, для сравнения полей HTTP-запросов при использовании HTTP и HTTPS на servicios.mensario.com/enviomasivo/apip. Вы используете обратный прокси на этом сайте?

Другие вопросы по тегам