How do I get SSL working in fsockopen?

soapergem picture soapergem · Nov 18, 2009 · Viewed 37.2k times · Source

I'm running PHP 5.2.6 on Windows, I have extension=php_curl.dll and extension=php_openssl.dll uncommented in php.ini; as such I can see the following in phpinfo:

curl
cURL support        enabled
cURL Information    libcurl/7.16.0 OpenSSL/0.9.8g zlib/1.2.3

openssl
OpenSSL support     enabled
OpenSSL Version     OpenSSL 0.9.8g 19 Oct 2007

I'm not sure that having cURL enabled is vital to this, but since it mentioned OpenSSL I thought I'd include it here anyway for completeness.


What I want to do is simple: make a POST request to another server over SSL using fsockopen.
My code so far is this:

$host = 'www.redacted.com';
$data = 'user=redacted&pass=redacted&action=redacted';
$response = "";

if ( $fp = fsockopen("ssl:{$host}", 443, $errno, $errstr, 30) ) {

    $msg  = 'POST /wsAPI.php HTTP/1.1' . "\r\n";
    $msg .= 'Content-Type: application/x-www-form-urlencoded' . "\r\n";
    $msg .= 'Content-Length: ' . strlen($data) . "\r\n";
    $msg .= 'Host: ' . $host . "\r\n";
    $msg .= 'Connection: close' . "\r\n\r\n";
    $msg .= $data;
    if ( fwrite($fp, $msg) ) {
        while ( !feof($fp) ) {
            $response .= fgets($fp, 1024);
        }
    }
    fclose($fp);

} else {
    $response = false;
}

This works fine of course if I just pass in $host and use port 80. But I really need to send this over SSL, and right now it's not working. $response gets set to false, $errno stays at 0, and $errstr gets set to php_network_getaddresses: getaddrinfo failed: No such host is known.. I know that it's not an issue of the server being down, or a typo in the host name, etc., because it DOES work if I go over port 80 unsecurely. The problems only start when I try to switch to SSL.

What do I do to get this working?

Answer

Powerlord picture Powerlord · Nov 23, 2009

This may sound obvious, but have you tried this instead?

if ($fp = fsockopen('ssl://'. $host, 443, $errno, $errstr, 30)) {

I'm not sure if the // is required or not, but the ssl and tls examples on the PHP Internet Transports page have them.

P.S. I also have a "thing" about included variables in strings, in case you're wondering why it uses string concatenation now.