【问题标题】:How can I stop cURL from using 100 Continue?如何阻止 cURL 使用 100 Continue?
【发布时间】:2012-12-18 23:34:10
【问题描述】:

所以,长话短说,我有一个使用 MVC Web API 作为后端的 AJAX 应用程序。然而,客户端从不同的域调用并使用 PHP 代理文件来解决跨域请求问题。

但是,使用 PHP 代理,Web API 会使用 100 Continue HTTP 标头响应某些请求,并且任何获取此信息的请求都需要花费过多的时间才能完成(我们说的最多 2 分钟左右)并且可以也返回一个无效的响应。

这个appears to be a known issue with cURL 和解决方法通常被引用为插入以下行以删除 cURL 请求中的 expect: 100 标头

不幸的是,解决方案对我来说似乎是难以捉摸的:

$headers = getallheaders();
$headers_new = "";
foreach($headers as $title => $body) {
    $headers_new[] = $title.": ".$body;
}
//$headers_new[] = 'Expect:';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers_new);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:') );

此代码有效,但删除了所有其他标头(这对我来说不可行,因为我使用 HTTP 基本身份验证标头通过 API 进行身份验证)。 您可能还注意到我尝试将 Expect: 添加到现有标题中,但这对我也没有帮助。

如何维护现有的标头,同时防止 cURL 期望 100 继续?

【问题讨论】:

  • getallheaders() 并不像您认为的那样做。它获取发送给您的请求标头,而不是 curl 将使用的请求标头。您应该只需要 curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:') ); 行 - 从上面的代码中删除所有其他内容,它应该可以工作。
  • DaveRandom - 实际上这正是我的意图 - 我正在获取请求标头并将它们传递给 API(它们包括 HTTP Auth 的东西)。问题是 cURL 会将Expect: 100 添加到这些标题中。
  • 引用this 可以尝试添加curl_setopt($ch, CURLOPT_FAILONERROR, TRUE); 吗?希望这会有所帮助。
  • 问题是,这没有被归类为错误 - 它实际上并没有失败!

标签: php jquery curl proxy


【解决方案1】:

使用$headers_new[] = 'Expect:'; 确实有效除非$headers_new 数组包含'Expect: 100-continue' 的字符串。在这种情况下,您需要将其从数组中删除,否则它将期望 100 继续(逻辑上)。

因为在您的代码中您使用 getallheaders() 并且您没有检查它是否已经包含 Expect: 100-continue 标头,所以您的情况可能就是这种情况。

以下是一般情况的摘要(以及创建它的脚本):

PHP Curl HTTP/1.1 100 Continue and CURLOPT_HTTPHEADER

GET request ..........................................: Continue: No
GET request with empty header ........................: Continue: No
POST request with empty header .......................: Continue: Yes
POST request with expect continue explicitly set .....: Continue: Yes
POST request with expect (set to nothing) as well ....: Continue: Yes
POST request with expect continue from earlier removed: Continue: No

代码:

<?php

$ch = curl_init('http://www.iana.org/domains/example/');

function curl_exec_continue($ch) {
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $result   = curl_exec($ch);
    $continue = 0 === strpos($result, "HTTP/1.1 100 Continue\x0d\x0a\x0d\x0a");
    echo "Continue: ", $continue ? 'Yes' : 'No', "\n";

    return $result;
}

echo "GET request ..........................................: ", !curl_exec_continue($ch);

$header = array();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
echo "GET request with empty header ........................: ", !curl_exec_continue($ch);

curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('hello'));
echo "POST request with empty header .......................: ", !curl_exec_continue($ch);

$header[] = 'Expect: 100-continue';
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
echo "POST request with expect continue explicitly set .....: ", !curl_exec_continue($ch);

$header[] = 'Expect:';
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
echo "POST request with expect (set to nothing) as well ....: ", !curl_exec_continue($ch);

unset($header[0]);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
echo "POST request with expect continue from earlier removed: ", !curl_exec_continue($ch);

【讨论】:

    【解决方案2】:

    谢谢你的剧本,哈克。因为我需要这个 HTTP PUT,所以我用以下结果对其进行了一些扩展:

    GET request ..........................................: Continue: No
    GET request with empty header ........................: Continue: No
    POST request with empty header .......................: Continue: Yes
    POST request with expect continue explicitly set .....: Continue: Yes
    POST request with expect (set to nothing) as well ....: Continue: Yes
    POST request with expect continue from earlier removed: Continue: No
    PUT request with empty header ........................: Continue: Yes
    PUT request with expect continue explicitly set ......: Continue: Yes
    PUT request with expect (set to nothing) as well .....: Continue: Yes
    PUT request with expect continue from earlier removed : Continue: No
    DELETE request with empty header .....................: Continue: Yes
    DELETE request with expect continue explicitly set ...: Continue: Yes
    DELETE request with expect (set to nothing) as well ..: Continue: Yes
    DELETE request with expect continue from earlier removed : Continue: No
    

    这是脚本:

    <?php 
    
    $ch = curl_init('http://www.iana.org/domains/example/');
    
    function curl_exec_continue($ch) {
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result   = curl_exec($ch);
        $continue = 0 === strpos($result, "HTTP/1.1 100 Continue\x0d\x0a\x0d\x0a");
        echo "Continue: ", $continue ? 'Yes' : 'No', "\n";
    
        return $result;
    }
    
    // --- GET
    
    echo "GET request ..........................................: ", !curl_exec_continue($ch);
    
    $header = array();
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "GET request with empty header ........................: ", !curl_exec_continue($ch);
    
    // --- POST
    
    curl_setopt($ch, CURLOPT_POST, TRUE);
    
    curl_setopt($ch, CURLOPT_POSTFIELDS, array('hello'));
    echo "POST request with empty header .......................: ", !curl_exec_continue($ch);
    
    $header[] = 'Expect: 100-continue';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "POST request with expect continue explicitly set .....: ", !curl_exec_continue($ch);
    
    $header[] = 'Expect:';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "POST request with expect (set to nothing) as well ....: ", !curl_exec_continue($ch);
    
    unset($header[0]);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "POST request with expect continue from earlier removed: ", !curl_exec_continue($ch);
    
    // --- PUT
    
    curl_setopt($ch, CURLOPT_PUT, TRUE);
    
    $header = array();
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "PUT request with empty header ........................: ", !curl_exec_continue($ch);
    
    $header[] = 'Expect: 100-continue';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "PUT request with expect continue explicitly set ......: ", !curl_exec_continue($ch);
    
    $header[] = 'Expect:';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "PUT request with expect (set to nothing) as well .....: ", !curl_exec_continue($ch);
    
    unset($header[0]);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "PUT request with expect continue from earlier removed : ", !curl_exec_continue($ch);
    
    // --- DELETE
    
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
    
    $header = array();
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "DELETE request with empty header .....................: ", !curl_exec_continue($ch);
    
    $header[] = 'Expect: 100-continue';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "DELETE request with expect continue explicitly set ...: ", !curl_exec_continue($ch);
    
    $header[] = 'Expect:';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "DELETE request with expect (set to nothing) as well ..: ", !curl_exec_continue($ch);
    
    unset($header[0]);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    echo "DELETE request with expect continue from earlier removed : ", !curl_exec_continue($ch);
    
    ?>
    

    【讨论】:

      【解决方案3】:

      要删除标题 101,请继续使用此

      curl_setopt($ch, CURLOPT_HTTPHEADER,array("Expect:"));
      

      【讨论】:

      • 它甚至适用于命令行 curl。
      猜你喜欢
      • 2013-11-17
      • 1970-01-01
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      相关资源
      最近更新 更多