【问题标题】:PHP Curl timeout, but unix Curl don'tPHP Curl 超时,但 unix Curl 没有
【发布时间】:2011-02-24 22:04:19
【问题描述】:

--- 底部更新,与 CURLOPT_COOKIE 相关 --

我正在我的本地机器 ( 192.168.1.103 ) 上进行开发,并且我有一个 PHP 脚本,它通过 CURL 调用来获取标题和远程脚本返回的内容。

我已经安装了 2 个必须返回其内容的远程脚本副本:
- 一个在我的本地机器上,在同一个虚拟主机下。 (http://192.168.1.103/test/output_script.php)
- 一个在远程服务器上。 (http://site.com/text/outputscript.php)

当我尝试从远程服务器获取内容时,CURL 脚本运行良好,但在尝试从本地服务器获取内容时完全超时。

PHP CURL 的详细说明是:

* About to connect() to 192.168.1.103 port 80 (#0)
*   Trying 192.168.1.103... * connected
* Connected to 192.168.1.103 (192.168.1.103) port 80 (#0)
> GET /app/getContent HTTP/1.1

Host: 192.168.1.103

Accept: */*

Cookie: PHPSESSID=u8spbervheh3tcrv62gcnc2j72



* Operation timed out after 5001 milliseconds with 0 bytes received
* Closing connection #0

请注意,URI 被以下 .htaccess 文件(在两个位置)重写:

RewriteEngine on

RewriteBase /cms/client1/public_html

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

另外请注意,我已经激活了重写日志并比较了请求,以确保 mod_rewrite 操作在所有情况下都完全相同。 (我 100% 确定这不是重写问题)

如果我尝试在 Ubuntu 下使用 CURL 应用程序获取文件,它运行良好:

$ curl -v --cookie PHPSESSID=u8spbervheh3tcrv62gcnc2j72 http://192.168.1.103/app/getContent
* About to connect() to 192.168.1.103 port 80 (#0)
*   Trying 192.168.1.103... connected
* Connected to 192.168.1.103 (192.168.1.103) port 80 (#0)
> GET /app/getContent HTTP/1.1
> User-Agent: curl/7.21.0 (i686-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.18
> Host: 192.168.1.103
> Accept: */*
> Cookie: PHPSESSID=u8spbervheh3tcrv62gcnc2j72
> 
< HTTP/1.1 403 Forbidden
< Date: Thu, 24 Feb 2011 21:40:17 GMT
< Server: Apache/2.2.16 (Ubuntu)
< X-Powered-By: PHP/5.3.3-1ubuntu9.3
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Vary: Accept-Encoding
< Content-Length: 82
< Content-Type: text/html; charset=UTF-8
< 
* Connection #0 to host 192.168.1.103 left intact
* Closing connection #0
WT_AUTH non défini. (strictement aucune authentification actuellement en session)

403 错误和 WT_AUTH 内容是我期望收到的,而不是我在 PHP 中遇到的超时。
如果在远程服务器上使用 php curl,我收到的结果也是相同的(想要的和正确的):

* About to connect() to site.com port 80 (#0)
*   Trying 123.123.123.123... * connected
* Connected to site.com (123.123.123.123) port 80 (#0)
> GET /app/getContent HTTP/1.1

Host: site.com

Accept: */*

Cookie: PHPSESSID=u8spbervheh3tcrv62gcnc2j72



< HTTP/1.1 403 Forbidden

< Date: Thu, 24 Feb 2011 21:45:30 GMT

< Server: Apache/2.2.16 (Debian) DAV/2 SVN/1.6.12 mod_fcgid/2.3.6

< Expires: Thu, 19 Nov 1981 08:52:00 GMT

< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

< Pragma: no-cache

< Content-Length: 28

< Content-Type: text/html; charset=UTF-8

< 

* Connection #0 to host site.com left intact
* Closing connection #0

如果我在浏览器中直接访问 192.168.1.103/app/getContent 也会得到同样的结果。

最后,我还通过将日志放入其中来确保 getContent 脚本正常工作。奇怪的是,如果我在 16:45:00 开始请求,并且超时发生在 16:45:05,那么 getContent 脚本中记录的数据将在 16:45:05 出现。因此,就像 CURL 在“打开”状态下保持连接一样。并且当连接关闭时,允许启动 php 脚本。

知道我的它在本地不起作用吗?

如果你想看一下 PHP 代码,下面是相关部分:

$ressource = curl_init();
curl_setopt($ressource, CURLOPT_URL, $destinationUrl);
curl_setopt($ressource, CURLOPT_VERBOSE, true);
$handle = fopen(FRAMEWORK_ROOT . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . 'curl_debug.txt', 'w');
curl_setopt($ressource, CURLOPT_STDERR, $handle);

// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ressource, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ressource, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ressource, CURLOPT_RETURNTRANSFER, TRUE); //retourn content
curl_setopt($ressource, CURLOPT_HEADER, TRUE); //get HTTP headers
curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . session_id());
curl_setopt($ressource, CURLOPT_TIMEOUT, 5);


echo "\n<br />" . date('Y/m/d H:i:s');
$httpResponse = curl_exec($ressource);

echo "\n<br />" . date('Y/m/d H:i:s');
if(curl_errno($ressource) != 0)
     throw new Core_Exc_Def(curl_error($ressource)); // WILL THROW AN ERROR ON 192.168.1.103, BUT NOT ON THE REMOTE SITE.

有趣的事实:在添加 TIMEOUT 之前,加载是无限的。本地站点没有响应,甚至其他页面也没有响应。我需要重新启动 apache 服务器才能再次访问该站点...

更新:
如果我评论该行:

curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . session_id());

它正在“工作”(它会导致另一个问题,但与超时无关)。 两个脚本都在同一个虚拟主机上,并且共享同一个会话,但这不应该创建一个 CURL TimeOut ?!

【问题讨论】:

    标签: php curl timeout


    【解决方案1】:

    发生这种情况是因为会话被锁定以进行写入。当您尝试将脚本连接到具有相同 session_id 的同一服务器时,第二个脚本会一直等待,直到该会话锁定被释放。

    您需要更改您在请求中发送的session_id

    变化:

    curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . session_id());
    

    收件人:

    curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . md5(session_id() . mktime()));
    

    【讨论】:

    • curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . md5(session_id() . time()));
    猜你喜欢
    • 2015-01-14
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 2023-03-18
    • 1970-01-01
    相关资源
    最近更新 更多