Простой 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. Вы используете обратный прокси на этом сайте?