tags:

views:

255

answers:

5

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

+2  A: 

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).

Oli
I develop on windows using `system32/drivers/etc/hosts`
Xeoncross
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.
Oli
I'm using the native windows build included with PHP 5.3 for windows (Running as php_fastcgi).
Xeoncross
+1  A: 

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.

--trace

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

-K/--config

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.
George Lambert
Again, I'm using PHP on windows to fetch a page on a vhost on the same windows running nginx. Anyway, I made a request to a vhost `http://domain.loc/users/getSettings.xml` and this is what the access.log showed `127.0.0.1 - - [09/Aug/2010:11:42:55 -0500] "POST /users/getSettings.xml HTTP/1.1" 499 0 "-" "-"` and curl reported `Operation timed out after 10000 milliseconds with 0 bytes received`So I guess that cURL is actually handling the vhost since the access.log shows the request. Then again, it might now be making it to the correct domain...
Xeoncross
The "499 0" on that line is VERY significant. The process returned zero bytes - which curl was waiting for. and returned an HTTP 499 - which is a strange result. call another script - that returns a static string in response to the post - and see that you are getting the response in curl. You many not be posting the data as you expect... and the script may be timing out waiting for the response. also change the script to log the input to a temp file, and see that you are "receiving the expected post from your curl request"
George Lambert
Add did you try command line curl - so that you could control the post and see the server response?
George Lambert
Quick answer to second question - no. I don't know how to access the command line cURL on windows since it's built into PHP and not the windows terminal.
Xeoncross
you can download a command line version of curl for windows from here http://curl.haxx.se/download.html
George Lambert
Yep, straight curl works great on my PC. Thanks for the download link. curl.exe is *really* useful! No trouble at all with making the same requests PHP fails at. It must be something PHP is doing before to alter how cURL performs or something.
Xeoncross
So the question is - "what is the PHP actually sending" and why is it failing. Can you change your script to save the contents of the "actual" request to a file, and then look at the file contents... your post data may be getting malformed.
George Lambert
I posted the results below.
Xeoncross
+1  A: 

It seems that this is not an uncommon problem.

Check this first. http://support.microsoft.com/kb/172218

I that doesn't help upi could use this method" Install a local dns server on windows. such as: http://posadis.sourceforge.net/sans

Use this instead of the hosts file for resolution. Set windows to point to this local DNS server only tell it what domains it will be authoritive for, and you should be away.

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 he problem you're having. Make sure you set up your normal dns servers as forwarders as well.

Matt H
+2  A: 

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

Try:

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.)

Bruno
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.
Xeoncross
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?
Bruno
Posted more data about the results of doing this below.
Xeoncross
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.
Xeoncross
A: 

Making a request to

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

Resulted in the -H log file containing:

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

My hosts file looks like:

# 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
`-H` is for the full header, not just host, so use `-H 'Host: project1.loc'`. In addition, despite this problem, this request seems to work on the correct host (obtained correctly from your `hosts` file by curl on the command line at least). What's not working (403) seems like an authentication/authorization issue, so your server seems to be blocking these requests. I'd suggest fixing the server configuration for this.
Bruno