Подтвердить что ты не робот

Как я могу остановить cURL при использовании 100 Continue?

Итак, длинный рассказ, у меня есть приложение AJAX, которое использует MVC Web API в качестве задней части. Однако клиент звонит из другого домена и использует файл прокси-сервера PHP, чтобы обойти проблемы междоменного запроса.

Однако, используя прокси-сервер PHP, веб-API отвечает на определенные запросы с заголовком 100 Continue HTTP, и любые запросы, которые получают это обратно, требуют чрезмерного времени (мы говорим до 2 минут или около того) и можем также возвращает недействительный ответ.

Этот представляет собой известную проблему с cURL, и обходной путь обычно упоминается как вставка строки ниже, чтобы удалить заголовок expect: 100 в запросе cURL

К сожалению, решение кажется мне неуловимым:

$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-заголовки auth для аутентификации с помощью API). Вы также можете заметить, что я попытался добавить Expect: в существующие заголовки, но это тоже мне не помогло.

Как я могу сохранить существующие заголовки, но также запретить cURL ожидать, что 100 продолжит?

4b9b3361

Ответ 1

Использование $headers_new[] = 'Expect:'; работает, если массив $headers_new не содержит строку 'Expect: 100-continue'. В этом случае вам нужно удалить его из массива, иначе он будет ожидать, что 100 продолжит (логически).

Потому что в вашем коде вы используете getallheaders(), и вы не проверяете, содержит ли он заголовок Expect: 100-continue, так что это, вероятно, случай в вашем случае.

Вот сводка общей ситуации (и созданного ею script):

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

Спасибо за script, Хакре. Поскольку мне это нужно для 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

Здесь script:

<?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);

?>