Hallo!
$fp = fsockopen("ssl://zielserver.com",443,$errstr,$errno);
Du willst offensichtlich Dich mit SSL mit dem Server verbinden. Das Problem: Wenn Du einen HTTP-Proxy dazwischen hast, dann musst Du vorher mit dem Proxy im Klartext reden, um einen HTTP-CONNECT-Aufruf abzusetzen. DANACH musst Du dann die TLS-Verschlüsselung aktivieren. Das heißt aber auch, dass Du das nicht mehr bequem per fsockopen() machen kannst (dort musst Du erst einmal eine normale TCP-Verbindung aufbauen), sondern Du musst den TLS-Handshake erst im Laufe der Verbindung (sobald CONNECT durchgegangen ist) anstoßen. Dafür bietet PHP eine Funktion an, nämlich stream_socket_enable_crypto, die aber erst ab PHP 5.1 funktioniert (unter PHP 5.2.6 würde ich aber aus Sicherheitsgründen sowieso kein PHP einsetzen wollen).
Hier mal ein Beispiel, wie man das machen kann:
$proxy_host = 'proxyhost.lan';
$proxy_port = 3128;
$remote_host = 'zielhost.test';
$remote_port = 443;
$fp = fsockopen ("tcp://$proxy_host:$proxy_port", 0, $errstr, $errno);
if (!is_resource ($fp)) {
// verbindung zum proxy geht nicht
throw new Exception ("Could not open connection to proxy server");
}
// CONNECT-request senden
fputs ($fp, "CONNECT $remote_host:$remote_port HTTP/1.1\r\n\r\n");
// antwort einlesen
$line = fgets ($fp, 8192);
$line = trim ($line);
if (substr ($line, 0, 7) != 'HTTP/1.') {
fclose ($fp);
// ungültige antwort
throw new Exception ("Invalid response: $line");
}
if (substr ($line, 9, 3) != '200') {
fclose ($fp);
// keinr 200er-Antwort, also fehlgeschlagen
throw new Exception ("CONNECT failed: $line");
}
// solange man keine leerzeile eingelesen hat, einfach neue zeilen
// einlesen, Leerzeile markiert Ende des HTTP-Headers und danach
// kann's mit TLS losgehen
while (trim ($line) != "") {
$line = fgets ($fp, 8192);
}
$res = stream_socket_enable_crypto ($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
if (!$res) {
// konnte keinen TLS-Handshake durchführen
throw new Exception ("TLS Handshake failed");
}
// Und JETZT über die Verbindung ganz normal den HTTP-Request absetzen
// und die Antwort auslesen, so wie vorher
fputs ($fp, "GET / HTTP/1.1\r\n");
// etc.
-------- schnipp ---------------
Im Falle von einer Klartextverbindung (d.h. **KEIN** SSL/TLS über den Proxy) hättest Du das ganze VIEL einfacher:
Im Klartextfall musst Du Dich nämlich lediglich mit dem Proxy verbinden statt mit dem richtigen Server und den Namen des richtigen Servers in dem Request verarbeiten, d.h.
Vereinfachter voriger Code (Klartext-Fall!):
$fp = fsockopen ('tcp://zielserver.test:80', 0, ...);
fputs ($fp, "POST /bla HTTP/1.1\r\n");
Vereinfachter neuer Code (Klartext-Fall!):
$fp = fsockopen ('tcp://proxyserver.lan:3128', 0, ...);
fputs ($fp, "POST http://zielserver.test/bla HTTP/1.1\r\n");
Viele Grüße,
Christian