2015-02-06 11 views
10

Quando tento di utilizzare i metodi cURL di PHP per SOME URL, si verifica il timeout. Quando uso la riga di comando per lo stesso URL, funziona perfettamente.I metodi PHP cURL scadono su alcuni URL, ma la riga di comando funziona sempre

Sto usando AWS e ho una scatola t2.medium con le librerie di apache php-55 di yum.

Ecco il mio codice PHP:

function curl($url) { 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_AUTOREFERER, true); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($ch, CURLOPT_VERBOSE, true); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_MAXREDIRS, 2); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Accept-Language: en-us' 
)); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 
curl_setopt($ch, CURLOPT_TIMEOUT, 10); 
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 
$fh = fopen('/home/ec2-user/curllog', 'w'); 
curl_setopt($ch, CURLOPT_STDERR, $fh); 
$a = curl_exec($ch); 
curl_close($ch); 
fclose($fh); 
$headers = explode("\n",$a); 
var_dump($headers); 
var_dump($a); 
exit; 

     return $result; 
} 

ecco chiamata che funziona bene:

curl('http://www.google.com'); 

E questa restituisce i dati per la home page di Google.

Tuttavia, provo un altro URL:

curl('http://www.trulia.com/profile/agent-1391347/overview'); 

e ottengo questo nel curllog:

[[email protected] Node]$ cat ../curllog 
* Hostname was NOT found in DNS cache 
* Trying 23.0.160.99... 
* Connected to www.trulia.com (23.0.160.99) port 80 (#0) 
> GET /profile/agent-1391347/overview HTTP/1.1 
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36 
Host: www.trulia.com 
Accept: */* 
Accept-Language: en-us 

* Operation timed out after 10002 milliseconds with 0 bytes received 
* Closing connection 0 

Se corro questo dalla riga di comando:

curl -s www.trulia.com/profile/agent-1391347/overview 

E ' Ritorna IMMEDIATAMENTE (entro 1 secondo) con uscita NO. Questo è previsto. Tuttavia quando eseguo questo:

curl -sL www.trulia.com/profile/agent-1391347/overview 

Restituisce la pagina correttamente, proprio come vorrei.

Quindi, cosa c'è di sbagliato nel mio ricciolo?

PHP 5.5.20

Qui è il bit cURL dal mio phpinfo():

curl 

cURL support => enabled 
cURL Information => 7.38.0 
Age => 3 
Features 
AsynchDNS => Yes 
CharConv => No 
Debug => No 
GSS-Negotiate => No 
IDN => Yes 
IPv6 => Yes 
krb4 => No 
Largefile => Yes 
libz => Yes 
NTLM => Yes 
NTLMWB => Yes 
SPNEGO => Yes 
SSL => Yes 
SSPI => No 
TLS-SRP => No 
Protocols => dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, ldaps, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp 
Host => x86_64-redhat-linux-gnu 
SSL Version => NSS/3.16.2 Basic ECC 
ZLib Version => 1.2.7 
libSSH Version => libssh2/1.4.2 
+0

Si sta eseguendo la riga di comando dalla stessa macchina del codice php? se no, potresti voler confrontare la versione arricciata. –

+0

qual è l'output di terminale 'curl --version'? e qual è l'output di ' hanshenrik

+0

snippet IRC: https://i.imgur.com/bOwxcS3.png - ... e il tizio che ha risposto, è l'autore di (lib-) curl – hanshenrik

risposta

4

Provare ad aumentare i valori di timeout nelle seguenti righe:

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 
curl_setopt($ch, CURLOPT_TIMEOUT, 10); 

Quelli sono abbastanza valori di timeout brevi: il CURLOPT_TIMEOUT limita in modo specifico l'intero tempo di esecuzione, prova a fornire valori più grandi:

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); 
curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
+0

Viene eseguito istantaneamente dalla riga di comando - meno di 1 secondo. Non dovrei avere bisogno di 10 secondi in PHP per fare ciò che richiede 1 sulla CLI. L'ho provato con valori doppi però e ancora a tempo. Ho eseguito una diversa istanza EC2 e ha funzionato perfettamente. –

3

avete 2 VARIABILI

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 
curl_setopt($ch, CURLOPT_TIMEOUT, 10); 

Il primo, CURLOPT_CONNECTTIMEOUT è intervallo di tempo massimo consentito per effettuare la connessione alla server`

È possibile disabilitarlo impostando a 0.

Questo è

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); 

Ma non è un buon metodo se si è in un ambiente di produzione perché non sarà mai timeout.

Ora CURLOPT_TIMEOUT

Da PHP Documentation

Il numero massimo di secondi per consentire funzioni CURL di eseguire.

Set a qualche valore più alto

curl_setopt($ch, CURLOPT_TIMEOUT, 20); // 20 Seconds. 
+0

Il mio problema particolare, e il motivo per cui ho messo il bounty su di esso, non viene risposto dai timeout. Osserva la prima affermazione nel post - il problema è che si verifica un timeout solo * a volte * quando viene chiamato da PHP, ma * mai * quando viene chiamato dalla riga di comando - anche quando viene utilizzato nello stesso URL entrambe le volte. – alzee

+0

Misuro dal mio pc, ci vogliono più di 10 secondi con il comando di arricciatura, il più delle volte usato per il trasferimento dei dati. Quindi significa che abbiamo attivato il limite di velocità di cdn (da cloudfront.net per questo esempio). Dovresti capire come bypassare il limite di velocità, o semplicemente impostare un CURLOPT_TIMEOUT più grande – tangxinfa

7

Ho controllato la vostra funzione curl() sembra che vada bene. Non c'è bisogno di cambiare nulla nella funzione. Che cosa si dovrebbe avere bisogno di fare è solo passare l'URL, è come parametro bisogno di cambiare HTTPS a HTTP

curl('http://www.trulia.com/profile/agent-1391347/overview');

Motivo:

È già detto curl di non verificare l'SSL

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Fatemi sapere se avete bisogno di alcuna spiegazione.

+0

Ah, niente come disattivare la sicurezza! :-) – user499211

3

L'output dettagliato mostra una chiara problema timeout:

  • funzionamento scaduta dopo 10002 millisecondi con 0 byte ricevuti

Questo segnala un problema con la configurazione di rete. Questi sono più difficili da individuare, questo può essere da soli (ad esempio nel contesto del server web o dell'eseguibile PHP) o dall'altra parte. Entrambe le posizioni sono possibili fino a un certo limite, tuttavia il server accetta entrambe le richieste anche se hanno intestazioni di richieste diverse, quindi è più probabile che si tratti di un contesto di esecuzione che è anche il modo in cui generalmente lo descrivi.

Verificare se ci sono restrizioni sulla sicurezza e altri livelli di rete relativi all'esecuzione di tali richieste tramite PHP. Per esempio. prova un'immagine del server diversa se non ti piace l'amministrazione del sistema e la risoluzione dei problemi. Da ciò che è condiviso nella tua domanda, è difficile dire che cosa causi esattamente il tuo timeout.

Problemi correlati