Як правильно обробляти gzipped сторінку при використанні curl?


139

Я написав скрипт bash, який отримує вихід з веб-сайту за допомогою curl і робить купу рядкових маніпуляцій на виході html. Проблема полягає в тому, коли я запускаю її проти сайту, який повертає вихідний файл gzipped. Захід на сайт у браузері працює чудово.

Коли я запускаю curl вручну, я отримую gzipped результат:

$ curl "http://example.com"

Ось заголовок із цього конкретного сайту:

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

Я знаю, що повернуті дані gzipped, тому що це повертає html, як очікувалося:

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

Я не хочу передавати висновок через gunzip, тому що сценарій працює як є на інших сайтах, а трубопровід через gzip порушує цю функціональність.

Що я спробував

  1. зміна користувача-агента (я спробував ту саму рядок, який надсилає мій браузер, "Mozilla / 4.0" тощо)
  2. людина завивати
  3. Пошук Google
  4. пошук потокового потоку

Все вийшло порожнім

Будь-які ідеї?


Для мене проблема полягала в тому, що cURL не зміг розпакувати 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) - вирішив його, видаливши brз Accept-Encoding. см stackoverflow.com/questions/18983719 / ...
Ніно Škopac

Відповіді:


260

curlавтоматично розпакує відповідь, якщо встановити --compressedпрапор:

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

- компресований (HTTP) запит на стиснуту відповідь за допомогою одного з алгоритмів, які підтримує libcurl, і зберегти нестиснений документ. Якщо використовується ця опція і сервер надсилає непідтримуване кодування, curl повідомить про помилку.

gzip, швидше за все, підтримується, але ви можете перевірити це, запустивши curl -Vта шукаючи libz десь у рядку "Особливості":

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

Зауважте, що тут справді винна веб-сайт. Якщо curlне пройшов Accept-Encoding: gzipзаголовок запиту, сервер не повинен був надсилати стиснуту відповідь.


24
Це може здатися помилкою згортання, оскільки воно повинно викликати розшифровку на основі відповіді, а не на тому, що він вимагав (враховуючи, що він підтримує gzip). Цитуючи HTTP 1.1: "Якщо в запиті немає поля Accept-Encoding, сервер МОЖЕ припустити, що клієнт прийме будь-яке кодування вмісту." Але все-таки говорять про те, що сервери ДОЛЖЕН у цьому випадку не кодувати вміст, хм, зрозуміти.
Джордж Лунд

насправді на моїй версії працює --comp --compress --compress
Radu Toader

3
тут також встановлюється заголовок запиту: "Accept-Encoding: deflate, gzip", це чудово, оскільки якщо сервер обслуговує gzip, а не gzip, вам просто потрібно - стиснути і не додавати заголовок приймання кодування самостійно
mbert

допоможіть моїй якості з цим рішенням за 1 хвилину! спасибі ! Однак, моя програма фактично надсилає відповідь gzip за допомогою Content-Encoding: gzip. Браузери та сучасні інструменти (наприклад, httpie) автоматично обробляють його. Я думаю, завитка просто потребує "підказки"
Далекий

Дивно, але налаштування Accept-Encoding: deflate, gzipнедостатньо - навіть якщо сервер поверне gzip-відповідь за допомогою Content-Encoding: gzip, curl не автоматично скасовує його. --compressedПрапор потрібно.
rjh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.