Warum lädt Curl diesen Link nicht herunter, wenn ein Browser dies tut?

30

Ich verwende Mac OS 10.11.6 El Capitan. Es gibt einen Link, den ich programmgesteuert herunterladen möchte:

https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg

Wenn ich diese URL in einen Browser (zB Safari) einfüge, funktioniert der Download einwandfrei.

Wenn ich jedoch versuche, dieselbe URL über die Befehlszeile herunterzuladen curl, funktioniert dies nicht. Das Ergebnis ist eine leere Datei:

$ ls -lA
$ curl -O https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
$ ls -lA
total 0
-rw-r--r--  1 myname  staff  0 Nov  7 14:07 mysql-5.7.16-osx10.11-x86_64.dmg
$ 

Natürlich kann ich die Datei über den Browser abrufen, aber ich möchte verstehen, warum der curlobige Befehl nicht funktioniert.

Warum kann curldiese Datei nicht korrekt heruntergeladen werden, wenn sie offensichtlich auf der Website vorhanden ist und über einen grafischen Webbrowser korrekt aufgerufen und heruntergeladen werden kann?

mattobob
quelle
7
Ich möchte darauf hinweisen, dass, obwohl die Antwort von techraf auf Redirects völlig korrekt ist, andere Faktoren wie Header dazu führen können, dass ein Server die Anforderung des Curl-Clients zum Herunterladen einer Datei ablehnt. Wenn der Server beispielsweise über einen Back-End-DDoS-Schutz verfügt, sucht diese Schutzsoftware normalerweise nach brauchbaren Browser-Headern, z. B. nach einem geeigneten User-Agent. Darüber hinaus können einige Browser-Downloads erfolgreich sein, da Sitzungscookies (dh, wenn Sie angemeldet sind) nur in diesem Browser vorhanden sind.
Joseph A.
6
Zur Fehlerbehebung bei einem Curl-Befehl können Sie curl -v"verbose" verwenden. Es werden verschiedene Informationen zu Verbindung, Anforderung und Antwort auf Standardfehler gedruckt. In diesem Fall sehen Sie, dass die Antwort HTTP 302 Found(einen Weiterleitungscode) und einen LocationHeader mit der URL enthält, zu der Sie wechseln möchten . Dann können Sie man curlherausfinden, wie Sie festlegen können, dass Weiterleitungen folgen sollen.
Nathan Long

Antworten:

59

Es gibt eine Umleitung auf dem Webserver-Seite auf die folgende URL: http://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg. Da es sich um ein CDN handelt, hängt das genaue Verhalten (ob Sie umgeleitet werden oder nicht) möglicherweise von Ihrem Standort ab.

curlfolgt standardmäßig keinen Weiterleitungen. Fügen Sie dazu das folgende -LArgument hinzu:

curl -L -O https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg
techraf
quelle
6
Eine HTTPS-zu-HTTP-Umleitung? Das ist schrecklich und ich bin nicht überrascht, dass Curl es gut alleine lässt ...
Toby Speight,
Und wenn das nicht klappt? Hat das vielleicht etwas mit .asp zu tun?
Mathtick
4

Wenn der Browser die Datei herunterladen kann, können Sie überprüfen, was der Browser tut. Auf Google Chrome können Sie Folgendes verwenden, um zu sehen, was passiert.

1) [Ansicht> Entwickler> Entwicklertools> Registerkarte Netzwerk> Registerkarte Header]

2) Klicken Sie auf den Download-Link.

3) Der Dateilink wird auf der Registerkarte Entwicklertools angezeigt.

4) Klicken Sie mit der rechten Maustaste auf die Datei und wählen Sie Kopieren> Als CURL kopieren.

Jetzt haben Sie einen Curl-Link, der funktioniert. Es wird wahrscheinlich überschüssige Parameter geben, die Sie wegschneiden können.

Weitere Details: https://lornajane.net/posts/2013/chrome-feature-copy-as-curl

Käfig
quelle
0

Ich werde einen der Kommentare zu diesem Beitrag in eine Antwort umwandeln.

Es gibt viele HTTP / HTTPS-Links, für deren Funktion bestimmte Header erforderlich sind. Dies führt zu einer funktionierenden Antwort von einem Webbrowser, aber nicht zu einer funktionierenden Antwort in einer Back-End-Webanforderung wie curl.

Ich bin gerade auf eine Site gestoßen, für die alle folgenden Header erforderlich waren. Die Nichtangabe führte zu einer Zeitüberschreitung.

  httpget.setHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36");
  httpget.setHeader("Upgrade-Insecure-Requests", "1");
  httpget.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
  httpget.setHeader("Accept-Encoding", "gzip, deflate, br");
  httpget.setHeader("Accept-Language", "en-US,en;q=0.9");
  httpget.setHeader("Connection", "keep-alive");
  httpget.setHeader("Host", "www.thehost.com");
Nicholas DiPiazza
quelle