Setel cURL untuk menggunakan host virtual lokal

115

Menggunakan Apache atau Ngnix Saya selalu membuat situs pengembangan berdasarkan proyek nyata seperti http://project1.locyang, setelah menambahkan ke .hostsfile saya , browser tidak memiliki masalah dalam menggunakannya.

Namun, ketika saya mencoba membuat permintaan cURL ( http://project1.loc/post.json) ke URL yang sama, saya tidak pernah mendapatkan apa pun selain batas waktu. Saya berasumsi cURL tidak peduli dengan host khusus saya dan langsung menuju ke server nama untuk infonya.

Bagaimana cara memperbaikinya?

PEMBARUAN Saya menetapkan tajuk khusus "HOST: http: //project1.loc " dan sekarang saya mendapatkan 400 kesalahan - tetapi kesalahan itu terjadi seketika jadi saya berasumsi bahwa cURL setidaknya menggunakan file host ...

Xeoncross
sumber

Jawaban:

428

Sebenarnya, curl memiliki opsi secara eksplisit untuk ini: --resolve

Dari pada curl -H 'Host: yada.com' http://127.0.0.1/something

menggunakan curl --resolve 'yada.com:80:127.0.0.1' http://yada.com/something

Apa bedanya, Anda bertanya?

Antara lain, ini berfungsi dengan HTTPS. Dengan asumsi server lokal Anda memiliki sertifikat untuk yada.com, contoh pertama di atas akan gagal karena yada.comsertifikat tidak cocok dengan 127.0.0.1nama host di URL.

Contoh kedua berfungsi dengan benar dengan HTTPS.

Intinya, meneruskan header "Host" melalui -Htidak meretas Host Anda ke kumpulan header, tetapi melewati semua kecerdasan khusus host curl. Menggunakan --resolvememanfaatkan semua logika normal yang berlaku, tetapi hanya berpura-pura pencarian DNS mengembalikan data dalam opsi baris perintah Anda. Ini bekerja seperti /etc/hostsseharusnya.

Catatan --resolvemembutuhkan nomor port, jadi untuk HTTPS Anda akan menggunakan

curl --resolve 'yada.com:443:127.0.0.1' https://yada.com/something

John Hart
sumber
26
Ini membunuh saya - dapatkah seseorang menandai ini sebagai jawaban yang benar? Ini jauh lebih baru daripada jawabannya, jadi tidak memiliki suara .. tetapi jawaban yang diterima salah (yaitu, hanya berfungsi untuk situasi tertentu) = (
John Hart
Ini memang jawaban yang bagus, dan menerima suara saya. Hanya Xenocross yang dapat menandai jawaban sebagai diterima. Pada waktunya, orang lain kemungkinan besar akan datang ke sini dan secara bertahap memilih Anda lebih tinggi.
Hobodave
10
Perlu dicatat bahwa --resolve hanya ditambahkan di curl 7.21.3 - jika Anda terjebak pada host yang lebih lama (misalnya Ubuntu 10.04 LTS) maka opsi -H 'Host ...' masih merupakan fallback yang berguna.
Ken
9
Meskipun saya setuju ini mungkin harus menjadi jawaban yang diterima (dan saya pasti tidak akan tersinggung jika OP mengubahnya, sebaliknya), mengatakan bahwa jawaban saya salah tidak benar: itu benar untuk versi yang tersedia pada saat itu pertanyaan dan jawaban pun dihasilkan. Pengguna SO, Anda tidak dapat diganggu membaca setelah jawaban pertama dan juga mengevaluasi jawaban berdasarkan stempel waktu mereka tidak akan pernah mendapatkan bantuan terbaik ...
Bruno
1
Maaf, Bruno, jangan tersinggung.
John Hart
120

EDIT: Meskipun ini adalah jawaban yang diterima saat ini, pembaca mungkin menemukan jawaban lain ini oleh pengguna John Hart lebih disesuaikan dengan kebutuhan mereka. Ini menggunakan opsi yang, menurut pengguna Ken , diperkenalkan di versi 7.21.3 (yang dirilis pada Desember 2010 , yaitu setelah jawaban awal ini).


Dalam pertanyaan yang Anda edit, Anda menggunakan URL sebagai nama host, sedangkan itu harus berupa nama host saja.

Mencoba:

curl -H 'Host: project1.loc' http://127.0.0.1/something

di mana project1.locadalah hanya nama host dan 127.0.0.1adalah alamat IP target.

(Jika Anda menggunakan curl dari pustaka dan bukan pada baris perintah, pastikan Anda tidak meletakkannya http://di Hosttajuk.)

Bruno
sumber
1
Saya mendapatkan 400 kesalahan dengan PHP dan ketika saya membuat permintaan secara manual dengan curl.exe saya mendapatkan indeks default dari server yang berarti tidak menghormati HOSTheader.
Xeoncross
Saya sudah mencobanya di berbagai server dengan host virtual, dan berfungsi (dari baris perintah). Cobalah untuk Hosttidak HOSTberjaga-jaga (meskipun menurut saya seharusnya tidak peka huruf besar-kecil). Seperti yang saya katakan, pastikan Anda hanya menggunakan nama host di Hostheader, tidak ada yang lain (tidak http://dan tidak /somethingsetelah). Bagaimana Anda mengatur file host Anda?
Bruno
Memposting lebih banyak data tentang hasil melakukan ini di bawah.
Xeoncross
1
Seperti yang dikatakan Bruno di bawah ini, masalahnya mungkin hanya konfigurasi server saya karena permintaan tersebut tampaknya membuatnya dan menerima kesalahan 403.
Xeoncross
Saya melewatkan "127.0.0.1 myvirtualhost.localhost" di file host karena itu masalahnya.
Arvind K.
2

Gunakan nama domain yang benar-benar memenuhi syarat (seperti dev.yourdomain.com) yang mengarah ke 127.0.0.1atau coba edit file host yang tepat (biasanya / etc / hosts di lingkungan * nix).

Oli
sumber
Saya mengembangkan pada windows menggunakansystem32/drivers/etc/hosts
Xeoncross
Apakah Anda menggunakan build asli cURL atau cross-build cygwin? Saya mengatakan ini karena saya tidak yakin bagaimana masing-masing menyelesaikan DNS mereka. Native harus mengambil dari file host Windows tetapi versi cygwin mungkin menginginkan versi cygwin. Apa pun itu, menggunakan domain nyata yang menunjuk ke 127.0.0.1 akan berfungsi, bagaimanapun hal-hal sudah disiapkan.
Oli
Saya menggunakan build windows asli yang disertakan dengan PHP 5.3 untuk windows (Menjalankan sebagai php_fastcgi).
Xeoncross
2

Sepertinya ini bukan masalah yang tidak biasa.

Periksa ini dulu.

Jika itu tidak membantu, Anda dapat menginstal server DNS lokal di Windows, seperti ini . Konfigurasikan Windows untuk menggunakan localhost sebagai server DNS. Server ini dapat dikonfigurasi agar otoritatif untuk domain palsu apa pun yang Anda butuhkan, dan untuk meneruskan permintaan ke server DNS nyata untuk semua permintaan lainnya.

Saya pribadi berpikir ini agak berlebihan, dan tidak dapat melihat mengapa file host tidak berfungsi. Tapi itu harus menyelesaikan masalah yang Anda alami. Pastikan Anda juga mengatur server DNS normal Anda sebagai penerus.

Matt
sumber
Bisakah Anda membaca jawaban Anda sendiri dan menulis ulang? Bahasa Inggris di baris ketiga tidak masuk akal!
OmarOthman
Dirapikan. Wah, kira saya mengetik terlalu cepat tanpa membacanya dengan benar.
Matt
1

Apakah server benar-benar mendapatkan permintaan, dan apakah Anda menangani nama host (alias) dengan benar?

setelah menambahkan ke file .hosts saya

Periksa log server web Anda, untuk melihat bagaimana permintaan itu masuk ...

curl memiliki opsi untuk membuang permintaan yang dikirim, dan respons diterima, itu disebut jejak, yang akan disimpan ke file.

--jejak

Jika Anda kehilangan informasi host atau header - Anda dapat memaksa header tersebut dengan opsi konfigurasi.

Saya akan mendapatkan permintaan curl yang bekerja pada baris perintah, dan kemudian mencoba menerapkannya di PHP.

opsi konfigurasinya adalah

-K / - config

opsi yang relevan dengan curl ada di sini

--trace Mengaktifkan trace dump lengkap dari semua data yang masuk dan keluar, termasuk informasi deskriptif, ke file keluaran yang diberikan. Gunakan "-" sebagai nama file agar keluaran dikirim ke stdout.

      This option overrides previous uses of -v/--verbose or --trace-ascii.

      If this option is used several times, the last one will be used.

-K / - config Tentukan file konfigurasi untuk membaca argumen curl. File konfigurasi adalah file teks di mana argumen baris perintah dapat ditulis yang kemudian akan digunakan seolah-olah ditulis pada baris perintah yang sebenarnya. Opsi dan parameternya harus ditentukan pada baris file konfigurasi yang sama, dipisahkan oleh spasi, titik dua, tanda sama dengan atau kombinasinya (namun, pemisah yang disukai adalah tanda sama dengan). Jika parameter berisi spasi, parameter harus diapit dalam tanda kutip. Dalam tanda kutip ganda, tersedia urutan escape berikut: \, \ ", \ t, \ n, \ r dan \ v. Garis miring terbalik sebelum huruf lainnya diabaikan. Jika kolom pertama dari baris konfigurasi adalah '#' karakter, sisa baris akan diperlakukan sebagai komentar.

      Specify the filename to -K/--config as '-' to make curl read the file from stdin.

      Note that to be able to specify a URL in the config file, you need to specify it using the --url option, and not by simply writing the URL on its own line. So, it could look similar to this:

      url = "http://curl.haxx.se/docs/"

      Long option names can optionally be given in the config file without the initial double dashes.

      When curl is invoked, it always (unless -q is used) checks for a default config file and uses it if found. The default config file is checked for in the following places in this order:

      1) curl tries to find the "home dir": It first checks for the CURL_HOME and then the HOME environment variables. Failing that, it uses getpwuid() on UNIX-like systems (which  returns  the  home  dir
      given the current user in your system). On Windows, it then checks for the APPDATA variable, or as a last resort the '%USERPROFILE%\Application Data'.

      2)  On windows, if there is no _curlrc file in the home dir, it checks for one in the same dir the curl executable is placed. On UNIX-like systems, it will simply try to load .curlrc from the deter-
      mined home dir.

      # --- Example file ---
      # this is a comment
      url = "curl.haxx.se"
      output = "curlhere.html"
      user-agent = "superagent/1.0"

      # and fetch another URL too
      url = "curl.haxx.se/docs/manpage.html"
      -O
      referer = "http://nowhereatall.com/"
      # --- End of example file ---

      This option can be used multiple times to load multiple config files.
George Lambert
sumber
Sekali lagi, saya menggunakan PHP di windows untuk mengambil halaman di vhost di windows yang sama yang menjalankan nginx. Bagaimanapun, saya membuat permintaan ke vhost http://domain.loc/users/getSettings.xmldan inilah yang ditunjukkan oleh access.log 127.0.0.1 - - [09/Aug/2010:11:42:55 -0500] "POST /users/getSettings.xml HTTP/1.1" 499 0 "-" "-"dan curl. Operation timed out after 10000 milliseconds with 0 bytes received Jadi saya kira cURL sebenarnya menangani vhost karena access.log menunjukkan permintaan tersebut. Kemudian lagi, sekarang mungkin membuatnya ke domain yang benar ...
Xeoncross
Angka "499 0" pada baris itu SANGAT signifikan. Proses mengembalikan nol byte - yang menunggu curl. dan mengembalikan HTTP 499 - yang merupakan hasil yang aneh. panggil skrip lain - yang mengembalikan string statis sebagai respons terhadap posting - dan lihat bahwa Anda mendapatkan respons dalam bentuk curl. Anda banyak yang tidak memposting data seperti yang Anda harapkan ... dan skrip mungkin kehabisan waktu menunggu tanggapan. juga mengubah skrip untuk memasukkan input ke file temp, dan melihat bahwa Anda "menerima posting yang diharapkan dari permintaan curl Anda"
George Lambert
Tambahkan apakah Anda mencoba baris perintah curl - sehingga Anda dapat mengontrol pos dan melihat respons server?
George Lambert
Jawaban cepat untuk pertanyaan kedua - tidak. Saya tidak tahu cara mengakses baris perintah cURL di windows karena itu dibangun ke dalam PHP dan bukan terminal windows.
Xeoncross
1
Anda dapat mengunduh versi baris perintah dari curl untuk windows dari sini curl.haxx.se/download.html
George Lambert
1

Membuat permintaan untuk

C:\wnmp\curl>curl.exe --trace-ascii -H 'project1.loc' -d "uuid=d99a49d846d5ae570
667a00825373a7b5ae8e8e2" http://project1.loc/Users/getSettings.xml

Menghasilkan -Hfile log yang berisi:

== Info: Could not resolve host: 'project1.loc'; Host not found
== Info: Closing connection #0
== Info: About to connect() to project1.loc port 80 (#0)
== Info:   Trying 127.0.0.1... == Info: connected
== Info: Connected to project1.loc (127.0.0.1) port 80 (#0)
=> Send header, 230 bytes (0xe6)
0000: POST /Users/getSettings.xml HTTP/1.1
0026: User-Agent: curl/7.19.5 (i586-pc-mingw32msvc) libcurl/7.19.5 Ope
0066: nSSL/1.0.0a zlib/1.2.3
007e: Host: project1.loc
0092: Accept: */*
009f: Content-Length: 45
00b3: Content-Type: application/x-www-form-urlencoded
00e4: 
=> Send data, 45 bytes (0x2d)
0000: uuid=d99a49d846d5ae570667a00825373a7b5ae8e8e2
<= Recv header, 24 bytes (0x18)
0000: HTTP/1.1 403 Forbidden
<= Recv header, 22 bytes (0x16)
0000: Server: nginx/0.7.66
<= Recv header, 37 bytes (0x25)
0000: Date: Wed, 11 Aug 2010 15:37:06 GMT
<= Recv header, 25 bytes (0x19)
0000: Content-Type: text/html
<= Recv header, 28 bytes (0x1c)
0000: Transfer-Encoding: chunked
<= Recv header, 24 bytes (0x18)
0000: Connection: keep-alive
<= Recv header, 25 bytes (0x19)
0000: X-Powered-By: PHP/5.3.2
<= Recv header, 56 bytes (0x38)
0000: Set-Cookie: SESSION=m9j6caghb223uubiddolec2005; path=/
<= Recv header, 57 bytes (0x39)
0000: P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
<= Recv header, 2 bytes (0x2)
0000: 
<= Recv data, 118 bytes (0x76)
0000: 6b
0004: <html><head><title>HTTP/1.1 403 Forbidden</title></head><body><h
0044: 1>HTTP/1.1 403 Forbidden</h1></body></html>
0071: 0
0074: 
== Info: Connection #0 to host project1.loc left intact
== Info: Closing connection #0

File host saya terlihat seperti:

# Copyright (c) 1993-1999 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

127.0.0.1       localhost
...
...
127.0.0.1   project1.loc
Xeoncross
sumber
1
-Hadalah untuk header lengkap, bukan hanya host, jadi gunakan -H 'Host: project1.loc'. Selain itu, meskipun ada masalah ini, permintaan ini tampaknya berfungsi pada host yang benar (diperoleh dengan benar dari hostsfile Anda dengan setidaknya menggunakan curl pada baris perintah). Apa yang tidak berfungsi (403) sepertinya merupakan masalah otentikasi / otorisasi, jadi sepertinya server Anda memblokir permintaan ini. Saya sarankan untuk memperbaiki konfigurasi server untuk ini.
Bruno
0

Untuk menyiapkan host virtual di server http Apache yang belum terhubung melalui DNS, saya suka menggunakan:

curl -s --connect-to ::host-name: http://project1.loc/post.json

Di mana nama host adalah alamat IP atau nama DNS dari mesin yang menjalankan server web. Ini juga berfungsi dengan baik untuk https-Sites.

effhaa
sumber
1
Posting ini telah dikirim 10 tahun yang lalu dan diperbaiki melalui komentar, terima kasih atas kontribusinya. Pada postingan semacam ini silahkan cek jawaban, jika ada yang tidak beres kirim vote lain postingan jawaban baru karena bisa saja kamu tandai sebagai spam.
samuhay