如何阻止 cURL 使用 100 Continue?

2022-08-30 17:49:40

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

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

这似乎是 cURL 的一个已知问题,解决方法通常被引用为插入以下行以删除预期的:cURL 请求中的 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 个继续?


答案 1

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

因为在你的代码中,你使用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);

?>

推荐