PHP / Curl: la requête HEAD prend beaucoup de temps sur certains sites

j'ai du code simple qui fait une demande de tête pour une URL et ensuite imprime les en-têtes de réponse. J'ai remarqué que sur certains sites, cela peut prendre un certain temps pour terminer.

par exemple, demander http://www.arstechnica.com prend environ deux minutes. J'ai essayé la même requête en utilisant un autre site web qui fait la même tâche de base, et il revient immédiatement. Donc il doit y avoir quelque chose que j'ai mal réglé qui cause ce retard.

voici le le code que j'ai:

$ch = curl_init();
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

$content = curl_exec ($ch);
curl_close ($ch);

voici un lien vers le site web qui fait la même fonction: http://www.seoconsultants.com/tools/headers.asp

le code ci-dessus, au moins sur mon serveur, prend deux minutes pour récupérer www.arstechnica.com, mais le service au lien ci-dessus le renvoie immédiatement.

Qu'est-ce que je rate?

23
demandé sur bignose 2009-04-21 01:29:50

5 réponses

essayez de le simplifier un peu:

print htmlentities(file_get_contents("http://www.arstechnica.com"));

les sorties ci-dessus instantanément sur mon serveur web. Si ce n'est pas sur la vôtre, il y a de fortes chances que votre hébergeur ait mis en place une sorte de réglage pour étouffer ce genre de requêtes.

MODIFIER :

comme ce qui précède se produit instantanément pour vous, essayez de définir cette boucle sur votre code d'origine:

curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);

en utilisant l'outil que vous avez posté, j'ai remarqué que http://www.arstechnica.com a un en-tête 301 envoyé pour toute requête envoyée. Il est possible que cURL obtienne ceci et ne suive pas le nouvel emplacement qui lui est spécifié, provoquant ainsi la suspension de votre script.

DEUXIÈME ÉDITION :

curieusement, essayer le même code que vous avez ci-dessus rendait mon webserver accroché aussi. J'ai remplacé ce code:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

avec ceci:

curl_setopt($ch, CURLOPT_NOBODY, true);

qui est le chemin le manuel vous recommande de faire une demande de tête. Il fait le travail instantanément.

43
répondu Paolo Bergantino 2009-04-20 21:49:23

vous devez vous rappeler que HEAD n'est qu'une suggestion pour le serveur web. Pour que HEAD fasse la bonne chose, il faut souvent un effort explicite de la part des administrateurs. Si vous dirigez un fichier statique Apache (ou quel que soit votre serveur web) fera souvent un pas dans la bonne direction. Si vous dirigez une page dynamique, la valeur par défaut pour la plupart des configurations est d'exécuter le chemin GET, de collecter tous les résultats, et de simplement renvoyer les en-têtes sans le contenu. Si cette demande est de niveau 3 (ou plus) setup, cet appel pourrait potentiellement être très coûteux et inutile pour un contexte HEAD. Par exemple, sur un servlet Java, par défaut doHead() appelle simplement doGet(). Pour faire quelque chose d'un peu plus intelligent pour l'application, le développeur devra implémenter explicitement doHead() (et le plus souvent, ils ne le seront pas).

j'ai rencontré une application d'une société fortune 100 qui est utilisé pour le téléchargement de plusieurs centaines de mégaoctets de l'information de prix. Nous vérifions les mises à jour ces données en exécutant des requêtes de HEAD assez régulièrement jusqu'à ce que la date modifiée change. Il s'avère que cette requête ferait en fait des appels en arrière-plan pour générer cette liste à chaque fois que nous avons fait la demande qui impliquait des gigaoctets de données sur leur arrière-plan et xfer il entre plusieurs serveurs internes. Ils n'étaient pas très contents de nous, mais une fois que nous leur avons expliqué le cas d'utilisation, ils ont rapidement trouvé une solution de rechange. S'ils avaient implémenté HEAD, plutôt que de compter sur leur serveur web faux, il n'aurait pas été un problème.

6
répondu Trey 2013-12-29 15:00:35

si ma mémoire ne me laisse pas tomber en faisant une requête en tête dans CURL change la version du protocole HTTP en 1.0 (ce qui est lent et probablement la partie coupable ici) essayez de changer cela en:

$ch = curl_init();
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); // ADD THIS

$content = curl_exec ($ch);
curl_close ($ch);
3
répondu Alix Axel 2009-04-20 21:41:42

j'ai utilisé la fonction ci-dessous pour trouver L'URL redirigée.

$head = get_headers($url, 1);

le deuxième argument le fait retourner un tableau avec des clés. Pour par exemple le ci-dessous donnera la valeur Location .

$head["Location"]

http://php.net/manual/en/function.get-headers.php

3
répondu San 2011-07-23 12:47:16

:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

Je n'essayais pas d'avoir des en-têtes.

J'essayais juste de faire le chargement de page de certaines données ne pas prendre 2 minutes similaire à décrit ci-dessus.

Ces petites options magiques l'ont fait tomber à 2 secondes.

0
répondu Brad 2012-11-28 10:40:29