|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2012-03-03 01:50 UTC] Erik dot Haller at gmail dot com
 Description:
------------
Socket streams created with fsockopen using ssl scheme fail with the event_buffer_new($socket, readcb, writecb, errorcg, arg) function; i.e. fsockopen("ssl://my_server", ...). The readcb callback is called and buffer returns encrypted data. The readcb works properly with the tcp scheme; i.e. fsockopen("tcp://my_server", ...). The event_buffer_read/event_buffer_write functionality is unusable with ssl sockets.
As a workaround, use the event_new()/event_set() functions with ssl socket streams.
Tested with php 5.3.8 (Windows XP) and php 5.3.10 (Windows Server 2003) and libevent 2.0.12 and php_libevent 0.0.4.
Also tested with php 5.3.8 (Windows XP) and php 5.3.10 (Windows Server 2003) and libevent 2.0.17 (latest) and pecl php_libevent trunk revision 318910 (2012-03-02).
Test script:
---------------
Pseudo Code
$socket = fsockopen("ssl://myserver", 61613, $errno, $errstr);
stream_set_blocking($socket, 0));
$event_buffer = event_buffer_new($socket, 'ev_read', 'ev_write', 'ev_error');			
event_buffer_base_set($event_buffer, self::$event_base);
event_buffer_enable($event_buffer, EV_READ | EV_PERSIST | EV_WRITE);
function ev_read($buffer, $arg) {
  // $in will have encrypted data when using ssl://. 
  // Data should be unencrypted
  // It seems that the event_buffer_read is not allowing the normal php sockets to unencrypt the data first.
   $in = event_buffer_read($buffer, 8192);
}
Expected result:
----------------
The above pseudo code used with ssl:// stream sockets should work as the tcp:// stream sockets with event_buffer_new()/event_buffer_base_set()/event_buffer_enable() functions.
The ssl:// & tcp:// stream sockets both work with the event_new()/event_set()/event_add() functions. When the EV_READ callback is executed the data is read from php as unencrypted.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 14:00:01 2025 UTC | 
php_libevent: 0.0.4 libevent version: 2.0.16-stable Problem also occurs on linux: Ubuntu 12.04.1 LTS precise php -version PHP 5.3.10-1ubuntu3.4 with Suhosin-Patch (cli) (built: Sep 12 2012 19:00:43) Copyright (c) 1997-2012 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies Here's the test code: <?php chdir( __DIR__ ); error_reporting( E_ALL | E_STRICT ); openlog( "le-test", LOG_PERROR, LOG_LOCAL0 ); syslog( LOG_INFO, "begin" ); $url = "tls://www.google.com:443"; // Uncomment below to see libevent code work with no encryption //$url = "tcp://www.google.com:80"; $get = "GET / HTTP/1.0\r\n\r\n"; $pa = parse_url( $url ); // Socket Test $res = fsockopen( "{$pa[ 'scheme']}://{$pa[ 'host' ]}", $pa[ "port" ], $errno, $errstr ); fwrite( $res, $get ); $str = fread( $res, 8192 ); syslog( LOG_INFO, sprintf( "Socket Read\n\n%s", $str ) ); fclose( $res ); // Libevent Test $res = fsockopen( "{$pa[ 'scheme']}://{$pa[ 'host' ]}", $pa[ "port" ], $errno, $errstr, 60 ); stream_set_blocking( $res, 0 ); $get_sent = false; $event_base = event_base_new(); $event_buffer = event_buffer_new( $res, "ev_read", "ev_write", "ev_error", $event_base ); function s2hex($s, $sep = "", $printable = false) { if($printable) { $p = array(); foreach(unpack("C*", $s) as $i) { if($i <= 31) { $p[] = sprintf("^%c", $i + 64); } elseif( (32 <= $i) && ($i <= 126) ) { $p[] = sprintf("%c ", $i); } else { $p[] = sprintf("%'02x", $i); } } return join($sep, $p); } else { return preg_replace('/../', '$0'.$sep, join("", unpack("H*", $s)) ); } } function ev_read( $buf, $arg ) { global $res; $str = event_buffer_read( $buf, 1000000 ); syslog( LOG_INFO, sprintf( "Libevent Read\n\nlen: %s %s", strlen( $str ), $str ) ); if( strlen( $str ) < 100 ) { syslog( LOG_INFO, sprintf( "hex:\n%s\n", s2hex( $str, ' ', true ) ) ); } } function ev_write( $buf, $arg ) { global $get, $event_buffer, $get_sent; if( ! $get_sent ) { $res = event_buffer_write( $buf, $get ); syslog( LOG_INFO, "ev_write result: $res" ); $get_sent = true; } } function ev_error( $buf, $what, $arg) { syslog( LOG_INFO, sprintf( "Libevent Error:\n\n%s\n\n%s" , print_r( func_get_args(), true ) , event_buffer_read( $buf, 8192 ) ) ); } echo "buffer: $event_buffer base: $event_base\n"; event_buffer_base_set( $event_buffer, $event_base ); event_buffer_enable( $event_buffer, EV_READ | EV_WRITE ); event_base_loop( $event_base ); syslog( LOG_INFO, "base_loop ended" ); event_buffer_disable( $event_buffer, EV_READ | EV_WRITE ); event_buffer_free( $event_buffer ); event_base_free( $event_base ); closelog(); ?>php_libevent: 0.0.4 libevent version: 2.0.16-stable Problem also occurs on linux: Ubuntu 12.04.1 LTS precise php -version PHP 5.3.10-1ubuntu3.4 with Suhosin-Patch (cli) (built: Sep 12 2012 19:00:43) Copyright (c) 1997-2012 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies Here's the test code: <?php chdir( __DIR__ ); error_reporting( E_ALL | E_STRICT ); openlog( "le-test", LOG_PERROR, LOG_LOCAL0 ); syslog( LOG_INFO, "begin" ); $url = "tls://www.google.com:443"; // Uncomment below to see libevent code work with no encryption //$url = "tcp://www.google.com:80"; $get = "GET / HTTP/1.0\r\n\r\n"; $pa = parse_url( $url ); // Socket Test $res = fsockopen( "{$pa[ 'scheme']}://{$pa[ 'host' ]}", $pa[ "port" ], $errno, $errstr ); fwrite( $res, $get ); $str = fread( $res, 8192 ); syslog( LOG_INFO, sprintf( "Socket Read\n\n%s", $str ) ); fclose( $res ); // Libevent Test $res = fsockopen( "{$pa[ 'scheme']}://{$pa[ 'host' ]}", $pa[ "port" ], $errno, $errstr, 60 ); stream_set_blocking( $res, 0 ); $get_sent = false; $event_base = event_base_new(); $event_buffer = event_buffer_new( $res, "ev_read", "ev_write", "ev_error", $event_base ); function s2hex($s, $sep = "", $printable = false) { if($printable) { $p = array(); foreach(unpack("C*", $s) as $i) { if($i <= 31) { $p[] = sprintf("^%c", $i + 64); } elseif( (32 <= $i) && ($i <= 126) ) { $p[] = sprintf("%c ", $i); } else { $p[] = sprintf("%'02x", $i); } } return join($sep, $p); } else { return preg_replace('/../', '$0'.$sep, join("", unpack("H*", $s)) ); } } function ev_read( $buf, $arg ) { global $res; $str = event_buffer_read( $buf, 1000000 ); syslog( LOG_INFO, sprintf( "Libevent Read\n\nlen: %s %s", strlen( $str ), $str ) ); if( strlen( $str ) < 100 ) { syslog( LOG_INFO, sprintf( "hex:\n%s\n", s2hex( $str, ' ', true ) ) ); } } function ev_write( $buf, $arg ) { global $get, $event_buffer, $get_sent; if( ! $get_sent ) { $res = event_buffer_write( $buf, $get ); syslog( LOG_INFO, "ev_write result: $res" ); $get_sent = true; } } function ev_error( $buf, $what, $arg) { syslog( LOG_INFO, sprintf( "Libevent Error:\n\n%s\n\n%s" , print_r( func_get_args(), true ) , event_buffer_read( $buf, 8192 ) ) ); } echo "buffer: $event_buffer base: $event_base\n"; event_buffer_base_set( $event_buffer, $event_base ); event_buffer_enable( $event_buffer, EV_READ | EV_WRITE ); event_base_loop( $event_base ); syslog( LOG_INFO, "base_loop ended" ); event_buffer_disable( $event_buffer, EV_READ | EV_WRITE ); event_buffer_free( $event_buffer ); event_base_free( $event_base ); closelog(); ?>