php - ejemplos - No se puede conectar al sitio HTTPS usando cURL. Devuelve 0 contenido de longitud en su lugar. ¿Que puedo hacer?
enviar datos post curl php (12)
Tengo un sitio que se conecta usando cURL (última versión) a una puerta de enlace segura para el pago.
El problema es que cURL siempre devuelve 0 contenido de longitud. Obtengo encabezados solo Y solo cuando configuro cURL para devolver encabezados. Tengo los siguientes indicadores en su lugar.
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);
El encabezado devuelto es
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
También he intentado cursar en diferentes sitios y devuelven bien el contenido. Creo que el problema podría tener algo que ver con la conexión https.
He hablado con la compañía y no son útiles.
¿Alguien más ha experimentado este error y conoce un trabajo alternativo? ¿Debo abandonar cURL y probar y usar fsockopen()
?
Gracias. :)
A veces debe actualizar sus certificados Curl a la última versión para no tener errores con https.
Acabo de tener un problema muy similar y lo resolví agregando
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
Aparentemente, el sitio que estoy buscando redirige a otra ubicación y php-curl no sigue los redireccionamientos de forma predeterminada.
Cada vez que pruebo algo con PHP / Curl, primero lo intento desde la línea de comando, entiendo lo que funciona y luego transfiero mis opciones a PHP.
Descubrí este error en un proyecto de aplicación reciente. Estaba escribiendo para ejecutar desde la línea de comandos o la ventana del navegador, así que estaba usando la detección del servidor para obtener la URL relativa del documento que estaba solicitando. El problema era que el sitio es https, y cada vez que intenté acceder a http://(same servidor), cURL lo cambió a https.
Esto funciona bien desde el navegador, pero desde la línea de comandos, obtendría un error de SSL incluso con ambos verificaciones configuradas en falso. Lo que tenía que hacer era,
1) Marque $ _SERVER [''HTTP_HOST'']. Si está presente, use ($ _SERVER [''HTTPS'']? "Https: //": "http: //"). $ _ SERVER [''HTTP_HOST'']
2) Marque $ _SERVER [''COMPUTERNAME''], y si coincide con el servidor de producción, proporcione la URL https. (" https://(servername) ")
3) Si ninguna de las dos condiciones pasó, significa que estoy ejecutando la línea de comandos en un servidor diferente, y uso " http: // localhost ".
Ahora, esto funcionó, pero es un truco. Además, nunca entendí por qué en un servidor (https) cURL cambió mi URL, mientras que en el otro (también https) dejó mi URL sola.
Extraño.
Está utilizando el método POST, pero ¿está proporcionando una matriz de datos? P.ej
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
La mejor forma de usar https y evitar problemas de seguridad es usar Firefox (u otra herramienta) y descargar el certificado a su servidor. Esta página web me ayudó mucho , y estos fueron los pasos que funcionaron para mí:
1) Abre en Firefox la URL que usarás con CURL
2) En la barra de direcciones, haga clic en el padlock
> more information
(las versiones de FF pueden tener menús diferentes, simplemente búsquelos). Haga clic en el botón Ver certificado > pestaña Details
.
3) Resalte el certificado "correcto" en la Certificate hierarchy
. En mi caso, fue el segundo de tres, llamado "Autoridad de Certificación de cPanel, Inc.". Acabo de descubrir el correcto por el método de "prueba y error".
4) Haz clic en el botón Exportar . En mi caso, el que trabajó fue el tipo de archivo "PEM con cadenas" (de nuevo por el método de prueba y error).
5) Luego en tu script PHP agrega:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, [PATH_TO_CRT_FILE]);
Además, diría que debemos prestar atención al hecho de que estos pasos probablemente deban rehacerse una vez al año o siempre que el certificado URL sea reemplazado o renovado.
Nota: Esto no es estrictamente uso de producción. Si desea depurar rápidamente, esto puede ser útil. De lo contrario, utilice la respuesta de @ SchizoDuckie anterior.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
Solo agrégalos. Funciona.
También debería intentar verificar los mensajes de error en curl_error (). Es posible que deba hacer esto una vez después de cada función curl_ *.
Tuve el mismo problema hoy. Curl viene con un archivo desactualizado para autenticar los certificados HTTPS.
obtener el nuevo de:
http://curl.haxx.se/ca/cacert.pem
guárdelo en algún directorio en su sitio
y añadir
curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
Para cada solicitud :-)
¡IGNORE cualquier comentario tonto sobre deshabilitar CURLOPT_VERIFYPEER y CURLOPT_VERIFYHOST !! ¡Eso hace que tu código sea vulnerable al hombre en los ataques medios!
Edición de diciembre de 2016:
Resuelva esto correctamente utilizando el método de Jasen mencionado a continuación.
agregue curl.cainfo=/etc/ssl/certs/ca-certificates.crt
a usted php.ini
Edición de octubre de 2017:
Ahora hay un paquete de compositor que lo ayuda a administrar los certificados ca, para que no sea vulnerable si su cacert.pem se vuelve obsoleto debido a la revocación de certificados.
https://github.com/paragonie/certainty -> composer require paragonie/certainty:dev-master
Tuve una situación en la que esto ayudó: (PHP 5.4.16 en Windows)
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
puede haber un problema en su empresa de alojamiento web desde donde está probando la comunicación segura para la puerta de enlace, que pueden no permitirle hacer eso.
también podría haber un nombre de usuario, una contraseña que debe proporcionarse antes de conectarse al host remoto.
o su IP podría necesitar estar en la lista de IP aprobada para que el servidor remoto inicie la comunicación.
stream_create_context
file_get_contents
usando stream_create_context
y funciona bien:
$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);