Polaczenia SSL w PHP

Transkrypt

Polaczenia SSL w PHP
Połączenia SSL w PHP (klient HTTPS)
Ostatnio stanąłem przed problemem utworzenia klienckiego połączenia SSL z poziomu
skryptu PHP w celu pobrania pliku przez protokół HTTP. Sprawa okazała się prostsza niż
myślałem. Tutaj zamieszczam gotową receptę.
Wymagania
Żeby całość zaczęła chodzić, musimy mieć PHP skompilowane z obsługą OpenSSL. To, czy
mamy wkompilowany OpenSSL możemy sprawdzić w wyniku, jaki zwraca funkcja
phpinfo(), lub po prostu - wyjdzie w praniu, podczas pisania skryptu.
Założenia ogólne
Cała procedura sprowadza się do utworzenia odpowiedniego nagłówka protokołu HTTP,
otwarcia połączenia SSL, wysłania tego nagłówka przez otwarte połączenie oraz odebrania
odpowiedzi.
Żeby ułatwić i uczynić skrypt bardziej przejrzystym, przyjmijmy kilka zmiennych:
$host="luktom.net"; $file="/testowy.php";
$get="zmienna1=wartosc1&zmienna2=wartosc2";
$post="zmienna1=wartosc1&zmienna2=wartosc2";
W zmiennych $get i $post zapisujemy zapytania do serwera, które chcemy wysłać daną
metodą.
Tworzenie nagłówka
Zasadniczo nie ma znaczenia, czy chcemy wykonać zapytanie GET czy POST. Procedura jest
taka sama. W przypadku metody GET nagłówek będzie wyglądał tak:
$request="GET {$file}?{$get} HTTP/1.0\r\n" . "Host: $host\r\n\r\n"
Natomiast dla POST, następująco:
$request="POST {$file}?{$get} HTTP/1.0\r\n" . "Host: $host\r\n" . "ContentType: application/x-www-form-urlencoded\r\n" . "Content-Length:
".strlen($post)."\r\n\r\n" . "$post\r\n"
Obsługa połączenia SSL
Otwarcie połączenia sprowadza się do pozyskania odpowiedniego deskryptora z funkcji
fsockopen:
$fp=fsockopen("ssl://$host", 443, $errno, $errstr, 1);
Dla sprawdzenia, czy połączenie zostało pomyślnie nawiązane sprawdzamy deskryptor:
if(!$fp) { die($errstr); }
Następnie przystępujemy do wysłania zapytania i odczytania odpowiedzi oraz ostatecznie
zamykamy połączenie:
fwrite($fp, $request); while(!feof($fp)) { $response.=fgets($fp, 128); }
fclose($fp);
Odpowiedź zawiera w sobie nagłówki oraz właściwą treść strony. Rozdzielmy je:
$pos=strpos($response,"\r\n\r\n") $body=substr($response,$pos+4);
$headers=substr($response,$pos);
Ostatecznie w zmiennej $body zapisaną mamy treść strony, natomiast w $headers - nagłówki
zwrócone od serwera.
Uwagi końcowe
Przedstawiona metoda sprawdza się nie tylko w przypadku protokołu HTTP - równie dobrze
możemy np. nawiązać szyfrowane połączenie z serwerem Jabbera lub serwerem pocztowym,
jak też każdym innym - wystarczy jedynie poznać ich protokoły oraz odpowiednio
dostosować skrypt.