1

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

任何人都可以解释为什么某个特定的服务器会在一天工作,然后在下一天不工作?我已经向 ISP 提交了一张票,解释了这个问题,但他们似乎无法找到问题所在(还)。

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

有趣的是我引用的 url 在返回错误的服务器上没有被触及。如果我将 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 请求被拒绝...

干杯

格雷格·J

4

3 回答 3

5

我知道这是一个旧线程,但我找到了一个可以让其他人头疼的解决方案:

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

浏览器提交的 HTML 表单有效,而 cURL POST 导致Empty reply from server错误。因此,我在我的开发系统上使用 PHP 函数检查了浏览器提交的标头与 cURL 提交的标头之间的区别,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")

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

于 2014-07-28T07:10:29.900 回答
2

根据PHP 手册,上传应该是urlencoded

CURLOPT_POSTFIELDS 要在 HTTP“POST”操作中发布的完整数据。[...] 此参数可以作为 urlencoded 字符串(如 'para1=val1¶2=val2&...')或作为字段名称作为键和字段数据作为值的数组传递。如果 value 是一个数组,则 Content-Type 标头将设置为 multipart/form-data。从 PHP 5.2.0 开始,如果文件以 @ 前缀传递给此选项,则 value 必须是数组。从 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)
于 2013-09-12T21:56:37.993 回答
0

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

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

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

非常感谢所有提供建议的人。尤其是伊塞米,他竭尽全力寻找解决方案。

于 2013-09-30T01:09:18.630 回答