Come gestire correttamente una pagina gzip quando si utilizza l'arricciatura?


139

Ho scritto uno script bash che ottiene l'output da un sito Web usando curl e fa un sacco di manipolazione delle stringhe sull'output html. Il problema è quando lo eseguo su un sito che sta restituendo il suo output gzip. Andare al sito in un browser funziona bene.

Quando eseguo il ricciolo a mano, ottengo un output gzip:

$ curl "http://example.com"

Ecco l'intestazione di quel particolare sito:

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=utf-8
X-Powered-By: PHP/5.2.17
Last-Modified: Sat, 03 Dec 2011 00:07:57 GMT
ETag: "6c38e1154f32dbd9ba211db8ad189b27"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: must-revalidate
Content-Encoding: gzip
Content-Length: 7796
Date: Sat, 03 Dec 2011 00:46:22 GMT
X-Varnish: 1509870407 1509810501
Age: 504
Via: 1.1 varnish
Connection: keep-alive
X-Cache-Svr: p2137050.pubip.peer1.net
X-Cache: HIT
X-Cache-Hits: 425

So che i dati restituiti sono compressi con gzip, perché questo restituisce html, come previsto:

$ curl "http://example.com" | gunzip

Non voglio reindirizzare l'output tramite gunzip, perché lo script funziona così com'è su altri siti e il piping tramite gzip interromperà tale funzionalità.

Quello che ho provato

  1. cambiando lo user-agent (ho provato la stessa stringa che il mio browser invia, "Mozilla / 4.0", ecc.)
  2. uomo arricciato
  3. ricerca Google
  4. ricerca stackoverflow

Tutto è risultato vuoto

Qualche idea?


Per me, il problema era che cURL non era in grado di decomprimere Brotli ( curl 7.54.0 (x86_64-apple-darwin17.0) libcurl/7.54.0 LibreSSL/2.0.20 zlib/1.2.11 nghttp2/1.24.0) - risolto rimuovendolo brda Accept-Encoding. vedi stackoverflow.com/questions/18983719/...
Nino Škopac

Risposte:


260

curldecomprimerà automaticamente la risposta se si imposta il --compressedflag:

curl --compressed "http://example.com"

--compressed (HTTP) Richiede una risposta compressa utilizzando uno degli algoritmi supportati da libcurl e salva il documento non compresso. Se viene utilizzata questa opzione e il server invia una codifica non supportata, curl segnalerà un errore.

gzip è probabilmente supportato, ma puoi verificarlo eseguendo curl -Ve cercando libz da qualche parte nella linea "Funzionalità":

$ curl -V
...
Protocols: ...
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz 

Si noti che è davvero il sito Web in questione che è in colpa qui. Se curlnon ha superato Accept-Encoding: gzipun'intestazione di richiesta, il server non avrebbe dovuto inviare una risposta compressa.


24
Questo sembra essere un bug di arricciatura, perché dovrebbe innescare la sua decodifica in base alla risposta, non a ciò che ha richiesto (dato che supporta gzip). Per citare HTTP 1.1: "Se in una richiesta non è presente alcun campo Accept-Encoding, il server PUO 'presumere che il client accetti qualsiasi codifica del contenuto." Ma continua dicendo che i server DOVREBBERO in quel caso non codificare il contenuto, hmm, vai a capire.
George Lund,

attualmente sulla mia versione funziona --comp --compress --compressed
Radu Toader il

3
questo imposta anche l'intestazione della richiesta: "Accept-Encoding: deflate, gzip" è fantastico poiché se il server serve gzip e no gzip, hai solo bisogno di - compresso e non aggiungere tu stesso l'intestazione accetta la codifica
mbert

aiuta il mio QA con questa soluzione in 1 minuto! grazie ! Detto questo, la mia applicazione sta effettivamente inviando una risposta gzip con Content-Encoding: gzip. Browser e strumenti moderni (ad es. Httpie) lo gestiscono automaticamente. Credo che il ricciolo abbia solo bisogno di un "suggerimento"
Faraway

Sorprendentemente, l'impostazione Accept-Encoding: deflate, gzipnon è sufficiente - anche se il server restituisce una risposta gzip con Content-Encoding: gzip, curl non la decomprimerà automaticamente. Il --compressedè richiesto bandiera.
RJ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.