2013-01-04 13 views
20

Krótko mówiąc, mam aplikację AJAX, która używa MVC Web API jako zaplecza. Klient jednak dzwoni z innej domeny i używa pliku proxy PHP, aby ominąć problemy z żądaniami między domenami.Jak mogę przerwać korzystanie z cURL 100 Kontynuuj?

Jednak za pomocą serwera proxy PHP Web API odpowiada na niektóre żądania za pomocą nagłówka HTTP 100 Continue, a wszelkie żądania, które otrzymają to żądanie, zabierają zbyt dużo czasu (rozmawiamy do 2 minut) i mogą również zwraca nieważną odpowiedź.

Ten appears to be a known issue with cURL a obejście jest powszechnie cytowane jako wstawianie linii poniżej, aby usunąć oczekiwać: 100 nagłówek w żądaniu cURL

Niestety, rozwiązanie wydaje się być nieuchwytny dla mnie:

$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:')); 

Ten kod działa, ale usuwa wszystkie inne nagłówki (co nie jest możliwe do zastosowania, ponieważ używam nagłówków HTTP auth do uwierzytelniania za pomocą interfejsu API). Możesz również zauważyć, że próbowałem dodać Expect: do istniejących nagłówków, ale to też mi nie pomogło.

Jak mogę zachować istniejące nagłówki, ale także uniemożliwić cURL oczekiwanie, że 100 będzie kontynuowane?

+2

'getallheaders()' nie robić to, co wydaje się, że to robi . Otrzymuje nagłówki żądań, które zostały do ​​ciebie wysłane, a nie nagłówki żądań, których użyje curl. Powinieneś potrzebować tylko 'curl_setopt ($ ch, CURLOPT_HTTPHEADER, array ('Expect:'));' line - usuń wszystko inne z powyższego kodu i powinno działać. – DaveRandom

+0

DaveRandom - właściwie to jest właśnie intencja - biorę nagłówki żądań i przekazuję je do API (zawierają one rzeczy Auth HTTP). Problem polega na tym, że cURL będzie _add_ "Expect: 100" do tych nagłówków. – jmillar

+0

Nawiązując do [this] (http://stackoverflow.com/questions/2964687/how-to-handle-100-continue-http-message) możesz spróbować dodać 'curl_setopt ($ ch, CURLOPT_FAILONERROR, TRUE);'? Mam nadzieję że to pomoże. – user1190992

Odpowiedz

19

Korzystanie $headers_new[] = 'Expect:'; działa chyba że tablicę $headers_new zawiera ciąg, który jest 'Expect: 100-continue'. W takim przypadku musisz usunąć go z tablicy, w przeciwnym razie spodziewasz się, że 100 będzie kontynuowane (logicznie).

Ponieważ w kodzie używasz getallheaders() i nie sprawdzasz, czy zawiera on nagłówek Expect: 100-continue, więc prawdopodobnie tak jest w twoim przypadku.

Oto podsumowanie dla ogólnej sytuacji (i skrypt, który go stworzył):

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 

Kod:

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

Znalazłem pokrewny, ale znacznie starszy post: http://stackoverflow.com/a/463277/367456 – hakre

0

Dzięki za skrypt, Hakre. Ponieważ musiałem to dla HTTP PUT, ja przedłużony to kawałek z następującymi wynikami:

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 

oto skrypt:

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

?>