2012-10-23 10 views
5

Zauważyłem "dziwne" zachowanie php CURL, które wysyła mi orzechy. Zasadniczo to, co robię, polega na wykonywaniu połączenia uwierzytelnionego z curl. Oto wyciąg z mojego kodu:php curl z podsumowaniem zwraca dwie odpowiedzi

curl_setopt($this->c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); 
curl_setopt($this->c, CURLOPT_USERPWD, $username . ":" . $password); 

To działa dobrze a serwer rzeczywiście wraca z „Tak, pod warunkiem że prawo poświadczeń” rodzaju wiadomości. Tylko kłopot polega na tym, że surowa odpowiedź http jest nieco dziwna, ponieważ w rzeczywistości zawiera 2 odpowiedzi zamiast jednej. Oto co curl_exec ($ this-> c) wypluwa:

HTTP/1.0 401 Unauthorized 
Date: Tue, 23 Oct 2012 08:41:18 GMT 
Server: Apache/2.2.20 (Ubuntu) 
X-Powered-By: PHP/5.3.6-13ubuntu3.9 
WWW-Authenticate: Digest realm="dynamikrest-testing",qop="auth",nonce="5086582e95104",opaque="4b24e95490812b28b3bf139f9fbc9a66" 
Vary: Accept-Encoding 
Content-Length: 9 
Connection: close 
Content-Type: text/html 

HTTP/1.1 200 OK 
Date: Tue, 23 Oct 2012 08:41:18 GMT 
Server: Apache/2.2.20 (Ubuntu) 
X-Powered-By: PHP/5.3.6-13ubuntu3.9 
Vary: Accept-Encoding 
Content-Length: 9 
Connection: close 
Content-Type: text/html 

"success" 

Nie rozumiem dlaczego to zawiera pierwszą odpowiedź od serwera (ten, w którym stwierdza się, że wymaga uwierzytelnienia).

Czy ktoś może rzucić nieco światła na tę kwestię? Jak uniknąć kumulacji odpowiedzi?

Cheers

+0

ja * * dokładnie ten sam problem. Ten komentarz nie dodaje nic do rezolucji, ale chciałem pokazać ludziom, że to nie jest całkowicie odosobniony problem. – Hezad

+0

W końcu użyłem funkcji zawijania wierszy poleceń PHP exec(). To daleki od ideału, ale działa dobrze na prototypowanie: exec ('curl --digest -u the_login: the_password the_url', $ params); Ciągle szukam i czekam na odpowiedź. – Hezad

+0

Właśnie przetestowałem to z wireshark i podobną konfiguracją, wygląda na to, że curl uruchamia 2 żądania podczas używania uwierzytelniania digest, a pierwsze jest bez żadnego uwierzytelnienia. Pytanie brzmi teraz, dlaczego linia poleceń curl ignoruje tę odpowiedź i php_curl ją dołącza. – gries

Odpowiedz

2

Wygląda curl ma ten sam problem w przypadku korzystania z opcji -I dla nagłówków:

curl -I --digest -u root:somepassword http://localhost/digest-test/ 

Powroty:

HTTP/1.1 401 Authorization Required 
Date: Fri, 31 May 2013 13:48:35 GMT 
Server: Apache/2.2.22 (Ubuntu) 
WWW-Authenticate: Digest realm="Test Page", nonce="9RUL3wPeBAA=52ef6531dcdd1de61f239ed6dd234a3288d81701", algorithm=MD5, domain="/digest-test/ http://localhost", qop="auth" 
Vary: Accept-Encoding 
Content-Type: text/html; charset=iso-8859-1 

HTTP/1.1 200 OK 
Date: Fri, 31 May 2013 13:48:35 GMT 
Server: Apache/2.2.22 (Ubuntu) 
Authentication-Info: rspauth="4f5f8237e9760f777255f6618c21df4c", cnonce="MTQ3NDk1", nc=00000001, qop=auth 
Vary: Accept-Encoding 
Content-Type: text/html;charset=UTF-8 
X-Pad: avoid browser bug 

To tylko dostać drugi nagłówek cię może spróbować tego (niezbyt optymalne rozwiązanie):

<?php 

$ch = curl_init(); 
     // set url 
curl_setopt($ch, CURLOPT_URL, "http://localhost/digest-test/"); 
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); 
curl_setopt($ch, CURLOPT_USERPWD, "root:test"); 


// first authentication with a head request 
curl_setopt($ch, CURLOPT_NOBODY, 1); 
curl_exec($ch);   

// the get the real output 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_HTTPGET, 1); 
$output = curl_exec($ch); 
echo $output; 
0

Wpadłem na ten sam problem i myślę, że spowodowało to, że PHP zostało skompilowane przeciwko starszej wersji libcurl (7.11.0 w moim przypadku, która ma teraz prawie 10 lat). Na innej maszynie z nowszą wersją libcurl (7.29.0) ten sam kod był w porządku, a moje problemy skończyły się po tym, jak mój gospodarz zrekompilował swój PHP, aby użyć najnowszego, jaki miał (7.30.0).

Ta poprawka została zasugerowana przez a thread on the curl-library mailing list from 2008, gdzie użytkownik odkrył problem, którego dotyczyła wersja 7.10.6, ale nie 7.12.1. Przeszukałem numer libcurl changelog around 7.12.0 i nie znalazłem żadnego wyraźnego wpisu o naprawianiu tego problemu, chociaż może on być objęty "ogólną poprawą uwierzytelniania HTTP". Wciąż jestem jednak pewny, że problemem jest stara libcurl.

Można sprawdzić, która wersja libcurl jest używany przez PHP z wejściem „Curl informacji” wyjściu phpinfo();