Diferença entre `curl -I` e` curl -X HEAD`

70

Eu estava assistindo o tipo de servidor engraçado de http://www.reddit.com com curl -I http://www.reddit.comquando eu imaginado que curl -X HEAD http://www.reddit.comfaria o mesmo. Mas, de fato, não.

Estou curioso sobre o porquê.

Isto é o que eu observo executando os dois comandos:

  • curl -I: funciona como esperado, gera o cabeçalho e existe.

  • curl -X HEAD: não mostra nada e parece aguardar a entrada do usuário.

Mas, farejando com tshark, vejo o segundo comando, na verdade, envia a mesma consulta HTML e recebe a resposta correta, mas não mostra e não fecha a conexão.

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

Alguma idéia de por que essa diferença de comportamento?

chmeee
fonte

Respostas:

66

Parece que a diferença tem a ver com o Content-Lengthcabeçalho e como ele é tratado pelos dois comandos.

Mas antes de entrar nisso, curl -X HEADnão dá saída porque, por padrão, curlnão imprime cabeçalhos se a opção -inão for fornecida ( -Iembora não seja necessário ).

De qualquer forma, curl -Ié a maneira correta de buscar os cabeçalhos. É só pedir o cabeçalho e fechar a conexão.

Por outro lado curl -X HEAD -i, aguardará a transmissão do número de bytes indicado por Content-Length. Caso não Content-Lengthseja especificado, acho que ele aguardará alguns dados ou esse cabeçalho específico.

Alguns exemplos que mostram esse comportamento:

$ 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

Como Content-Lengthé 0, nesse caso, os dois comandos se comportam da mesma forma. E a conexão é fechada depois.

$ 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

Nesse caso, parece haver um tempo limite (provavelmente por verniz), portanto, curlprotesta que a conexão foi fechada antes de receber o Content-Lengthnúmero de bytes.

A propósito, observe os engraçados cabeçalhos do X-Bender (mostrados no exemplo) e do X-Fry (tente você mesmo) :).

chmeee
fonte
2
Caso mais alguém venha procurar por isso: a opção para definir na biblioteca curl do PHP é CURLOPT_NOBODY.
Matthew
12

Eu acho que isso é um bug no curl. Se eu especificar um método com -X, o curl deverá manipular a resposta de acordo com o RFC. Infelizmente, o mantenedor de curl não concorda. Alguém registrou um bug e até enviou um patch:

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

mas o mantenedor de cachos a rejeitou. Aparentemente, uma opção "-X HEAD" quebrada está "funcionando como projetado".

--Jamshid

jamshid
fonte
4
Para ser justo, posso seguir a lógica da resposta do ticket: --headnos fornece uma implementação válida de uma solicitação HEAD e -X <method>simplesmente substitui o método HTTP na solicitação.
Hank
3
sim, era realmente isso que eu precisava. Eu tenho um servidor de buggy que exibe conteúdo quando recebe uma solicitação HEAD. -X HEADera a única maneira que eu poderia testá-lo ao tentar obter o servidor a aderir ao RFC
Hashbrown
5

Dos documentos :

-X, --request

(HTTP) Especifica um método de solicitação personalizado a ser usado ao se comunicar com o servidor HTTP. O método de solicitação especificado será usado em vez do método usado de outra forma (cujo padrão é GET). Leia a especificação HTTP 1.1 para obter detalhes e explicações. Solicitações HTTP adicionais comuns incluem PUT e DELETE, mas tecnologias relacionadas como WebDAV oferecem PROPFIND, COPY, MOVE e muito mais.

Normalmente você não precisa dessa opção. Todos os tipos de solicitações GET, HEAD, POST e PUT são bastante chamados usando opções de linha de comando dedicadas.

Esta opção altera apenas a palavra real usada na solicitação HTTP, não altera o modo como a curvatura se comporta . Por exemplo, se você deseja fazer uma solicitação HEAD adequada, usar -X HEAD não será suficiente. Você precisa usar a opção -I, --head.

Em outras palavras, -Xé para fins diferentes métodos GET, HEAD, POSTe PUT. Para HEADuso -I.

x-yuri
fonte
0

Encontro o mesmo problema ao escrever o código cpp no ​​curl 7.34,

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "HEAD");

vai ficar lá por um longo tempo, parece que está esperando a transferência do corpo até que um tempo limite ocorra. depois de adicionar uma nova linha, esse problema foi resolvido.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

do doc

faça a solicitação de download sem obter o corpo

essa linha forçaria o enrolamento a não esperar.

dasons
fonte