วิธีจัดการเพจ gzipped อย่างถูกต้องเมื่อใช้ curl?


143

ฉันเขียนสคริปต์ทุบตีที่ได้รับผลลัพธ์จากเว็บไซต์โดยใช้ 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. การเปลี่ยน user-agent (ฉันลองใช้สตริงเดียวกันกับที่เบราว์เซอร์ส่ง "Mozilla / 4.0" ฯลฯ )
  2. คนขด
  3. ค้นหา Google
  4. กำลังค้นหา stackoverflow

ทุกอย่างกลับมาว่างเปล่า

ความคิดใด ๆ ?


สำหรับฉันปัญหาคือ 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/…
Nino Škopac

คำตอบ:


267

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
สิ่งนี้ดูเหมือนจะเป็นข้อผิดพลาด curl เนื่องจากควรเรียกใช้การถอดรหัสตามการตอบสนองไม่ใช่สิ่งที่ร้องขอ (เนื่องจากรองรับ gzip) หากต้องการอ้างอิง HTTP 1.1: "หากไม่มีฟิลด์การเข้ารหัสที่ยอมรับอยู่ในคำขอเซิร์ฟเวอร์อาจถือว่าไคลเอ็นต์ยอมรับการเข้ารหัสเนื้อหาใด ๆ " แต่กล่าวต่อไปว่าเซิร์ฟเวอร์ควรจะไม่เข้ารหัสเนื้อหาในกรณีนี้อืมไปคิด
George Lund

ในเวอร์ชันของฉันใช้งานได้จริง --comp --compress --compressed
Radu Toader

3
นอกจากนี้ยังตั้งค่าส่วนหัวของคำขอ: "Accept-Encoding: deflate, gzip" ซึ่งดีมากเนื่องจากถ้าเซิร์ฟเวอร์ให้บริการ gzip และไม่มี gzip คุณเพียงแค่บีบอัดและไม่ต้องเพิ่มส่วนหัวการเข้ารหัสที่ยอมรับด้วยตัวคุณเอง
mbert

ช่วย QA ของฉันด้วยวิธีนี้ใน 1 นาที! ขอบคุณ ! ที่กล่าวว่าแอปพลิเคชันของฉันกำลังส่งการตอบสนอง gzip ด้วย Content-Encoding: gzip เบราว์เซอร์และเครื่องมือสมัยใหม่ (เช่น httpie) จะจัดการโดยอัตโนมัติ ฉันเดาว่า curl ต้องการ "คำใบ้"
Faraway

น่าแปลกใจที่การตั้งค่าAccept-Encoding: deflate, gzipไม่เพียงพอแม้ว่าเซิร์ฟเวอร์จะส่งคืนการตอบกลับ gzip ด้วยContent-Encoding: gzipcurl จะไม่เปิดเครื่องรูดโดยอัตโนมัติ --compressedธงเป็นสิ่งจำเป็น
rjh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.