Bagaimana cara menangani halaman gzip dengan benar saat menggunakan curl?

143

Saya menulis skrip bash yang mendapatkan output dari situs web menggunakan curl dan melakukan banyak manipulasi string pada output html. Masalahnya adalah ketika saya menjalankannya terhadap situs yang mengembalikan outputnya dalam bentuk gzip. Membuka situs di browser berfungsi dengan baik.

Saat saya menjalankan curl dengan tangan, saya mendapatkan hasil gzip:

$ curl "http://example.com"

Berikut tajuk dari situs tersebut:

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

Saya tahu data yang dikembalikan adalah gzip, karena ini mengembalikan html, seperti yang diharapkan:

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

Saya tidak ingin menyalurkan output melalui gunzip, karena skrip berfungsi sebagaimana adanya di situs lain, dan menyalurkan melalui gzip akan merusak fungsi itu.

Apa yang saya coba

  1. mengubah agen pengguna (Saya mencoba string yang sama yang dikirimkan browser saya, "Mozilla / 4.0", dll)
  2. pria ikal
  3. pencarian Google
  4. mencari stackoverflow

Semuanya kosong

Ada ide?

BryanH
sumber
Bagi saya, masalahnya adalah cURL tidak dapat mendekompresi 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) - menyelesaikannya dengan menghapus brdari Accept-Encoding. lihat stackoverflow.com/questions/18983719/…
Nino Škopac

Jawaban:

267

curlakan secara otomatis mendekompresi respons jika Anda menyetel --compressedbendera:

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

--compressed (HTTP) Minta respons terkompresi menggunakan salah satu algoritme yang didukung libcurl, dan simpan dokumen yang tidak dikompresi. Jika opsi ini digunakan dan server mengirimkan encoding yang tidak didukung, curl akan melaporkan kesalahan.

gzip kemungkinan besar didukung, tetapi Anda dapat memeriksanya dengan menjalankan curl -Vdan mencari libz di suatu tempat di baris "Fitur":

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

Perhatikan bahwa sebenarnya situs web tersebut yang salah di sini. Jika curltidak meneruskan Accept-Encoding: gzipheader permintaan, server seharusnya tidak mengirimkan respons terkompresi.

Martin
sumber
24
Ini akan tampak seperti bug curl, karena itu harus memicu decoding-nya berdasarkan respons, bukan pada apa yang diminta (mengingat bahwa ia mendukung gzip). Mengutip HTTP 1.1: "Jika tidak ada bidang Terima-Pengkodean dalam permintaan, server MUNGKIN menganggap bahwa klien akan menerima pengkodean konten apa pun." Tetapi selanjutnya dikatakan bahwa server HARUS dalam hal itu tidak menyandikan konten, hmm, lanjutkan.
George Lund
sebenarnya pada versi saya berfungsi --comp --compress --compressed
Radu
3
ini juga menyetel header permintaan: "Accept-Encoding: deflate, gzip" itu bagus karena jika server melayani gzip dan tidak ada gzip, Anda hanya perlu --compressed dan tidak menambahkan header accept encoding sendiri
mbert
bantu QA saya dengan solusi ini dalam 1 menit! Terima kasih ! Meskipun demikian, aplikasi saya sebenarnya mengirimkan respons gzip dengan Content-Encoding: gzip. Browser dan alat modern (mis. Httpie) secara otomatis menanganinya. Kurasa curl hanya butuh "petunjuk"
Jauh
Anehnya, pengaturan Accept-Encoding: deflate, gziptidak cukup - bahkan jika server mengembalikan respons gzip dengan Content-Encoding: gzip, curl tidak akan secara otomatis melepasnya. The --compressedflag diperlukan.
rjh