Z reguły jestem człowiekiem spokojnym, ale zdarzają się chwile, w których klnę na czym świat stoi. Wczoraj przytrafił mi się właśnie taki dzień.
Słońce świeciło i nic nie zapowiadało kataklizmu...
Wszystko zaczęło się od migracji pokaźnego skryptu korzystającego z API poprzez SOAP. Do dnia wczorajszego, działał on na serwerze z zainstalowanym PHP 5.2.x, natomiast komunikacja klienta z serwerem odbywa się poprzez protokół HTTPS. Problemy zaczęły pojawiać się wraz z wersjami PHP 5.3.x.
Po "odpaleniu" aplikacji zostałem poczęstowany przemiłym komunikatem:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://domain.ltd/ListService?wsdl' : Start tag expected, '<' not found
Komunikat sugeruje, że zwracany dokument nie zaczyna się standardowym znakiem "<". Wkleiłem zatem adres w przeglądarce i ku mojemu zdziwieniu, załadował się poprawny dokument XML. Ciekawe jest to, że zupełnie inne API, które działa zarówno poprzez HTTP jak i HTTPS również sprawiło ten sam problem. Pierwsza myśl, jaka przyszła mi do głowy to brak rozszerzenia OpenSSL, co jest z kolei nielogiczne, gdyż we wszystkich innych rozszerzeniach PHP, które potrafią korzystać z SSL obsłużyły je koncertowo (curl, imap, mysqlnd) - ręce mi opadły...
Przesłuchanie ...
Wziąłem więc wujka Google na poważne przesłuchanie - co się okazało? Problem ten jest bardzo popularny i dosłownie nie ma na niego złotego lekarstwa - albo będzie Ci działać, albo nie... Wśród możliwych przyczyn były: brak modułu do obsługi SSL, niewłaściwy transport nagłówków, ginący w trakcie zapytania nagłówek Content-Lenght, różne warianty linii konfiguracyjnej kompilacji PHP (nawet ze zamianą kolejności), jak również downgrade różnej maści bibliotek. Wszystkie te cenne uwagi okazały się jednak nieskuteczne.
Śledztwo na własną rękę!
Po pierwsze - upewniłem się, że kompilacja PHP 5.3.x jest prawidłowa na feralnej maszynie jak i na drugiej, z całkowicie świeżą instalacją PHP 5.3.6 i systemu. Wszystko w obu przypadkach wyglądało OK!.
Registered PHP Streams: compress.bzip2, php, file, glob, data, dict, ftp, ftps, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, smtp, smtps, telnet, tftp, compress.zlib, zip, phar
Registered Stream Socket Transports: tcp, udp, unix, udg, ssl, sslv3, sslv2, tls
Curl SSL: yes
Curl Protocols: dict, file, ftp, ftps, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, smtp, smtps, telnet, tftp
OpenSSL support: enabled
Jak wspomniałem wcześniej, wszystko inne korzystające z OpenSSL działa prawidłowo - SOAP uparcie nie!
File_get_contents() również odmówił posłuszeństwa
Sprawdziłem z rozbiegu, czy można pobrać dokument WSDL za pomocą file_get_contents(). I znów magia - na starym PHP 5.2.x pobrał zarówno poprzez HTTPS jak i HTTP. W PHP 5.3.6 via HTTPS nie było żadnych komunikatów, błędów i ostrzeżeń - był za to pusty plik z rozmiarem "zero".
- <?php
- // test pobrania pliku przez https
- ?>
Tłumaczy to brak wymaganego znaku "<" i problem z SOAPem, który nie korzysta w żadnym stopniu z CURLa - a szkoda... bo działa doskonale, ładnie pobierając wybrany dokument poprzez HTTPS.
Chwilowe rozwiązanie
Po kilkunastu godzinach kombinowania nie udało mi się znaleźć przyczyny. Udało mi się jednak obejść problem, pobierając plik WSDL za pomocą CURLa i otwierając go lokalnie.
- <?php
- $client = new SoapClient($file);
- ?>
Czy ktoś z Was ma również podobne problemy, chociażby z pobraniem przykładowego dokumentu https://www.nazwa.pl/domeny-rejestracja-domen.html za pomocą file_get_contents() ?
Osoby, które posiadają dostęp do PHP 5.3.x prosiłbym o sprawdzenie i podesłanie wyniku php_info() na adres public (at) santyago (dot) pl. Może uda mi się na ich podstawie znaleźć podłoże problemu.
Aktualizacja dnia 29/03/2011 14:30 - Problem rozwiązany!
Dziękuję Tomaszowi i Marcinowi za podesłane wyników php_info(). Naprowadziło mnie to na wersje niektórych pakietów. Rzucającą się w oczy była biblioteka CURL, którą posiadam w wersji 7.20.1. Po wyładowaniu rozszerzenia CURL - file_get_contents() i SOAP zadziałał z protokołem HTTPS.
CURL jest jednak ważną biblioteką, której zabraknąć w PHP nie może. Po aktualizacji CURLa do wersji 7.21.4 wszystko nadal działa jak burza. Zastanawiające jest, że rozszerzenie uniemożliwiło działanie HTTPS w SOAP oraz w podstawowych funkcjach, tym bardziej, że samo akurat poprawnie łączyło się przez ten protokół.
Jeszcze raz dziękuję za pomoc.









Komentarze (5)
Tomasz Sh4dow Budzyński / 29 mar 2011 / 13:17
Używam Kubuntu, PHP w wersji 5.3.3-1ubuntu9.3 (dziwna wersja) i nie mam żadnych kłopotów z SOAP'em po ssl'u
Maila z phpinfo wysłałem jak coś :)
Marcin Gryszkalis / 29 mar 2011 / 14:01
U mnie działa zarówno na gentoo jak i na FreeBSD (oba 5.3.6)
Korneliusz / 29 mar 2011 / 14:31 Strona www «
Panowie, dzięki :) Winę ponosiła biblioteka CURL 7.20.1 i samo rozszerzenie PHP.
Domker_ / 30 mar 2011 / 12:06 Strona www «
Swoją drogą też miałem nieco podobny problem po aktualizacji, ale nie PHP tylko Linuxa :P Na starszej wersji funkcją file_get_contents normalnie zczytywałem zawartość pliku parsera (tekstowego) z pewnego serwera. Po aktualizacji Linuxa już miałem tylko pusty plik, bez żadnej zawartości, a ten sam skrypt PHP na dedyku działał normalnie =.= Najdziwniejsze jest to, że odświeżając szybko, kilkakrotnie wynik działania skryptu klawiszem F5 w przeglądarce (localhost) pojawiała się prawidłowa zawartość, a nie tylko "pustka".
Thorvard / 30 mar 2011 / 14:58
Tak sobie czytam ChangeLoga Slackware Current, a tu taka niespodzianka :)
Tue Mar 29 22:58:09 UTC 2011
.....
n/curl-7.21.4-i486-1.txz: Upgraded.
Fixes PHP curl extension.
Thanks to Korneliusz Jarzebski.