Imposta cURL per utilizzare host virtuali locali


115

Utilizzando Apache o Ngnix creo sempre siti di sviluppo basati su progetti reali come i http://project1.locquali, dopo averli aggiunti al mio .hostsfile, il browser non ha problemi ad utilizzare.

Tuttavia, quando provo a fare una richiesta cURL ( http://project1.loc/post.json) allo stesso URL non ottengo mai altro che un timeout. Presumo che cURL non si preoccupi dei miei host personalizzati e vada direttamente a un server dei nomi per le sue informazioni.

Come posso risolvere questo problema?

AGGIORNAMENTO Ho impostato un'intestazione personalizzata "HOST: http: //project1.loc " e ora ricevo 400 errori, ma sono istantanei, quindi presumo che cURL stia almeno utilizzando il file hosts ...

Risposte:


428

In realtà, curl ha un'opzione esplicitamente per questo: --resolve

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

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

Qual è la differenza, chiedi?

Tra l'altro, funziona con HTTPS. Supponendo che il tuo server locale abbia un certificato per yada.com, il primo esempio sopra non avrà esito positivo perché il yada.comcertificato non corrisponde al 127.0.0.1nome host nell'URL.

Il secondo esempio funziona correttamente con HTTPS.

In sostanza, il passaggio di un'intestazione "Host" tramite -Hincide il tuo Host nel set di intestazioni, ma ignora tutta l'intelligenza specifica dell'host di curl. L'utilizzo --resolvesfrutta tutta la logica normale che si applica, ma semplicemente fa finta che la ricerca DNS abbia restituito i dati nell'opzione della riga di comando. Funziona proprio come/etc/hosts dovrebbe.

Nota --resolveaccetta un numero di porta, quindi per HTTPS useresti

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


26
Questo mi sta uccidendo: qualcuno può contrassegnarlo come la risposta giusta? È molto più recente della risposta, quindi non ha i voti .. ma la risposta accettata è sbagliata (vale a dire, funziona solo per determinate situazioni) = (
John Hart

Questa è davvero un'ottima risposta e ha ricevuto il mio voto. Solo Xenocross può contrassegnare una risposta come accettata. Col tempo altri probabilmente verranno qui e gradualmente voteranno il tuo più alto.
hobodave

10
Vale la pena notare che --resolve è stato aggiunto solo in curl 7.21.3 - se sei bloccato su un host più vecchio (ad esempio Ubuntu 10.04 LTS), l'opzione -H "Host ..." è ancora un utile ripiego.
Ken

9
Pur essendo d'accordo questa probabilmente dovrebbe essere la risposta accettata (e di certo non mi offenderei se l'OP la cambiasse, al contrario), dire che la mia risposta è sbagliata non è giusta: è corretta per le versioni disponibili al momento la domanda e la risposta sono state prodotte. Quindi gli utenti che non ti preoccupano di leggere oltre la prima risposta e anche di valutare le risposte in base ai loro timestamp non riceveranno mai il miglior aiuto ...
Bruno

1
Scusa, Bruno, senza offesa.
John Hart

120

EDIT: Sebbene questa sia attualmente una risposta accettata, i lettori potrebbero trovare quest'altra risposta dell'utente John Hart più adatta alle loro esigenze. Utilizza un'opzione che, secondo l'utente Ken , è stata introdotta nella versione 7.21.3 ( rilasciata a dicembre 2010 , cioè dopo questa risposta iniziale).


Nella domanda modificata, stai utilizzando l'URL come nome host, mentre deve essere solo il nome host.

Provare:

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

dove project1.locè solo il nome host ed 127.0.0.1è l'indirizzo IP di destinazione.

(Se stai usando ricciolo da una libreria e non sulla riga di comando, assicuratevi di non mettere http://in Hostintestazione.)


1
Ricevo 400 errori con PHP e quando effettuo manualmente la richiesta con curl.exe ottengo l'indice predefinito del server, il che significa che non rispetta l' HOSTintestazione.
Xeoncross

L'ho provato su vari server con host virtuali e funziona (dalla riga di comando). Prova Hostnon HOSTsolo nel caso (anche se penso che non dovrebbe essere case-sensitive). Come ho detto, assicurati di utilizzare solo il nome host Hostnell'intestazione, nient'altro (no http://e no /somethingdopo). Come hai impostato il tuo file hosts?
Bruno

Di seguito sono stati pubblicati ulteriori dati sui risultati di questa operazione.
Xeoncross

1
Come ha detto Bruno di seguito, il problema è probabilmente solo la configurazione del mio server poiché la richiesta sembra averlo fatto e ricevere un errore 403.
Xeoncross

Ho perso "127.0.0.1 myvirtualhost.localhost" nel file hosts, quindi il problema.
Arvind K.

2

Utilizzare un vero nome di dominio completo (come dev.yourdomain.com) che punta 127.0.0.1ao provare a modificare il file hosts corretto (di solito / etc / hosts in ambienti * nix).


system32/drivers/etc/hosts
Sviluppo

Stai usando la build nativa di cURL o qualche cross-build cygwin? Dico questo perché non sono sicuro di come ciascuno risolva il proprio DNS. Il nativo dovrebbe riprendere dal file hosts di Windows, ma una versione di cygwin potrebbe volere una versione di cygwin. In ogni caso, l'utilizzo di un dominio reale che punta a 127.0.0.1 funzionerebbe comunque le cose siano impostate.
Oli

Sto usando la build nativa di Windows inclusa con PHP 5.3 per Windows (in esecuzione come php_fastcgi).
Xeoncross

2

Sembra che questo non sia un problema raro.

Controlla prima questo .

Se ciò non aiuta, puoi installare un server DNS locale su Windows, come questo . Configurare Windows per utilizzare localhost come server DNS. Questo server può essere configurato per essere autorevole per qualsiasi dominio falso di cui hai bisogno e per inoltrare le richieste ai server DNS reali per tutte le altre richieste.

Personalmente penso che sia un po 'esagerato e non riesco a capire perché il file hosts non funzionerebbe. Ma dovrebbe risolvere il problema che stai riscontrando. Assicurati di configurare anche i tuoi normali server DNS come forwarder.


Potresti leggere la tua risposta e riscriverla? L'inglese in terza riga non ha senso!
OmarOthman

Riordinato. Cavolo, immagino di averlo digitato troppo velocemente senza leggerlo correttamente.
Matt

1

Il server riceve effettivamente le richieste e stai gestendo correttamente il nome host (alias)?

dopo aver aggiunto al mio file .hosts

Controlla il log del tuo server web, per vedere come è arrivata la richiesta ...

curl ha opzioni per scaricare la richiesta inviata e la risposta ricevuta, si chiama traccia, che verrà salvata in un file.

--traccia

Se ti mancano le informazioni sull'host o sull'intestazione, puoi forzare quelle intestazioni con l'opzione di configurazione.

Vorrei far funzionare la richiesta curl sulla riga di comando e quindi provare a implementarla in PHP.

l'opzione di configurazione è

-K / - config

le opzioni rilevanti in curl sono qui

--trace Abilita un dump di traccia completo di tutti i dati in entrata e in uscita, comprese le informazioni descrittive, nel file di output specificato. Usa "-" come nome del file per inviare l'output allo 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 Specifica da quale file di configurazione leggere gli argomenti di curl. Il file di configurazione è un file di testo in cui è possibile scrivere gli argomenti della riga di comando che verranno utilizzati come se fossero scritti sulla riga di comando effettiva. Le opzioni ed i loro parametri devono essere specificati sulla stessa riga del file di configurazione, separati da spazi bianchi, due punti, il segno di uguale o qualsiasi loro combinazione (tuttavia, il separatore preferito è il segno di uguale). Se il parametro deve contenere spazi vuoti, il parametro deve essere racchiuso tra virgolette. All'interno di virgolette doppie, sono disponibili le seguenti sequenze di escape: \, \ ", \ t, \ n, \ r e \ v. Una barra rovesciata che precede qualsiasi altra lettera viene ignorata. Se la prima colonna di una riga di configurazione è un" # " carattere, il resto della riga verrà considerato come un commento.

      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.

Di nuovo, sto usando PHP su Windows per recuperare una pagina su un vhost sulle stesse finestre che eseguono nginx. Ad ogni modo, ho fatto una richiesta a un vhost http://domain.loc/users/getSettings.xmle questo è ciò che access.log ha mostrato 127.0.0.1 - - [09/Aug/2010:11:42:55 -0500] "POST /users/getSettings.xml HTTP/1.1" 499 0 "-" "-"e riportato da curl Operation timed out after 10000 milliseconds with 0 bytes received Quindi immagino che cURL stia effettivamente gestendo il vhost poiché access.log mostra la richiesta. Poi di nuovo, potrebbe ora arrivare al dominio corretto ...
Xeoncross

Il "499 0" su quella riga è MOLTO significativo. Il processo ha restituito zero byte, che curl stava aspettando. e ha restituito un HTTP 499, che è uno strano risultato. chiama un altro script - che restituisce una stringa statica in risposta al post - e vedi che stai ricevendo la risposta in curl. Molti non pubblicherete i dati come vi aspettate ... e lo script potrebbe scadere in attesa della risposta. cambia anche lo script per registrare l'input in un file temporaneo e vedi che stai "ricevendo il post previsto dalla tua richiesta di curl"
George Lambert

Aggiungi hai provato a riga di comando curl, in modo da poter controllare il post e vedere la risposta del server?
George Lambert

Risposta rapida alla seconda domanda: no. Non so come accedere alla riga di comando cURL su Windows poiché è integrato in PHP e non nel terminale di Windows.
Xeoncross

1
puoi scaricare una versione da riga di comando di curl per Windows da qui curl.haxx.se/download.html
George Lambert

1

Fare una richiesta a

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

Risultato nel -Hfile di registro contenente:

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

Il mio file hosts ha il seguente aspetto:

# 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è per l'intestazione completa, non solo per l'host, quindi usa -H 'Host: project1.loc'. Inoltre, nonostante questo problema, questa richiesta sembra funzionare sull'host corretto (ottenuto correttamente dal tuo hostsfile almeno da curl sulla riga di comando). Ciò che non funziona (403) sembra un problema di autenticazione / autorizzazione, quindi il tuo server sembra bloccare queste richieste. Suggerirei di correggere la configurazione del server per questo.
Bruno

0

Per configurare host virtuali su server http Apache che non sono ancora connessi tramite DNS, mi piace usare:

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

Dove nome-host è l'indirizzo IP o il nome DNS della macchina su cui è in esecuzione il server web. Funziona bene anche per i siti https.


1
Questo post è stato inviato 10 anni fa e corretto tramite commenti, grazie per il contributo. In questo tipo di post si prega di controllare le risposte, se c'è una domanda inviare votare altrimenti inserire una nuova risposta perché potresti contrassegnare come spam.
samuhay
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.