设置cURL以使用本地虚拟主机


115

我总是使用Apache或Ngnix创建基于真实项目的开发站点,例如,将http://project1.loc这些站点添加到我的.hosts文件中后,浏览器就不会出现问题。

但是,当我尝试向http://project1.loc/post.json同一URL 发出cURL请求()时,除了超时我什么都没有得到。我假设cURL不在乎我的自定义主机,而是直接转到名称服务器获取其信息。

我怎样才能解决这个问题?

更新 我设置了一个自定义标头“ HOST:http://project1.loc ”,现在我收到了400个错误-但是它们是瞬时的,因此我假设cURL至少使用了hosts文件...

Answers:


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 2012年

10
值得注意的是,--resolve仅在curl 7.21.3中添加-如果您卡在较旧的主机(例如Ubuntu 10.04 LTS)上,则-H'Host ...'选项仍然是一个有用的备用。
2012年

9
虽然我同意这可能是可接受的答案(相反,如果OP进行了更改,我当然不会冒犯),说我的答案是错误的:这对当时可用的版本是正确的问题和答案产生了。这样的用户,您将不会因为阅读第一个答案而烦恼,也不会根据他们的时间戳评估答案永远不会得到最好的帮助……
Bruno 2014年

1
抱歉,布鲁诺,没有冒犯的意思。
约翰·哈特

120

编辑:虽然这是当前公认的答案,但读者约翰·哈特John Hart)可能会发现此其他答案更适合他们的需求。根据用户Ken的说法,它使用的选项是在7.21.3版本(于2010年12月发布,即此初始答案之后)中引入的。


在您编辑的问题中,您使用URL作为主机名,而仅需使用主机名。

尝试:

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

这里project1.loc只是主机名,127.0.0.1是目标的IP地址。

(如果你使用curl从库中,而不是在命令行中,请确保你不把http://Host标题中。)


1
我在使用PHP时遇到了400个错误,当我使用curl.exe手动进行请求时,我得到了服务器的默认索引,这意味着它不遵守HOST标头。
Xeoncross

我已经在带有虚拟主机的各种服务器上尝试过它,并且它可以工作(从命令行)。尝试HostHOST只是以防万一(尽管我认为它不应该区分大小写)。就像我说的,请确保您仅在Host标题中使用主机名,而不要使用其他名称(不可以http:///something以后不能使用)。您是如何设置主机文件的?
布鲁诺

在下面发布了有关执行此操作的结果的更多数据。
Xeoncross

1
正如Bruno在下面说的那样,问题可能出在我的服务器配置上,因为请求似乎正在执行并收到403错误。
Xeoncross

我在主机文件中错过了“ 127.0.0.1 myvirtualhost.localhost”,因此出现了问题。
Arvind K.

2

请使用dev.yourdomain.com指向的真实的完全限定域名(例如),127.0.0.1或尝试编辑适当的主机文件(通常在* nix环境中为/ etc / hosts)。


我在Windows上使用system32/drivers/etc/hosts
Xeoncross

您使用的是cURL的本机版本还是cygwin交叉版本?我之所以这样说,是因为我不确定每个人如何解析其DNS。本机应从 Windows的hosts文件中选取,但cygwin版本可能需要cygwin版本。无论哪种方式,都可以使用指向127.0.0.1的真实域来进行设置。
奥利

我正在使用Windows的PHP 5.3附带的本机Windows构建(以php_fastcgi运行)。
Xeoncross

2

看来这并不是一个罕见的问题。

首先检查一下

如果这样做没有帮助,则可以在Windows上安装本地DNS服务器,例如this。将Windows配置为使用localhost作为DNS服务器。可以将该服务器配置为对所需的任何伪造域具有权威性,并将所有其他请求转发到真实的DNS服务器上。

我个人认为这有点过头了,看不到为什么hosts文件不起作用。但这应该可以解决您遇到的问题。确保将普通DNS服务器也设置为转发器。


您能阅读并重写答案吗?第三行的英语没有意义!
OmarOthman'2

整理。哎呀,猜想我打的太快了,没有正确阅读。
马特

1

服务器实际上收到请求了吗,您是否在正确处理主机名(别名)?

添加到我的.hosts文件后

检查您的网络服务器日志,以了解请求是如何传入的...

curl可以选择转储发送的请求和接收到的响应,这称为跟踪,它将被保存到文件中。

- 跟踪

如果缺少主机或标头信息,则可以使用config选项强制使用这些标头。

我将在命令行上使用curl请求,然后尝试在PHP中实现。

config选项是

-K /-配置

卷曲相关的选项在这里

--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指定从哪个配置文件读取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.

同样,我在Windows上使用PHP在运行Nginx的相同Windows上的虚拟主机上获取页面。无论如何,我向虚拟主机发出了一个请求 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实际上是在处理虚拟主机,因为access.log显示了请求。再说一遍,它现在可能已经进入了正确的域...
Xeoncross

该行上的“ 499 0”非常重要。进程返回零字节-curl正在等待。并返回了HTTP 499-这是一个奇怪的结果。调用另一个脚本-返回一个静态字符串以响应该帖子-并看到您正在curl中获得响应。您中的许多人可能并没有按您期望的那样发布数据...并且脚本可能会超时等待响应。还更改了脚本以将输入记录到临时文件中,并看到您“正在从curl请求中接收预期的帖子”
George Lambert 2010年

添加您是否尝试了命令行curl-这样您就可以控制帖子并查看服务器响应?
乔治·兰伯特

快速回答第二个问题-不。我不知道如何在Windows上访问命令行cURL,因为它内置在PHP中,而不是Windows终端中。
Xeoncross

1
您可以从以下位置下载适用于Windows的curl命令行版本: curl.haxx.se/download.html
George Lambert 2010年

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)似乎是身份验证/授权问题,因此您的服务器似乎正在阻止这些请求。我建议为此修复服务器配置。
布鲁诺

0

为了在尚未通过DNS连接的Apache http服务器上设置虚拟主机,我喜欢使用:

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

其中,主机名是运行Web服务器的计算机的IP地址或DNS名称。这也适用于https-Sites。


1
该帖子于10年前发送,并通过评论进行了固定,感谢您的贡献。在此类帖子中,请检查答案,如果存在asnwear投票,否则请发布新答案,因为您可能被标记为垃圾邮件。
samuhay
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.