Wie gehe ich mit einer gezippten Seite richtig um, wenn ich Curl verwende?

139

Ich habe ein Bash-Skript geschrieben, das mithilfe von Curl von einer Website ausgegeben wird und eine Reihe von Zeichenfolgenmanipulationen an der HTML-Ausgabe vornimmt. Das Problem ist, wenn ich es für eine Site ausführe, die ihre Ausgabe gzipped zurückgibt. Das Aufrufen der Site in einem Browser funktioniert einwandfrei.

Wenn ich Curl von Hand laufen lasse, erhalte ich eine gezippte Ausgabe:

$ curl "http://example.com"

Hier ist der Header von dieser bestimmten Site:

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

Ich weiß, dass die zurückgegebenen Daten komprimiert sind, da dies erwartungsgemäß HTML zurückgibt:

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

Ich möchte die Ausgabe nicht über gunzip leiten, da das Skript auf anderen Websites unverändert funktioniert und das Weiterleiten durch gzip diese Funktionalität beeinträchtigen würde.

Was ich versucht habe

  1. Ändern des Benutzeragenten (Ich habe versucht, dieselbe Zeichenfolge zu verwenden, die mein Browser sendet, "Mozilla / 4.0" usw.)
  2. Mann locken
  3. Google-Suche
  4. Suche nach Stackoverflow

Alles war leer

Irgendwelche Ideen?

BryanH
quelle
Für mich war das Problem, dass 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) nicht dekomprimieren konnte - es wurde durch Entfernen brvon gelöst Accept-Encoding. siehe stackoverflow.com/questions/18983719/…
Nino Škopac

Antworten:

260

curldekomprimiert die Antwort automatisch, wenn Sie das --compressedFlag setzen:

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

--compressed (HTTP) Fordern Sie eine komprimierte Antwort mit einem der von libcurl unterstützten Algorithmen an und speichern Sie das unkomprimierte Dokument. Wenn diese Option verwendet wird und der Server eine nicht unterstützte Codierung sendet, meldet curl einen Fehler.

gzip wird höchstwahrscheinlich unterstützt, aber Sie können dies überprüfen, indem Sie libz irgendwo in der Zeile "Features" ausführencurl -V und suchen :

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

Beachten Sie, dass hier wirklich die betreffende Website schuld ist. Wenn curlkein Accept-Encoding: gzipAnforderungsheader übergeben wurde, sollte der Server keine komprimierte Antwort gesendet haben.

Martin
quelle
24
Dies scheint ein Curl-Fehler zu sein, da er seine Dekodierung basierend auf der Antwort und nicht auf der Anforderung auslösen sollte (vorausgesetzt, er unterstützt gzip). Um HTTP 1.1 zu zitieren: "Wenn in einer Anforderung kein Accept-Encoding-Feld vorhanden ist, kann der Server davon ausgehen, dass der Client jegliche Inhaltscodierung akzeptiert." Aber es heißt weiter, dass Server in diesem Fall den Inhalt nicht codieren sollten, hmm, go figure.
George Lund
Eigentlich funktioniert auf meiner Version --comp --compress --compressed
Radu Toader
3
Dies setzt auch den Anforderungsheader: "Accept-Encoding: deflate, gzip", das ist großartig, denn wenn der Server gzip und kein gzip bereitstellt, müssen Sie nur --komprimiert und den Accept-Codierungsheader nicht selbst hinzufügen
mbert
Helfen Sie meiner Qualitätssicherung mit dieser Lösung in 1 Minute! Danke ! Das heißt, meine Anwendung sendet tatsächlich eine gzip-Antwort mit Content-Encoding: gzip. Browser und moderne Tools (z. B. httpie) verarbeiten dies automatisch. Ich denke, Curl braucht nur einen "Hinweis"
Faraway
Überraschenderweise reicht die Einstellung Accept-Encoding: deflate, gzipnicht aus - selbst wenn der Server eine gzip-Antwort mit zurückgibt Content-Encoding: gzip, wird Curl diese nicht automatisch entpacken. Die --compressedFlagge ist erforderlich.
rjh