Mengapa curl tidak mengunduh tautan ini saat browser mau?

30

Saya menjalankan Mac OS 10.11.6 El Capitan. Ada tautan yang ingin saya unduh secara terprogram:

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

Jika saya menempelkan URL ini ke browser apa pun (misalnya Safari), unduhan berfungsi dengan baik.

Namun, jika saya mencoba mengunduh URL yang sama dari baris perintah dengan menggunakan curl, itu tidak berfungsi — hasilnya adalah file kosong:

$ 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
$ 

Tentu saja saya bisa mendapatkan file melalui browser, tapi saya ingin memahami mengapa para curlperintah di atas tidak bekerja.

Mengapa tidak dapat curlmengunduh file ini dengan benar, ketika ternyata ada di situs web dan dapat diakses dan diunduh dengan benar melalui browser web grafis?

mattobob
sumber
7
Saya ingin menunjukkan bahwa meskipun jawaban techraf tentang pengalihan benar, faktor lain seperti header dapat menyebabkan server menolak permintaan klien ikal untuk mengunduh file. Misalnya, jika server memiliki perlindungan DDoS backend, perangkat lunak perlindungan seperti itu biasanya memeriksa header browser yang layak, seperti memiliki hak User-Agent. Selain itu, beberapa unduhan browser mungkin berhasil karena cookie sesi (yaitu jika Anda masuk) hanya ada di browser tersebut.
Joseph A.
6
Untuk memecahkan masalah perintah ikal, Anda dapat menggunakan curl -vuntuk "verbose". Ini akan mencetak ke kesalahan standar berbagai info tentang koneksi, permintaan, dan respons. Dalam hal ini, Anda akan melihat bahwa responsnya meliputi HTTP 302 Found(kode arahan) dan Locationheader dengan URL untuk pergi. Kemudian Anda bisa man curlmengetahui cara mengatakannya untuk mengikuti arahan ulang.
Nathan Long

Jawaban:

59

Ada redirect pada webserver-sisi ke URL berikut: http://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg. Karena ini adalah CDN, perilaku persis (apakah Anda diarahkan atau tidak) mungkin tergantung pada lokasi Anda.

curltidak mengikuti arahan ulang secara default. Untuk menyuruhnya melakukannya, tambahkan -Largumen:

curl -L -O https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg
techraf
sumber
6
Pengalihan HTTPS ke HTTP? Itu mengerikan, dan saya tidak terkejut bahwa Curl meninggalkannya sendirian ...
Toby Speight
Dan jika ini tidak menyelesaikannya? Ada hubungannya dengan .asp mungkin?
mathtick
4

Jika browser dapat mengunduh file, Anda dapat memeriksa apa yang dilakukan browser. Di google chrome Anda dapat menggunakan yang berikut untuk melihat apa yang terjadi.

1) [Lihat> Pengembang> Alat pengembang> Tab Jaringan> tab Header]

2) Klik tautan unduhan.

3) Tautan file akan muncul di tab alat pengembang.

4) Klik kanan pada file dan pilih Copy> Copy as cURL.

Sekarang Anda memiliki tautan ikal yang berfungsi. Mungkin akan memiliki parameter berlebih yang dapat Anda potong.

Lebih detail: https://lornajane.net/posts/2013/chrome-feature-copy-as-curl

kandang
sumber
0

Saya akan mengonversi salah satu komentar pada posting ini menjadi sebuah jawaban.

Ada banyak tautan HTTP / HTTPS yang membutuhkan tajuk tertentu agar dapat berfungsi. Jadi ini akan menghasilkan respons yang berfungsi dari browser web tetapi bukan respons yang berfungsi dalam permintaan web backend seperti curl.

Saya baru saja berlari ke situs yang membutuhkan semua tajuk berikut. Kegagalan untuk menentukan mereka menghasilkan batas waktu.

  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
sumber