ตั้งค่า cURL เพื่อใช้โฮสต์เสมือนภายในเครื่อง


115

การใช้ Apache หรือ Ngnix ฉันมักจะสร้างไซต์การพัฒนาตามโครงการจริงเช่นhttp://project1.locซึ่งหลังจากเพิ่มลงใน.hostsไฟล์แล้วเบราว์เซอร์ก็ไม่มีปัญหาในการใช้.

อย่างไรก็ตามเมื่อฉันพยายามส่งคำขอ cURL ( http://project1.loc/post.json) ไปยัง URL เดียวกันนั้นฉันจะไม่ได้รับอะไรเลยนอกจากหมดเวลา ฉันสมมติว่า cURL ไม่สนใจโฮสต์ที่กำหนดเองของฉันและตรงไปที่เนมเซิร์ฟเวอร์เพื่อดูข้อมูล

ฉันจะแก้ไขปัญหานี้ได้อย่างไร?

อัปเดต ฉันตั้งค่าส่วนหัวที่กำหนดเอง "HOST: http: //project1.loc " และตอนนี้ฉันได้รับข้อผิดพลาด 400 ข้อ แต่เกิดขึ้นทันทีดังนั้นฉันจึงสันนิษฐานว่าอย่างน้อย cURL ก็ใช้ไฟล์โฮสต์ ...

คำตอบ:


428

จริงๆแล้ว curl มีตัวเลือกอย่างชัดเจนสำหรับสิ่งนี้: --resolve

แทน curl -H 'Host: yada.com' http://127.0.0.1/something

ใช้ curl --resolve 'yada.com:80:127.0.0.1' http://yada.com/something

อะไรคือความแตกต่างคุณถาม?

สิ่งนี้ใช้ได้กับ HTTPS สมมติว่าเซิร์ฟเวอร์ภายในของคุณมีใบรับรองสำหรับyada.comตัวอย่างแรกด้านบนจะล้มเหลวเนื่องจากyada.comใบรับรองไม่ตรงกับ127.0.0.1ชื่อโฮสต์ใน URL

ตัวอย่างที่สองทำงานอย่างถูกต้องกับ HTTPS

โดยพื้นฐานแล้วการส่งส่วนหัว "โฮสต์" ผ่าน-Hจะแฮ็คโฮสต์ของคุณไปยังชุดส่วนหัว แต่จะข้ามข้อมูลอัจฉริยะเฉพาะโฮสต์ทั้งหมดของ curl ใช้--resolveประโยชน์จากตรรกะปกติทั้งหมดที่ใช้ แต่เพียงแค่แสร้งทำเป็นว่าการค้นหา DNS ส่งคืนข้อมูลในตัวเลือกบรรทัดคำสั่งของคุณ มันใช้งานได้เหมือนที่/etc/hostsควร

หมายเหตุ--resolveใช้หมายเลขพอร์ตดังนั้นสำหรับ HTTPS คุณจะใช้

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


26
นี่กำลังฆ่าฉัน - ใครก็ได้ช่วยทำเครื่องหมายว่านี่เป็นคำตอบที่ถูกต้องได้ไหม มันใหม่กว่าคำตอบมากจึงไม่มีคะแนนโหวต .. แต่คำตอบที่ยอมรับนั้นผิด (เช่นใช้ได้กับบางสถานการณ์เท่านั้น) = (
John Hart

นี่เป็นคำตอบที่ยอดเยี่ยมและได้รับการโหวตของฉัน Xenocross เท่านั้นที่สามารถทำเครื่องหมายคำตอบว่ายอมรับ ในเวลาต่อมาคนอื่น ๆ มักจะมาที่นี่และค่อยๆโหวตให้คุณสูงขึ้น
hobodave

10
ที่น่าสังเกตว่า - แก้ไขถูกเพิ่มใน curl 7.21.3 เท่านั้น - หากคุณติดอยู่กับโฮสต์รุ่นเก่า (เช่น Ubuntu 10.04 LTS) ตัวเลือก -H 'Host ... ' ยังคงเป็นทางเลือกที่มีประโยชน์
Ken

9
ในขณะที่ฉันยอมรับว่านี่น่าจะเป็นคำตอบที่ยอมรับได้ (และฉันจะไม่รู้สึกผิดอย่างแน่นอนหาก OP เปลี่ยนมันในทางตรงกันข้าม) โดยบอกว่าคำตอบของฉันไม่ถูกต้องไม่ถูกต้อง: มันถูกต้องสำหรับเวอร์ชันที่มีอยู่ในเวลานั้น เกิดคำถามและคำตอบ ดังนั้นผู้ใช้ที่คุณไม่ต้องกังวลเมื่ออ่านคำตอบแรกและประเมินคำตอบตามการประทับเวลาจะไม่ได้รับความช่วยเหลือที่ดีที่สุด ...
Bruno

1
ขอโทษบรูโนไม่มีความผิดหมายถึง
John Hart

120

แก้ไข:แม้ว่าคำตอบนี้จะเป็นที่ยอมรับในปัจจุบัน แต่ผู้อ่านอาจพบว่าคำตอบอื่น ๆ นี้โดยผู้ใช้John Hartปรับให้เข้ากับความต้องการของพวกเขาได้มากขึ้น มันใช้ตัวเลือกซึ่งอ้างอิงจากผู้ใช้Kenได้รับการแนะนำในเวอร์ชัน 7.21.3 (ซึ่งเปิดตัวในเดือนธันวาคม 2010เช่นหลังจากคำตอบเริ่มต้นนี้)


ในคำถามที่แก้ไขของคุณคุณกำลังใช้ URL เป็นชื่อโฮสต์ในขณะที่ต้องเป็นชื่อโฮสต์เท่านั้น

ลอง:

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

ซึ่งproject1.locเป็นเพียงชื่อโฮสต์และ127.0.0.1เป็นที่อยู่ IP เป้าหมาย

(หากคุณกำลังใช้ขดจากห้องสมุดและไม่ได้อยู่ในบรรทัดคำสั่งให้แน่ใจว่าคุณไม่ได้ใส่http://ในHostหัว.)


1
ฉันได้รับข้อผิดพลาด 400 ข้อกับ PHP และเมื่อฉันส่งคำขอด้วย curl.exe ด้วยตนเองฉันได้รับดัชนีเริ่มต้นของเซิร์ฟเวอร์ซึ่งหมายความว่าไม่เกี่ยวข้องกับHOSTส่วนหัว
Xeoncross

ฉันได้ลองใช้กับเซิร์ฟเวอร์ต่างๆที่มีโฮสต์เสมือนและใช้งานได้ (จากบรรทัดคำสั่ง) ลองHostไม่HOSTเพียงในกรณีที่ (แม้ว่าฉันคิดว่ามันไม่ควรจะเป็นกรณี ๆ ไป) ดังที่ฉันได้กล่าวไปแล้วตรวจสอบให้แน่ใจว่าคุณใช้เฉพาะชื่อโฮสต์ในHostส่วนหัวเท่านั้นไม่มีอะไรอื่น (ไม่http://และไม่มี/somethingหลังจาก) คุณตั้งค่าไฟล์โฮสต์ของคุณอย่างไร
Bruno

โพสต์ข้อมูลเพิ่มเติมเกี่ยวกับผลลัพธ์ของการดำเนินการนี้ด้านล่าง
Xeoncross

1
ดังที่ Bruno กล่าวไว้ด้านล่างปัญหาอาจเป็นเพียงแค่การกำหนดค่าเซิร์ฟเวอร์ของฉันเนื่องจากดูเหมือนว่าคำขอจะสร้างขึ้นและได้รับข้อผิดพลาด 403
Xeoncross

ฉันพลาด "127.0.0.1 myvirtualhost.localhost" ในไฟล์โฮสต์จึงเป็นปัญหา
Arvind K.

2

ใช้ชื่อโดเมนแบบเต็มจริง (เช่นdev.yourdomain.com) ที่ชี้ไป127.0.0.1หรือลองแก้ไขไฟล์โฮสต์ที่เหมาะสม (โดยปกติ / etc / hosts ในสภาพแวดล้อม * nix)


ฉันพัฒนาบน windows โดยใช้system32/drivers/etc/hosts
Xeoncross

คุณใช้งานสร้างดั้งเดิมของ cURL หรือ cygwin cross-build หรือไม่? ฉันพูดแบบนี้เพราะฉันไม่แน่ใจว่าแต่ละตัวแก้ไข DNS ของตนอย่างไร เนทีฟควรรับจากไฟล์โฮสต์ของ Windows แต่เวอร์ชัน cygwin อาจต้องการเวอร์ชัน cygwin ไม่ว่าจะด้วยวิธีใดการใช้โดเมนจริงที่ชี้ไปที่ 127.0.0.1 จะใช้งานได้อย่างไรก็ตามมีการตั้งค่าสิ่งต่างๆ
Oli

ฉันใช้ Windows build ที่มาพร้อมกับ PHP 5.3 สำหรับ windows (ทำงานเป็น php_fastcgi)
Xeoncross

2

ดูเหมือนว่านี่ไม่ใช่ปัญหาที่ผิดปกติ

ตรวจสอบสิ่งนี้ก่อน

หากไม่ได้ช่วยให้คุณสามารถติดตั้งเซิร์ฟเวอร์ DNS ท้องถิ่นบน Windows เช่นนี้ กำหนดค่า Windows เพื่อใช้ localhost เป็นเซิร์ฟเวอร์ DNS เซิร์ฟเวอร์นี้สามารถกำหนดค่าให้เชื่อถือได้สำหรับโดเมนปลอมที่คุณต้องการและส่งต่อคำขอไปยังเซิร์ฟเวอร์ DNS จริงสำหรับคำขออื่น ๆ ทั้งหมด

โดยส่วนตัวฉันคิดว่านี่เป็นด้านบนเล็กน้อยและไม่เห็นว่าทำไมไฟล์โฮสต์ถึงใช้งานไม่ได้ แต่ควรแก้ปัญหาที่คุณพบ ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าเซิร์ฟเวอร์ DNS ปกติของคุณเป็นผู้ส่งต่อด้วย


คุณช่วยอ่านคำตอบของคุณเองและเขียนใหม่ได้ไหม ภาษาอังกฤษในบรรทัดที่สามไม่สมเหตุสมผล!
OmarOthman

tidied ฉันเดาว่าฉันพิมพ์เร็วเกินไปโดยไม่ได้อ่านอย่างถูกต้อง
Matt

1

เซิร์ฟเวอร์ได้รับคำขอจริงหรือไม่และคุณจัดการชื่อโฮสต์ (นามแฝง) อย่างถูกต้องหรือไม่

หลังจากเพิ่มลงในไฟล์. hosts ของฉัน

ตรวจสอบบันทึกเว็บเซิร์ฟเวอร์ของคุณเพื่อดูว่าคำขอเข้ามาได้อย่างไร ...

curl มีตัวเลือกในการถ่ายโอนคำขอที่ส่งและการตอบกลับที่ได้รับเรียกว่าการติดตามซึ่งจะถูกบันทึกลงในไฟล์

--ติดตาม

หากคุณไม่มีข้อมูลโฮสต์หรือส่วนหัวคุณสามารถบังคับส่วนหัวเหล่านั้นด้วยตัวเลือกการกำหนดค่า

ฉันจะได้รับคำขอ curl ที่ทำงานบนบรรทัดคำสั่งจากนั้นลองใช้งานใน PHP

ตัวเลือก config คือ

-K / - การตั้งค่า

ตัวเลือกที่เกี่ยวข้องกับ curl อยู่ที่นี่

--trace เปิดใช้งานการถ่ายโอนข้อมูลแบบเต็มของข้อมูลขาเข้าและขาออกรวมถึงข้อมูลเชิงบรรยายไปยังไฟล์เอาต์พุตที่กำหนด ใช้ "-" เป็นชื่อไฟล์เพื่อส่งเอาต์พุตไปยัง 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 ระบุไฟล์ config ที่จะอ่านอาร์กิวเมนต์ curl ไฟล์กำหนดค่าเป็นไฟล์ข้อความที่สามารถเขียนอาร์กิวเมนต์บรรทัดคำสั่งซึ่งจะถูกนำไปใช้ราวกับว่าถูกเขียนบนบรรทัดคำสั่งจริง ต้องระบุตัวเลือกและพารามิเตอร์ในบรรทัดไฟล์กำหนดค่าเดียวกันโดยคั่นด้วยช่องว่างเครื่องหมายจุดคู่เครื่องหมายเท่ากับหรือชุดค่าผสมใด ๆ (อย่างไรก็ตามแยกที่ต้องการคือเครื่องหมายเท่ากับ) หากพารามิเตอร์มีช่องว่างพารามิเตอร์ต้องอยู่ภายในเครื่องหมายคำพูด ภายในเครื่องหมายคำพูดคู่จะมีลำดับการหลีกต่อไปนี้: \, \ ", \ t, \ n, \ r และ \ v แบ็กสแลชที่นำหน้าตัวอักษรอื่น ๆ จะถูกละเว้นหากคอลัมน์แรกของบรรทัดการกำหนดค่าเป็น" # " อักขระส่วนที่เหลือของบรรทัดจะถือว่าเป็นความคิดเห็น

      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.

อีกครั้งฉันใช้ PHP บน windows เพื่อดึงหน้าบน vhost บนหน้าต่างเดียวกันที่ใช้ nginx อย่างไรก็ตามฉันได้ส่งคำขอไปยัง vhost http://domain.loc/users/getSettings.xmlและนี่คือสิ่งที่ access.log แสดง127.0.0.1 - - [09/Aug/2010:11:42:55 -0500] "POST /users/getSettings.xml HTTP/1.1" 499 0 "-" "-"และ curl รายงานOperation timed out after 10000 milliseconds with 0 bytes received ดังนั้นฉันเดาว่า cURL กำลังจัดการ vhost จริงเนื่องจาก access.log แสดงคำขอ จากนั้นอีกครั้งตอนนี้อาจจะทำให้เป็นโดเมนที่ถูกต้อง ...
Xeoncross

"499 0" ในบรรทัดนั้นมีความสำคัญมาก กระบวนการส่งคืนศูนย์ไบต์ - ซึ่ง curl กำลังรออยู่ และส่งคืน HTTP 499 - ซึ่งเป็นผลลัพธ์ที่แปลก เรียกใช้สคริปต์อื่น - ที่ส่งคืนสตริงแบบคงที่เพื่อตอบสนองต่อโพสต์และดูว่าคุณได้รับการตอบสนองเป็น curl คุณหลายคนไม่ได้โพสต์ข้อมูลอย่างที่คุณคาดหวัง ... และสคริปต์อาจหมดเวลารอการตอบกลับ เปลี่ยนสคริปต์เพื่อบันทึกอินพุตเป็นไฟล์ชั่วคราวและดูว่าคุณ "ได้รับโพสต์ที่คาดไว้จากคำขอ curl ของคุณ"
George Lambert

คุณได้ลองใช้บรรทัดคำสั่ง curl เพื่อให้คุณสามารถควบคุมโพสต์และดูการตอบสนองของเซิร์ฟเวอร์ได้หรือไม่
George Lambert

คำตอบด่วนสำหรับคำถามที่สอง - ไม่ ฉันไม่ทราบวิธีเข้าถึง cURL บรรทัดคำสั่งบน windows เนื่องจากมีอยู่ใน PHP ไม่ใช่เทอร์มินัล windows
Xeoncross

1
คุณสามารถดาวน์โหลด curl เวอร์ชันบรรทัดคำสั่งสำหรับ windows ได้จากที่นี่ curl.haxx.se/download.html
George Lambert

1

การร้องขอไปยัง

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

ผลลัพธ์ใน-Hล็อกไฟล์ที่มี:

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

ไฟล์โฮสต์ของฉันดูเหมือนว่า:

# 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

1
-Hมีไว้สำหรับส่วนหัวแบบเต็มไม่ใช่แค่โฮสต์ดังนั้นให้ใช้-H 'Host: project1.loc'ไฟล์. นอกจากนี้แม้จะมีปัญหานี้ แต่ดูเหมือนว่าคำขอนี้จะทำงานบนโฮสต์ที่ถูกต้อง (ได้รับอย่างถูกต้องจากhostsไฟล์ของคุณโดย curl ในบรรทัดคำสั่งเป็นอย่างน้อย) สิ่งที่ไม่ทำงาน (403) ดูเหมือนว่าเป็นปัญหาการตรวจสอบสิทธิ์ / การอนุญาตดังนั้นเซิร์ฟเวอร์ของคุณจึงบล็อกคำขอเหล่านี้ ฉันขอแนะนำให้แก้ไขการกำหนดค่าเซิร์ฟเวอร์สำหรับสิ่งนี้
Bruno

0

สำหรับการตั้งค่าโฮสต์เสมือนบนเซิร์ฟเวอร์ Apache http ที่ยังไม่ได้เชื่อมต่อผ่าน DNS ฉันชอบใช้:

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

โดยที่ชื่อโฮสต์คือที่อยู่ IP หรือชื่อ DNS ของเครื่องที่เว็บเซิร์ฟเวอร์กำลังทำงานอยู่ นอกจากนี้ยังใช้ได้ดีกับ https-Sites


1
โพสต์นี้ส่งเมื่อ 10 ปีที่แล้วและแก้ไขผ่านความคิดเห็นขอบคุณสำหรับการสนับสนุน ในโพสต์ประเภทนี้โปรดตรวจสอบคำตอบหากมี asnwear ส่งโหวตอื่นโพสต์คำตอบใหม่เนื่องจากคุณอาจถูกทำเครื่องหมายว่าเป็นสแปม
samuhay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.