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

54

Eu estava vendo o tipo de servidor engraçado do link com curl -I http://www.reddit.com quando imaginei que curl -X HEAD http://www.reddit.com faria o mesmo. Mas, na verdade, isso não acontece.

Estou curioso sobre o porquê.

Isso é 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 esperar pela entrada do usuário.

Mas, farejando com tshark , vejo que o segundo comando realmente 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 ideia de por que essa diferença de comportamento?

    
por chmeee 10.05.2010 / 08:49

4 respostas

54

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

Mas antes de entrar nisso, curl -X HEAD não fornece nenhuma saída porque, por padrão, curl não imprime cabeçalhos se a opção -i não for fornecida (não necessária em -I ).

Em qualquer caso, 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 declarado por Content-Length . No caso de não Content-Length não ser especificado, eu acho que ele irá esperar por alguns dados ou por aquele cabeçalho em particular.

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

Porque Content-Length é 0, neste caso ambos os 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 Varnish), então curl protesta que a conexão foi fechada antes de ter recebido o número de bytes Content-Length .

A propósito, olhe para os cabeçalhos engraçados X-Bender (mostrado no exemplo) e X-Fry (teste você mesmo):).

    
por 12.05.2010 / 06:49
12

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

link

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

- Jamshid

    
por 29.03.2011 / 20:59
2

De os documentos :

-X, --request

(HTTP) Specifies a custom request method to use when communicating with the HTTP server. The specified request method will be used instead of the method otherwise used (which defaults to GET). Read the HTTP 1.1 specification for details and explanations. Common additional HTTP requests include PUT and DELETE, but related technologies like WebDAV offers PROPFIND, COPY, MOVE and more.

Normally you don't need this option. All sorts of GET, HEAD, POST and PUT requests are rather invoked by using dedicated command line options.

This option only changes the actual word used in the HTTP request, it does not alter the way curl behaves. So for example if you want to make a proper HEAD request, using -X HEAD will not suffice. You need to use the -I, --head option.

Em outras palavras, -X é para métodos diferentes de GET , HEAD , POST e PUT . Por HEAD use -I .

    
por 02.03.2017 / 07:36
0

Eu encontro o mesmo problema ao escrever 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 por transferência do corpo até que um tempo limite aconteça. depois de adicionar uma nova linha, esse problema foi resolvido.

curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L );

de o documento

do the download request without getting the body

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

    
por 19.07.2017 / 08:42