Ustaw cURL, aby używać lokalnych wirtualnych hostów

115

Korzystając z Apache lub Ngnix zawsze tworzę strony deweloperskie w oparciu o rzeczywiste projekty takie z http://project1.locktórych po dodaniu do mojego .hostspliku przeglądarka nie ma problemu z obsługą .

Jednak gdy próbuję wykonać żądanie cURL ( http://project1.loc/post.json) do tego samego adresu URL, nigdy nie otrzymuję niczego poza limitem czasu. Zakładam, że cURL nie dba o moje niestandardowe hosty i trafia prosto do serwera nazw w celu uzyskania informacji.

Jak mogę to naprawić?

UPDATE Ustawiłem niestandardowy nagłówek „HOST: http: //project1.loc ” i teraz otrzymuję 400 błędów - ale są one natychmiastowe, więc zakładam, że cURL używa przynajmniej pliku hosts ...

Xeoncross
źródło

Odpowiedzi:

428

W rzeczywistości curl ma do tego opcję: --resolve

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

posługiwać się curl --resolve 'yada.com:80:127.0.0.1' http://yada.com/something

Jaka jest różnica, pytasz?

Działa to między innymi z HTTPS. Zakładając, że Twój serwer lokalny ma certyfikat dla yada.com, pierwszy przykład powyżej zakończy się niepowodzeniem, ponieważ yada.comcertyfikat nie jest zgodny z 127.0.0.1nazwą hosta w adresie URL.

Drugi przykład działa poprawnie z HTTPS.

Zasadniczo, przekazanie nagłówka „Host” przez -Hhackowanie twojego hosta do zestawu nagłówków pomija całą inteligencję curl specyficzną dla hosta. Używanie --resolvewykorzystuje całą normalną logikę, która ma zastosowanie, ale po prostu udaje, że wyszukiwanie DNS zwróciło dane w opcji wiersza poleceń. Działa tak, jak /etc/hostspowinno.

Uwaga --resolveprzyjmuje numer portu, więc w przypadku protokołu HTTPS należy użyć

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

John Hart
źródło
26
To mnie zabija - czy ktoś może oznaczyć to jako właściwą odpowiedź? Jest dużo nowszy niż odpowiedź, więc nie ma głosów ... ale zaakceptowana odpowiedź jest nieprawidłowa (tj. Działa tylko w określonych sytuacjach) = (
John Hart
To naprawdę świetna odpowiedź i otrzymałem mój głos. Tylko Xenocross może oznaczyć odpowiedź jako zaakceptowaną. Z czasem inni prawdopodobnie przyjdą tutaj i stopniowo będą głosować wyżej.
hobodave
10
Warto zauważyć, że opcja --resolve została dodana tylko w curl 7.21.3 - jeśli utkniesz na starszym hoście (np. Ubuntu 10.04 LTS), opcja -H 'Host ...' jest nadal użyteczną alternatywą.
Ken
9
Chociaż zgadzam się, że to prawdopodobnie powinna być akceptowana odpowiedź (i na pewno nie obraziłbym się, gdyby PO ją zmienił, wręcz przeciwnie), mówiąc, że moja odpowiedź jest nieprawidłowa, nie jest poprawna: jest poprawna dla wersji dostępnych w tym czasie pytanie i odpowiedź zostały stworzone. Użytkownicy SO, którym nie będzie Ci przeszkadzać czytanie po pierwszej odpowiedzi, a także oceniają odpowiedzi na podstawie ich sygnatur czasowych, nigdy nie uzyskają najlepszej pomocy ...
Bruno
1
Przepraszam, Bruno, bez obrazy.
John Hart
120

EDYTUJ: Chociaż jest to obecnie akceptowana odpowiedź, czytelnicy mogą uznać tę inną odpowiedź użytkownika Johna Harta za bardziej dostosowaną do ich potrzeb. Korzysta z opcji, która według użytkownika Kena została wprowadzona w wersji 7.21.3 ( wydanej w grudniu 2010 , czyli po tej wstępnej odpowiedzi).


W edytowanym pytaniu używasz adresu URL jako nazwy hosta, podczas gdy musi to być tylko nazwa hosta.

Próbować:

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

gdzie project1.locto tylko nazwa hosta, a 127.0.0.1docelowy adres IP.

(Jeśli używasz curl z biblioteki, a nie z wiersza poleceń, upewnij się, że nie umieszczasz http://w Hostnagłówku).

Bruno
źródło
1
Otrzymuję 400 błędów z PHP i kiedy ręcznie wykonuję żądanie za pomocą curl.exe, otrzymuję domyślny indeks serwera, co oznacza, że ​​nie przestrzega HOSTnagłówka.
Xeoncross
Wypróbowałem to na różnych serwerach z wirtualnymi hostami i działa (z linii poleceń). Spróbuj Hostnie HOSTtylko na wszelki wypadek (chociaż myślę, że nie powinno to uwzględniać wielkości liter). Jak powiedziałem, upewnij się, że używasz tylko nazwy hosta w Hostnagłówku, nic więcej (nie http://i nie /somethingpo). Jak skonfigurowałeś plik hosts?
Bruno
Poniżej zamieściłem więcej danych o wynikach tego działania.
Xeoncross
1
Jak powiedział Bruno poniżej, problem prawdopodobnie dotyczy tylko mojej konfiguracji serwera, ponieważ żądanie wydaje się je wykonywać i otrzymuje błąd 403.
Xeoncross
Brakowało „127.0.0.1 myvirtualhost.localhost” w pliku hosts, stąd problem.
Arvind K.
2

Użyj prawdziwej, w pełni kwalifikowanej nazwy domeny (takiej jak dev.yourdomain.com), która wskazuje na 127.0.0.1lub spróbuj edytować odpowiedni plik hosts (zwykle / etc / hosts w środowiskach * nix).

Oli
źródło
system32/drivers/etc/hosts
Tworzę na Windowsie
Czy używasz natywnej kompilacji cURL lub jakiejś kompilacji krzyżowej Cygwin? Mówię to, ponieważ nie jestem pewien, jak każdy z nich rozwiązuje swój DNS. Natywny powinien odebrać z pliku hostów systemu Windows, ale wersja cygwin może wymagać wersji cygwin. Tak czy inaczej, użycie prawdziwej domeny wskazującej na 127.0.0.1 działałoby, jakkolwiek wszystko jest skonfigurowane.
Oli
Używam natywnej kompilacji systemu Windows dołączonej do PHP 5.3 dla systemu Windows (działa jako php_fastcgi).
Xeoncross
2

Wydaje się, że nie jest to rzadki problem.

Sprawdź to najpierw.

Jeśli to nie pomoże, możesz zainstalować lokalny serwer DNS w systemie Windows, taki jak ten . Skonfiguruj system Windows, aby używał localhost jako serwera DNS. Ten serwer można skonfigurować tak, aby był autorytatywny dla dowolnych fałszywych domen, których potrzebujesz, i przekazywał żądania do prawdziwych serwerów DNS w przypadku wszystkich innych żądań.

Osobiście uważam, że jest to trochę przesadzone i nie rozumiem, dlaczego plik hosts nie działa. Ale to powinno rozwiązać problem, który masz. Upewnij się, że skonfigurowałeś również swoje zwykłe serwery DNS jako usługi przesyłania dalej.

Matt
źródło
Czy mógłbyś przeczytać własną odpowiedź i przepisać ją? Angielski w trzeciej linijce nie ma sensu!
OmarOthman
Uporządkowane. Ojej, myślę, że napisałem to zbyt szybko bez prawidłowego czytania.
Matt,
1

Czy serwer faktycznie otrzymuje żądania i czy poprawnie obsługujesz nazwę hosta (alias)?

po dodaniu do mojego pliku .hosts

Sprawdź dziennik serwera internetowego, aby zobaczyć, jak otrzymano żądanie ...

curl ma opcje zrzutu wysłanego żądania, a otrzymana odpowiedź nazywa się śledzeniem, która zostanie zapisana do pliku.

--ślad

Jeśli brakuje informacji o hoście lub nagłówku - możesz wymusić te nagłówki za pomocą opcji config.

Otrzymywałbym żądanie curl działające w wierszu poleceń, a następnie próbowałbym zaimplementować je w PHP.

opcja konfiguracji to

-K / - config

opcje, które są istotne w curl są tutaj

--trace Włącza pełny zrzut śledzenia wszystkich danych przychodzących i wychodzących, w tym informacji opisowych, do danego pliku wyjściowego. Użyj "-" jako nazwy pliku, aby dane wyjściowe były wysyłane na standardowe wyjście.

      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 Określa, z którego pliku konfiguracyjnego mają być odczytywane argumenty curl. Plik konfiguracyjny to plik tekstowy, w którym można zapisać argumenty wiersza poleceń, które następnie zostaną użyte tak, jakby zostały zapisane w rzeczywistym wierszu poleceń. Opcje i ich parametry muszą być określone w tym samym wierszu pliku konfiguracyjnego, oddzielone białymi znakami, dwukropkiem, znakiem równości lub dowolną ich kombinacją (jednak preferowanym separatorem jest znak równości). Jeśli parametr ma zawierać spacje, musi być ujęty w cudzysłów. W cudzysłowach dostępne są następujące sekwencje specjalne: \, \ ", \ t, \ n, \ r i \ v. Ukośnik odwrotny poprzedzający jakąkolwiek inną literę jest ignorowany. Jeśli pierwszą kolumną wiersza konfiguracji jest znak„ # ” znak, reszta linii będzie traktowana jako komentarz.

      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
źródło
Ponownie używam PHP w systemie Windows, aby pobrać stronę na serwerze vhost w tych samych oknach, na których działa nginx. W każdym razie http://domain.loc/users/getSettings.xmlwysłałem żądanie do vhosta i to właśnie pokazał access.log 127.0.0.1 - - [09/Aug/2010:11:42:55 -0500] "POST /users/getSettings.xml HTTP/1.1" 499 0 "-" "-"i zgłosił curl. Wydaje Operation timed out after 10000 milliseconds with 0 bytes received mi się, że cURL faktycznie obsługuje vhost, ponieważ access.log pokazuje żądanie. Z drugiej strony, może teraz trafić do właściwej domeny ...
Xeoncross
„499 0” w tym wierszu jest BARDZO znaczące. Proces zwrócił zero bajtów - na które czekał curl. i zwrócił HTTP 499 - co jest dziwnym wynikiem. wywołaj inny skrypt - który zwraca statyczny ciąg znaków w odpowiedzi na post - i zobacz, że otrzymujesz odpowiedź w curl. Wielu nie publikuje danych zgodnie z oczekiwaniami ... a skrypt może czekać na odpowiedź. zmień także skrypt, aby rejestrował dane wejściowe w pliku tymczasowym i zobaczył, że „otrzymujesz oczekiwany post z żądania curl”
George Lambert
Dodaj, czy próbowałeś curl wiersza poleceń - żebyś mógł kontrolować post i zobaczyć odpowiedź serwera?
George Lambert
Szybka odpowiedź na drugie pytanie - nie. Nie wiem, jak uzyskać dostęp do cURL wiersza poleceń w systemie Windows, ponieważ jest on wbudowany w PHP, a nie w terminal Windows.
Xeoncross
1
możesz pobrać wersję curl dla systemu Windows z wiersza poleceń
George Lambert,
1

Wysyłam prośbę do

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

Wynik w -Hpliku dziennika zawierającym:

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

Plik moich hostów wygląda następująco:

# 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
źródło
1
-Hdotyczy pełnego nagłówka, a nie tylko hosta, więc użyj -H 'Host: project1.loc'. Ponadto, pomimo tego problemu, to żądanie wydaje się działać na właściwym hoście (poprawnie uzyskanym z twojego hostspliku przez curl w linii poleceń). To, co nie działa (403), wygląda na problem z uwierzytelnianiem / autoryzacją, więc Twój serwer blokuje te żądania. Proponuję w tym celu naprawić konfigurację serwera.
Bruno
0

Do konfigurowania wirtualnych hostów na serwerach http Apache, które nie są jeszcze połączone przez DNS, lubię używać:

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

Gdzie nazwa-hosta to adres IP lub nazwa DNS komputera, na którym działa serwer WWW. Działa to również dobrze w przypadku witryn https.

effhaa
źródło
1
Ten post został wysłany 10 lat temu i poprawiony za pomocą komentarzy, dzięki za wkład. W tego rodzaju postach prosimy o sprawdzanie odpowiedzi, czy istnieje asnwear wyślij głos, w przeciwnym razie napisz nową odpowiedź, ponieważ możesz oznaczyć jako spam.
samuhay