Не удается подключиться к сайту 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

Я также попробовал cURL'ing на разных сайтах, и они вернули контент в порядке. Я думаю, что проблема может иметь какое-то отношение к соединению https.

Я разговаривал с компанией, и они бесполезны.

Кто-нибудь еще испытал эту ошибку и знает, что нужно делать? Должен ли я канавать cURL и пытаться использовать fsockopen()?

Спасибо.:)

Ответ 1

Вы также должны попробовать проверить сообщения об ошибках в curl_error(). Возможно, вам понадобится сделать это один раз после каждой функции curl_ *.

http://www.php.net/curl_error

Ответ 2

У меня была такая же проблема сегодня. Curl поставляется с устаревшим файлом для аутентификации сертификатов HTTPS.

получить новый:

http://curl.haxx.se/ca/cacert.pem

сохранить его в каком-либо каталоге на вашем сайте

и добавьте

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 изменить:

Теперь есть композитный пакет, который помогает вам управлять сертификатами ca, чтобы вы не были уязвимы, если ваш cacert.pem устарел из-за отзыва сертификатов.

https://github.com/paragonie/certaintycomposer require paragonie/certainty:dev-master

Ответ 3

Примечание. Это строго не производственное использование. Если вы хотите быстро отладить, это может быть полезно. В противном случае, пожалуйста, используйте ответ @SchizoDuckie выше.

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);     
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 

Просто добавьте их. Оно работает.

Ответ 4

У меня была очень похожая проблема и она была решена, добавив

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

По-видимому, сайт, на который я перенаправляю перенаправления в другое место и php-curl, по умолчанию не выполняет перенаправления.

Ответ 5

У меня была ситуация, когда это помогло: (PHP 5.4.16 в Windows)

curl_setopt($ch, CURLOPT_SSLVERSION, 3);

Ответ 6

Всякий раз, когда я тестирую что-то с PHP/Curl, я сначала пытаюсь использовать его из командной строки, выяснять, что работает, а затем переносить мои параметры на PHP.

Ответ 7

Иногда вам нужно обновить свои сертификаты Curl до последней версии, чтобы не иметь ошибок с https.

Ответ 8

Я использовал 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);

Ответ 9

может возникнуть проблема в вашей веб-хостинговой компании, где вы тестируете безопасную связь для шлюза, что они могут не позволить вам это сделать.

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

или ваш IP, возможно, должен быть в списке одобренных IP-адресов для удаленного сервера для обмена сообщениями.

Ответ 10

Я обнаружил эту ошибку в недавнем проекте приложения. Я писал для запуска из командной строки или окна браузера, поэтому я использовал обнаружение сервера, чтобы получить относительный URL-адрес документа, который я просил. Проблема была в том, что на сайте есть https, и каждый раз, когда я пытался получить доступ к http://(same серверу, cURL помог изменить его на https.

Это отлично работает в браузере, но из командной строки я получаю SSL-ошибку, даже если оба параметра установлены в false. Я должен был сделать,

1) Проверьте $_SERVER ['HTTP_HOST']. Если присутствует, используйте ($ _SERVER ['HTTPS']? "Https://": "http://" ). $_ SERVER ['HTTP_HOST']

2) Проверьте $_SERVER ['COMPUTERNAME'], и если он соответствует производственному серверу, укажите URL-адрес https. ( " https://(servername)" )

3) Если ни одно условие не прошло, это означает, что я запускаю командную строку на другом сервере и использую " http://localhost".

Теперь это сработало, но это взломать. Кроме того, я никогда не выяснял, почему на одном сервере (https) cURL изменил мой URL, а на другом (также https) он оставил мой URL один.

Weird.

Ответ 11

Лучший способ использовать https и избежать проблем безопасности - использовать Firefox (или другой инструмент) и загрузить сертификат на ваш сервер. Эта веб-страница мне очень помогла, и это были шаги, которые работали для меня:

1) Откройте в Firefox URL, который вы собираетесь использовать с CURL

2) В адресной строке нажмите padlock > more information (версии FF могут иметь разные меню, просто найдите их). Перейдите на вкладку View certificate > Details.

3) Выделите "правильный" сертификат в Certificate hierarchy. В моем случае это был второй из трех, называемый "сертификационный центр cPanel, Inc.". Я только что нашел правильный метод "проб и ошибок".

4) Нажмите кнопку Export. В моем случае тот, кто работал, был типом файла "PEM с цепями" (опять же методом проб и ошибок).

5) Затем в вашем PHP script добавьте:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);    
curl_setopt($ch, CURLOPT_CAINFO, [PATH_TO_CRT_FILE]);

Кроме того, я бы сказал, что мы должны обратить внимание на тот факт, что эти шаги, вероятно, нужно будет переделать один раз в год или при замене или обновлении сертификата URL.

Ответ 12

Вы используете метод POST, но предоставляете ли вы массив данных? Например.

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);