Не удается подключиться к сайту HTTPS с помощью cURL. Возвращает 0 длина, а не содержание. Что я могу сделать?
у меня есть сайт, который подключается с помощью cURL (последняя версия) к защищенному шлюзу для оплаты.
проблема в том, что cURL всегда возвращает содержимое длины 0. Я получаю только заголовки. И только когда я установил cURL для возврата заголовков. У меня есть следующие флаги на месте.
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $gatewayURI);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_POST, 1);
заголовок возвращено
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 01:08:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 0
Content-Type: text/html
Set-Cookie: ASPSESSIONIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/
Cache-control: private
Я также пробовал завивать разные сайты, и они возвращают контент нормально. Я думаю, что проблема может иметь какое-то отношение к https соединение.
Я говорил с компанией, и они бесполезны.
кто-нибудь еще испытал эту ошибку и знает работу вокруг? Я должен канаву завиток и попытаться использовать fsockopen() ?
спасибо. :)
12 ответов:
вы также должны проверить сообщения об ошибках в curl_error(). Возможно, вам придется сделать это один раз после каждой функции curl_*.
у меня была такая же проблема сегодня. Curl поставляется с устаревшим файлом для проверки подлинности сертификатов HTTPS.
получить новый от:
http://curl.haxx.se/ca/cacert.pem
сохранить его в какой-то dir на вашем сайте
и добавить
curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");на каждый запрос :-)
игнорировать любые тупые комментарии об отключении CURLOPT_VERIFYPEER и CURLOPT_VERIFYHOST!! Это оставляет ваш код уязвимым для человека в средние атаки!
декабрь 2016 редактировать:
решите это правильно, используя метод Jasen, упомянутый ниже.
добавить
curl.cainfo=/etc/ssl/certs/ca-certificates.crtдля вас php.iniоктябрь 2017 редактировать:
теперь есть пакет composer, который помогает вам управлять сертификатами ca, так что вы не уязвимы, если ваш cacert.pem устаревает из-за отзыва сертификаты.
https://github.com/paragonie/certainty ->
composer require paragonie/certainty:dev-master
Примечание: это строго не производственного использования. Если вы хотите быстро отлаживать, это может быть полезно. В противном случае, пожалуйста, используйте ответ @SchizoDuckie выше.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);просто добавить их. Это работает.
просто была очень похожая проблема и решил ее, добавив
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);по-видимому, сайт, который я получаю, перенаправляет в другое место, а php-curl по умолчанию не следует за перенаправлениями.
У меня была ситуация, когда это помогло: (PHP 5.4.16 на Windows)
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
всякий раз, когда я тестирую что-то с PHP/Curl, я сначала пробую его из командной строки, выясняю, что работает, а затем переношу свои параметры на PHP.
Я
file_get_contentsС помощьюstream_create_contextи он отлично работает:$postdataStr = http_build_query($postdataArr); $context_options = array ( 'http' => array ( <blink> // this will allways be http!!!</blink> 'method' => 'POST', 'header'=> "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($postdataArr) . "\r\n" . "Cookie: " . $cookies."\r\n" 'content' => $postdataStr ) ); $context = stream_context_create($context_options); $HTTPSReq = file_get_contents('https://www.example.com/', false, $context);
может возникнуть проблема в вашей веб-хостинговой компании, где вы тестируете безопасную связь для шлюза, что они могут не позволить вам это сделать.
также может быть имя пользователя, пароль, который должен быть предоставлен перед подключением к удаленному хосту.
или ваш IP-адрес может потребоваться в списке утвержденных IP-адресов для удаленного сервера для инициализации связи.
Я обнаружил эту ошибку в недавнем проекте приложения. Я писал для запуска из командной строки или окна браузера, поэтому я использовал обнаружение сервера, чтобы получить относительный URL-адрес документа, который я просил. Проблема была, сайт https, и каждый раз, когда я пытался получить доступ адресу http://(то же самое server), cURL услужливо изменил его на https.
Это отлично работает из браузера, но из командной строки Я бы тогда получил ошибку SSL даже с обоими проверками задать значение false. Что я должен был сделать,
1) Проверьте $_SERVER ['HTTP_HOST']. Если присутствует, используйте ($_SERVER ['HTTPS']? "с HTTPS://" : "в HTTP://").$_SERVER ['HTTP_HOST']
2) Проверьте $_SERVER ['COMPUTERNAME'], и если он соответствует производственному серверу, укажите URL-адрес https. ( " https: / / (имя_сервера)")
3) Если ни одно из условий не прошло, это означает, что я запускаю командную строку на другом сервере и использую "http://localhost".
теперь, это сработало, но это хак. Кроме того, я никогда не понимал, почему на одном сервере (https) cURL изменил мой URL, а на другом (также https) он оставил мой URL в покое.
странно.
лучший способ использовать https и избежать проблем с безопасностью-использовать Firefox (или другой инструмент) и загрузить сертификат на свой сервер. эта страница мне очень помогла, и это были шаги, которые работали для меня:
1) Откройте в Firefox URL, который вы собираетесь использовать с CURL
2) в адресной строке нажмите на кнопку
padlock>more information(версии FF могут иметь разные меню, просто найдите его). Нажмите кнопку посмотреть сертификат>Detailsтабуляция.3) выделите" правильный " сертификат в
Certificate hierarchy. В моем случае это был второй из трех, называемый " cPanel, Inc. центр сертификации." Я только что обнаружил правильный метод" проб и ошибок".4) Нажмите кнопку экспорт. В моем случае тот, кто работал, был типом файла "PEM с цепями" (снова методом проб и ошибок).
5) тогда в ваш PHP-скрипт:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_CAINFO, [PATH_TO_CRT_FILE]);кроме того, я бы сказал, что мы должны платить обратите внимание на то, что эти шаги, вероятно, необходимо будет переделывать один раз в год или всякий раз, когда сертификат URL заменяется или обновляется.
вы используете метод POST, но предоставляете ли вы массив данных? Е. Г.
curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
Comments