Différence entre `curl -I` et` curl -X HEAD`

70

Je regardais le type de serveur drôle de http://www.reddit.com avec curl -I http://www.reddit.comquand j'ai deviné que curl -X HEAD http://www.reddit.comcela ferait la même chose. Mais en fait, ce n'est pas le cas.

Je suis curieux de savoir pourquoi.

Voici ce que j'observe lors de l'exécution des deux commandes:

  • curl -I: fonctionne comme prévu, sort l'en-tête et existe.

  • curl -X HEAD: ne montre rien et semble attendre les entrées de l'utilisateur.

Cependant, si tsharkje vois la deuxième commande renifler envoie la même requête HTML et reçoit la réponse correcte, mais elle ne l’affiche pas et ne ferme pas la connexion.

curl -I

0.000000 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=47267342 TSER=0 WS=6
0.045392 213.248.111.106 -> 333.33.33.33 TCP http > 59675 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=2552532839 TSER=47267342 WS=1
0.045441 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=47267353 TSER=2552532839
0.045623 333.33.33.33 -> 213.248.111.106 HTTP HEAD / HTTP/1.1
0.091665 213.248.111.106 -> 333.33.33.33 TCP http > 59675 [ACK] Seq=1 Ack=155 Win=6432 Len=0 TSV=2552532886 TSER=47267353
0.861782 213.248.111.106 -> 333.33.33.33 HTTP HTTP/1.1 200 OK
0.861830 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [ACK] Seq=155 Ack=321 Win=6912 Len=0 TSV=47267557 TSER=2552533656
0.862127 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [FIN, ACK] Seq=155 Ack=321 Win=6912 Len=0 TSV=47267557 TSER=2552533656
0.910810 213.248.111.106 -> 333.33.33.33 TCP http > 59675 [FIN, ACK] Seq=321 Ack=156 Win=6432 Len=0 TSV=2552533705 TSER=47267557
0.910880 333.33.33.33 -> 213.248.111.106 TCP 59675 > http [ACK] Seq=156 Ack=322 Win=6912 Len=0 TSV=47267570 TSER=2552533705

curl -X HEAD

34.106389 333.33.33.33 -> 213.248.111.90 TCP 51690 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=47275868 TSER=0 WS=6
34.149507 213.248.111.90 -> 333.33.33.33 TCP http > 51690 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=3920268348 TSER=47275868 WS=1
34.149560 333.33.33.33 -> 213.248.111.90 TCP 51690 > http [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=47275879 TSER=3920268348
34.149646 333.33.33.33 -> 213.248.111.90 HTTP HEAD / HTTP/1.1
34.191484 213.248.111.90 -> 333.33.33.33 TCP http > 51690 [ACK] Seq=1 Ack=155 Win=6432 Len=0 TSV=3920268390 TSER=47275879
34.192657 213.248.111.90 -> 333.33.33.33 TCP [TCP Dup ACK 15#1] http > 51690 [ACK] Seq=1 Ack=155 Win=6432 Len=0 TSV=3920268390 TSER=47275879
34.823399 213.248.111.90 -> 333.33.33.33 HTTP HTTP/1.1 200 OK
34.823453 333.33.33.33 -> 213.248.111.90 TCP 51690 > http [ACK] Seq=155 Ack=321 Win=6912 Len=0 TSV=47276048 TSER=3920269022

Une idée sur pourquoi cette différence de comportement?

chmeee
la source

Réponses:

66

Il semble que la différence concerne l'en- Content-Lengthtête et son traitement par les deux commandes.

Mais avant d'entrer dans cela, curl -X HEADne donne aucune sortie car, par défaut, curln'imprime pas les en-têtes si le commutateur -in'est pas fourni (pas nécessaire sur -I).

Dans tous les cas, curl -Iest la bonne façon de récupérer les en-têtes. Il suffit de demander l'en-tête et de fermer la connexion.

D'autre part curl -X HEAD -iattendra la transmission du nombre d'octets indiqué par Content-Length. Dans le cas où non Content-Lengthn'est pas spécifié, je suppose qu'il attendra certaines données ou cet en-tête particulier.

Quelques exemples montrant ce comportement:

$ curl -X HEAD -i http://www.elpais.es
HTTP/1.1 301 Moved Permanently
Server: AkamaiGHost
Content-Length: 0
Location: http://www.elpais.com/
Date: Wed, 12 May 2010 06:35:57 GMT
Connection: keep-alive

Parce que Content-Lengthvaut 0, dans ce cas les deux commandes se comportent de la même manière. Et la connexion est fermée après.

$ curl -X HEAD -i http://slashdot.org
HTTP/1.1 200 OK
Server: Apache/1.3.41 (Unix) mod_perl/1.31-rc4
SLASH_LOG_DATA: shtml
X-Powered-By: Slash 2.005001296
X-Bender: Since I love you all so much, I'd like to give everyone hugs.
X-XRDS-Location: http://slashdot.org/slashdot.xrds
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=iso-8859-1
Content-Length: 115224
Date: Wed, 12 May 2010 06:37:20 GMT
X-Varnish: 1649060825 1649060810
Age: 1
Connection: keep-alive

curl: (18) transfer closed with 115224 bytes remaining to read

Dans ce cas, il semble y avoir un délai d'attente (probablement de Varnish), ce curlqui proteste donc que la connexion a été fermée avant d'avoir reçu le Content-Lengthnombre d'octets.

Au fait, regardez les en-têtes drôles X-Bender (montrés dans l'exemple) et X-Fry (essayez par vous-même) :).

chmeee
la source
2
Au cas où quelqu'un d'autre viendrait à la recherche de ceci: l'option de configuration dans la bibliothèque curl de PHP est CURLOPT_NOBODY.
Matthew
12

Je pense que c'est un bug dans curl. Si je spécifie une méthode avec -X, curl devrait gérer la réponse conformément à la RFC. Malheureusement, le responsable de curl n'est pas d'accord. Quelqu'un a déposé un bogue et même soumis un correctif:

http://sourceforge.net/tracker/?func=detail&atid=100976&aid=1810273&group_id=976

mais le responsable de la boucle l'a rejeté. Apparemment, une option "-X HEAD" cassée fonctionne "comme prévu".

--Jamshid

jamshid
la source
4
Pour être juste, je peux suivre la logique de la réponse au ticket: --headnous fournit une implémentation valide d'une requête HEAD et -X <method>remplace simplement la méthode HTTP dans la requête.
Hank
3
oui, c'était ce dont j'avais besoin. J'ai un serveur buggy qui sert du contenu quand une demande HEAD est donnée. -X HEADétait la seule façon que je pouvais le tester en essayant d'obtenir le serveur d'adhérer à la RFC
Hashbrown
5

De la docs :

-X, --request

(HTTP) Spécifie une méthode de requête personnalisée à utiliser lors de la communication avec le serveur HTTP. La méthode de requête spécifiée sera utilisée à la place de la méthode utilisée par ailleurs (GET par défaut). Lisez la spécification HTTP 1.1 pour plus de détails et d’explications. Les requêtes HTTP supplémentaires communes incluent PUT et DELETE, mais des technologies connexes telles que WebDAV offrent PROPFIND, COPY, MOVE et plus encore.

Normalement, vous n'avez pas besoin de cette option. Toutes sortes de requêtes GET, HEAD, POST et PUT sont plutôt appelées à l'aide d'options de ligne de commande dédiées.

Cette option ne modifie que le mot utilisé dans la requête HTTP, elle ne modifie pas le comportement de curl . Donc, par exemple, si vous voulez faire une demande HEAD appropriée, utiliser -X HEAD ne suffira pas. Vous devez utiliser l'option -I, --head.

En d' autres termes, -Xest des méthodes autres que GET, HEAD, POSTet PUT. Pour HEADutilisation -I.

x-yuri
la source
0

Je rencontre le même problème lorsque j'écris du code cpp sous curl 7.34,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

y restera longtemps, semble attendre le transfert du corps jusqu’à l’expiration du délai. après avoir ajouté une nouvelle ligne, ce problème est résolu.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

de la doc

faire la demande de téléchargement sans avoir le corps

cette ligne obligerait curl à ne pas attendre.

dasons
la source