Set cURL to use local virtual hosts

Using Apache or Ngnix I always create development sites based on real projects such as http://project1.loc which, after adding to my .hosts file, the browser has no problem using. However, when I attempt to make a cURL request ( http://project1.loc/post.json ) to that same URL I never get anything but a timeout. I'm assuming cURL doesn't care about my custom hosts and goes straight to a name server for it's info. How can I fix this? UPDATE I set a custom header "HOST: http://project1.loc" and now I am getting 400 errors - but they are instantaneous so I'm assuming that cURL is at least using the hosts file.

asked Aug 2, 2010 at 18:14 56.8k 80 80 gold badges 268 268 silver badges 370 370 bronze badges

7 Answers 7

Actually, curl has an option explicitly for this: --resolve

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

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

What's the difference, you ask?

Among others, this works with HTTPS. Assuming your local server has a certificate for yada.com , the first example above will fail because the yada.com certificate doesn't match the 127.0.0.1 hostname in the URL.

The second example works correctly with HTTPS.

In essence, passing a "Host" header via -H does hack your Host into the header set, but bypasses all of curl's host-specific intelligence. Using --resolve leverages all of the normal logic that applies, but simply pretends the DNS lookup returned the data in your command-line option. It works just like /etc/hosts should.

Note --resolve takes a port number, so for HTTPS you would use

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

answered Apr 18, 2012 at 21:43 5,848 2 2 gold badges 21 21 silver badges 12 12 bronze badges

This is killing me - can someone please mark this as the right answer? It's much newer than the answer, so doesn't have the votes .. but the accepted answer is wrong (ie, only works for certain situations) =(

Commented Aug 2, 2012 at 16:50

This is indeed a great answer, and received my vote. Only Xenocross can mark an answer as accepted. In time others will likely come here and gradually vote yours higher.

Commented Oct 19, 2012 at 17:50

Worth noting that --resolve was only added in curl 7.21.3 - if you're stuck on an older host (eg Ubuntu 10.04 LTS) then the -H 'Host. ' option is still a useful fallback.

Commented Nov 21, 2012 at 10:20

While I agree this probably should be the accepted answer (and I would certainly not take offence if the OP changed it, on the contrary), saying that my answer is wrong isn't right: it is correct for the versions available at the time the question and answer was produced. SO users you can't be bothered reading past the first answer and also evaluate answers based on their timestamps will never get the best help.

Commented Oct 26, 2014 at 14:36 Sorry, Bruno, no offense meant. Commented Nov 10, 2014 at 17:06

EDIT: While this is currently accepted answer, readers might find this other answer by user John Hart more adapted to their needs. It uses an option which, according to user Ken, was introduced in version 7.21.3 (which was released in December 2010, i.e. after this initial answer).

In your edited question, you're using the URL as the host name, whereas it needs to be the host name only.

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

where project1.loc is just the host name and 127.0.0.1 is the target IP address.

(If you're using curl from a library and not on the command line, make sure you don't put http:// in the Host header.)

1 1 1 silver badge answered Aug 11, 2010 at 12:51 122k 32 32 gold badges 275 275 silver badges 381 381 bronze badges

I'm getting 400 errors with PHP and when I manually make the request with curl.exe I get the default index of the server which means it's not respecting the HOST header.

Commented Aug 11, 2010 at 15:29

I've tried it on various servers with virtual hosts, and it works (from the command line). Try Host not HOST just in case (although I think it shouldn't be case-sensitive). As I said, make sure you're using only the hostname in the Host header, nothing else (no http:// and no /something after). How did you set up your hosts file?

Commented Aug 11, 2010 at 15:37 Posted more data about the results of doing this below. Commented Aug 11, 2010 at 15:44

As Bruno said below, the problem is probably just my server config as the request seems to be making it and receiving a 403 error.

Commented Aug 11, 2010 at 16:21 I missed "127.0.0.1 myvirtualhost.localhost" in hosts file hence the problem. Commented Nov 20, 2015 at 7:39

For setting up virtual hosts on Apache http-servers that are not yet connected via DNS, I like to use:

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

Where host-name ist the IP address or the DNS name of the machine on which the web-server is running. This also works well for https-Sites.

answered May 7, 2020 at 10:43 51 1 1 silver badge 3 3 bronze badges

This post was send 10 years ago and fixed via comments, thanks for contribution. In this kind of posts please check for answers, if there is an asnwear send up vote else post new answer because you could marked as spam.

Commented May 7, 2020 at 20:29

Interesting point. Old answers that have visibility (and are still pretty ok), may bury newer answers that aren't that bad either. A problem of vote/credit/reputation based websites. Thank you for your suggestion, --connect-to works indeed

Commented Nov 7, 2022 at 17:02

Either use a real fully qualified domain name (like dev.yourdomain.com ) that pointing to 127.0.0.1 or try editing the proper hosts file (usually /etc/hosts in *nix environments).

answered Aug 2, 2010 at 18:20 239k 65 65 gold badges 225 225 silver badges 303 303 bronze badges I develop on windows using system32/drivers/etc/hosts Commented Aug 2, 2010 at 18:26

Are you using the native build of cURL or some cygwin cross-build? I say this because I'm not sure how each resolve their DNS. The native should pick up from Windows' hosts file but a cygwin version might want a cygwin version. Either way, using a real domain pointing to 127.0.0.1 would work however things are set up.

Commented Aug 4, 2010 at 21:19 I'm using the native windows build included with PHP 5.3 for windows (Running as php_fastcgi). Commented Aug 5, 2010 at 15:42

It seems that this is not an uncommon problem.

If that doesn't help, you can install a local DNS server on Windows, such as this. Configure Windows to use localhost as the DNS server. This server can be configured to be authoritative for whatever fake domains you need, and to forward requests on to the real DNS servers for all other requests.

I personally think this is a bit over the top, and can't see why the hosts file wouldn't work. But it should solve the problem you're having. Make sure you set up your normal DNS servers as forwarders as well.

1,728 2 2 gold badges 19 19 silver badges 37 37 bronze badges answered Aug 10, 2010 at 0:24 38.3k 49 49 gold badges 191 191 silver badges 300 300 bronze badges Could you please read your own answer and rewrite it? The English in the third line makes no sense! Commented Feb 2, 2017 at 19:21 Tidied. Gee, guess I typed that too fast without reading it properly. Commented Feb 2, 2017 at 19:31

Does the server actually get the requests, and are you handling the host name (alias) properly?

after adding to my .hosts file

Check your webserver log, to see how the request came in.

curl has options to dump the request sent, and response received, it is called trace, which will will be saved to a file.

If you are missing host or header information - you can force those headers with the config option.

I would get the curl request working on the command line, and then try to implement in PHP.

the config option is

the options that are relevant in curl are here

--trace Enables a full trace dump of all incoming and outgoing data, including descriptive information, to the given output file. Use "-" as filename to have the output sent to 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 Specify which config file to read curl arguments from. The config file is a text file in which command line arguments can be written which then will be used as if they were written on the actual command line. Options and their parameters must be specified on the same config file line, separated by whitespace, colon, the equals sign or any combination thereof (however, the preferred separa- tor is the equals sign). If the parameter is to contain whitespace, the parameter must be enclosed within quotes. Within double quotes, the following escape sequences are available: \, \", \t, \n, \r and \v. A backslash preceding any other letter is ignored. If the first column of a config line is a '#' character, the rest of the line will be treated as a comment. Only write one option per physical line in the config file.

 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.