CURL php 代码返回 http_code=0 和来自服务器消息的空回复


CURL php code returns http_code=0 and empty reply from server message

我在多个站点/服务器上运行相同的代码。 2天前,代码开始在其中一台服务器上返回http_code = 0和错误消息"来自服务器的空回复"。

谁能阐明为什么特定的服务器有一天会工作,然后第二天就不工作了? 我已经向ISP提交了一张票证,解释了这个问题,但他们似乎找不到问题所在(还)。

我想问题真的是,服务器上会/可以更改什么来阻止它工作?

有趣的是,我引用的网址在返回错误的服务器上没有被触及。 如果我更改 url 以指向不存在的内容,则会返回相同的错误。 因此,服务器似乎总共拒绝了CURL POST引用。 我目前有其他 CURL 脚本正在访问这些问题站点,这些站点仍在工作,但它们中没有 POST 选项。

该问题肯定与此服务器上的CURL POST请求有关,并且它们几乎立即被拒绝。

在有问题的服务器上,我有15 +单独的帐户,每个帐户都返回相同的结果,因此我认为我没有更改任何内容,因为我知道在出现此问题时,我没有对所有站点进行任何大规模更改。 在我在其他地方托管的其他 6 个站点中,使用完全相同的代码仍然运行良好。

我已经尝试了我读过的帖子中的各种组合/更改选项,但没有什么真正不同,工作站点仍然有效,非工作站点仍然不起作用。

function sendWSRequest($url, $xml) {
//  $headers[] = 'Content-Type: application/xml; charset=utf-8';
    $headers[] = 'Content-Type: text/xml; charset=utf-8';
    $headers[] = 'Content-Length: ' . strlen($xml);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HEADER, true);
//  curl_setopt($ch, CURLINFO_HEADER_OUT, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
//  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
    $result = curl_exec($ch);
    if($result===false) {
        print 'error with curl - '.curl_error($ch).'<br />';
    }
    $info = curl_getinfo($ch);
    curl_close($ch);
    return $result;
}

任何帮助将不胜感激。

编辑根据进一步的调查进行总结,当脚本出错时,服务器访问日志中不会记录任何内容。 因此,在授予/记录访问权限之前,似乎包含 POST 选项的 CURL 请求被拒绝......

干杯

格雷格·

我知道

这是一个古老的线程,但我找到了一个解决方案,可以省去别人的头痛:

我刚刚开始在GoDaddy托管的一个网站上遇到这个确切的问题,该网站直到最近才工作。为了调查这个问题,我创建了一个HTML页面,其中包含一个表单,其中包含通过cURL在POST数据中提交的相同字段。

浏览器提交的 HTML 表单正常工作,而 cURL POST 导致Empty reply from server错误。因此,我检查了浏览器提交的标头与 cURL 提交的标头之间的区别,在我的开发系统上使用 PHP apache_request_headers() 函数,其中 cURL 和浏览器提交都有效。

一旦我将浏览器提交的"User-Agent"标头添加到cURL POST,问题站点就会按预期工作,而不是返回空回复:

CURLOPT_HTTPHEADER =>
      array("User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0")

我没有尝试其他/更简单的用户代理标头,因为这个快速修复解决了我的问题。

根据 PHP 手册,上传应该被编码

CURLOPT_POSTFIELDS 要在 HTTP"POST"操作中发布的完整数据。 [...]此参数可以是 作为 urlencoding 字符串传递,例如"para1=val1&para2=val2&..."或作为 字段名称为键,字段数据为值的数组。如果值 是一个数组,内容类型标头将设置为 多部分/表单数据。从 PHP 5.2.0 开始,如果文件,值必须是数组 以 @ 前缀传递给此选项。从 PHP 5.5.0 开始,@ 前缀已弃用,可以使用 CURLFile 发送文件。

所以你可以尝试

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'xml=' . urlencode($xml));

看看会发生什么。或者,无论如何,从一个空的或非常简单的 FIELD 开始,看看它是否至少到达目标服务器。

更新

我已经在测试机器上检查了此设置,它可以工作。在这一点上,问题可能根本不是PHP或cURL端。您能否请求最近几天该机器和网络上的软件/硬件更新列表?

否则,我会尝试捕获传出流量,以确定请求是否离开服务器(问题介于两者之间,例如配置错误的防火墙:因此我在更改列表中包含"硬件"),或者根本不离开服务器。在后一种情况下,罪魁祸首可能是:

  • 对 cURL 库的更新
  • 对 PHP cURL 模块和/或 PHP 二进制文件的更新
  • "软件"防火墙规则的更新
  • 对辅助网络库的更新(不太可能;它们应该是HTTP无关的,并且不能区分POST和GET或HEAD)

好吧,事实证明,一个相当不情愿的主机重新编译了 Apache2 和 PHP,这已经解决了这个问题。

主持人声称(他们对我的支持票证的开场白)在问题发生时没有对 Apache2 或 PHP 进行更新。

该行为是这样的,它甚至没有确认包含 POST 命令的 CURL 请求。 从未到达目标 URL。

非常感谢所有提供建议的人。 特别是Isemi,他不遗余力地寻找解决方案。