Od kilku tygodni bawię się po trochu CURLem, w ramach tworzenia PeHaPowej biblioteki do Blip!a. Poniżej kilka zagwozdek, na które ciężko znaleźć sensowną odpowiedź w google, albo ja nie wiem jak pytać…
-
Jak poprawnie wykonać zapytanie PUT? (aka: metoda PUT i “select/poll returned error”)
Nad tym spędziłem najwięcej czasu. Kombinowałem na mnóstwo sposobów. Kluczem do sukcesu okazało się podejrzenie wersji konsolowej CURLa z dokładnie takim samym zapytaniem, jakie wysyłałem za pomocą skryptu PHP. W skrócie: należy wymusić na CURLu HTTP 1.0, za pomocą ustawienia opcji:
curl_setopt ($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); # gdzie $ch jest obiektem utworzonym za pomocą curl_init ()Po tej operacji zapytania śmigają jak należy (dodam tylko, że czasem zamiast “select/poll returned error” dostawałem “connection reset by peer”).
-
Przy rozwiązywaniu powyższego problemu, pomogła mi mała sztuczka. Mianowicie musiałem podejrzeć jakie nagłówki wysyła CURL. Normalnie PHPowy CURL nie zamierza pokazać co jest wysyłane
i odbierane(Rozpisałem się – oczywiście nagłówki odbierane bez problemu można zobaczyć. Dzięki, Arek ;) ), bo i po co… Ja posłużyłem się tutaj specjalnie na tą okazję utworzonym skryptem PHP z dokładnie wyizolowanym ‘testcase’. Tutaj, po zaimplementowaniu opcji:curl_setopt ($ch, CURLOPT_VERBOSE, 1);i odpaleniu skryptu z konsoli, grzecznie została mi pokazana komunikacja wychodząca z serwerem, co było kluczem do rozwiązania problemu (okazało się że był wysyłany dodatkowy nagłówek
Expectnależący do HTTP 1.1, a po wrzuceniu tego w google znalazłem informacje które mnie nakierowały na właściwy trop). -
Jak wysłać plik POSTem?
Ech, w sumie rozwiązanie jest banalne, jeśli ktoś dokładniej przeczyta manual na stronach PHP dotyczący CURLa. Ale skoro już opisuję zagwozdki…
PHPowy CURL pozwala wysyłać dane na dwa sposoby (akceptowane i sprecyzowane, oczywiście, w odpowiednim RFC). Jeden to
x-www-form-urlencoded(tak są wysyłane dane za pomocą webowych formularzy), drugi tomulti-part form-data(tak są wysyłane pliki, także z formularzy). Normalnie dla opcjiCURLOPT_POSTFIELDSpodaje sięstringktóry wygląda dokładnie tak samo jak ten widoczny w URLach skryptów pehapowych (mówiąc po laicku), np.a=1&b=2– wtedy dane są wysyłane metodąx-www-form-urlencoded. Aby zmusić CURLa do wysłania danych metodąmulti-part form-data, jako parametr opcjiCURLOPT_POSTFIELDSmusimy podać tablicę. Tak, właśnie tablicę, gdzie kluczem powinne być nazwa pola (odpowiadająca temu z prawdziwego formularza), a wartością ścieżka do pliku, ale uwaga: ścieżka powinna być poprzedzona znakiem “małpy”: @. Czyli powinno wyglądać to tak:curl_setopt ($ch, CURLOPT_POSTFIELDS, array ('pole' => '@/sciezka/do/pliku.jpg'));Po tej operacji wysłanie pliku nie powinno być już problemem :)
