web-dev-qa-db-ja.com

cContinが100 Continueを使用しないようにするにはどうすればよいですか?

つまり、簡単に言えば、AJAX MVC Web APIをバックエンドとして使用するアプリケーションがあります。ただし、クライアントは別のドメインから呼び出し、PHP =クロスドメインリクエストの問題を回避するためのプロキシファイル。

ただし、PHPプロキシを使用すると、Web APIは100 Continue HTTPヘッダーとこれを取り戻すリクエストは、完了するまでに非常に時間がかかり(最大2分程度)、無効な応答が返されることもあります。

これは 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:') );

このコードは機能しますが、他のすべてのヘッダーを削除します(APIで認証するためにHTTP基本認証ヘッダーを使用しているため、これは私には機能しません)。また、Expect:を既存のヘッダーに追加しましたが、これも役に立ちませんでした。

既存のヘッダーを維持しながら、cURLが100の継続を期待できないようにするにはどうすればよいですか?

21
jmillar

_$headers_new[] = 'Expect:';_を使用しても機能しますnless _$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);
_
21
hakre

台本をありがとう、ハクレ。これは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);

?>
1
Xenonite