Простой HttpWebRequest через SSL (https) дает 404 не найден в C # - PullRequest
5 голосов
/ 20 апреля 2009

Я хочу сделать 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 ()

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

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

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

<body>
</body>
</html>

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

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;

Есть идеи?

UPDATE Я вернулся и создал простое консольное приложение. Код only :

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 ]

10 голосов
/ 21 апреля 2009

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

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

а это не так:

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

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

0 голосов
/ 21 апреля 2009

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

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

0 голосов
/ 20 апреля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...