©
This document uses PHP Chinese website manual Release
(PECL event >= 1.2.6-beta)
EventBufferEvent::sslFilter — Create a new SSL buffer event to send its data over another buffer event
$base
, EventBufferEvent $underlying
, EventSslContext $ctx
, int $state
[, int $options
= 0
] )Create a new SSL buffer event to send its data over another buffer event
Note:
This function is available only if Event is compiled with OpenSSL support.
base
Associated event base.
underlying
A socket buffer event to use for this SSL.
ctx
Object of EventSslContext class.
state
The current state of SSL connection:
EventBufferEvent::SSL_OPEN
,
EventBufferEvent::SSL_ACCEPTING
or
EventBufferEvent::SSL_CONNECTING
.
options
One or more buffer event options.
Returns a new SSL EventBufferEvent object.
Example #1 Simple SMTP server
<?php
class Handler {
public $domainName = FALSE ;
public $connections = [];
public $buffers = [];
public $maxRead = 256000 ;
public function __construct () {
$this -> ctx = new EventSslContext ( EventSslContext :: SSLv3_SERVER_METHOD , [
EventSslContext :: OPT_LOCAL_CERT => 'cert.pem' ,
EventSslContext :: OPT_LOCAL_PK => 'privkey.pem' ,
//EventSslContext::OPT_PASSPHRASE => '',
EventSslContext :: OPT_VERIFY_PEER => false , // change to true with authentic cert
EventSslContext :: OPT_ALLOW_SELF_SIGNED => true // change to false with authentic cert
]);
$this -> base = new EventBase ();
if (! $this -> base ) {
exit( "Couldn't open event base\n" );
}
if (! $this -> listener = new EventListener ( $this -> base ,
[ $this , 'ev_accept' ],
$this -> ctx ,
EventListener :: OPT_CLOSE_ON_FREE | EventListener :: OPT_REUSEABLE ,
- 1 ,
'0.0.0.0:25' ))
{
exit( "Couldn't create listener\n" );
}
$this -> listener -> setErrorCallback ([ $this , 'ev_error' ]);
$this -> base -> dispatch ();
}
public function ev_accept ( $listener , $fd , $address , $ctx ) {
static $id = 0 ;
$id += 1 ;
$this -> connections [ $id ][ 'clientData' ] = '' ;
$this -> connections [ $id ][ 'cnx' ] = new EventBufferEvent ( $this -> base , $fd ,
EventBufferEvent :: OPT_CLOSE_ON_FREE );
if (! $this -> connections [ $id ][ 'cnx' ]) {
echo "Failed creating buffer\n" ;
$this -> base -> exit ( NULL );
exit( 1 );
}
$this -> connections [ $id ][ 'cnx' ]-> setCallbacks ([ $this , "ev_read" ], NULL ,
[ $this , 'ev_error' ], $id );
$this -> connections [ $id ][ 'cnx' ]-> enable ( Event :: READ | Event :: WRITE );
$this -> ev_write ( $id , '220 ' . $this -> domainName . " wazzzap?\r\n" );
}
function ev_error ( $listener , $ctx ) {
$errno = EventUtil :: getLastSocketErrno ();
fprintf ( STDERR , "Got an error %d (%s) on the listener. Shutting down.\n" ,
$errno , EventUtil :: getLastSocketError ());
if ( $errno != 0 ) {
$this -> base -> exit ( NULL );
exit();
}
}
public function ev_close ( $id ) {
$this -> connections [ $id ][ 'cnx' ]-> disable ( Event :: READ | Event :: WRITE );
unset( $this -> connections [ $id ]);
}
protected function ev_write ( $id , $string ) {
echo 'S(' . $id . '): ' . $string ;
$this -> connections [ $id ][ 'cnx' ]-> write ( $string );
}
public function ev_read ( $buffer , $id ) {
while( $buffer -> input -> length > 0 ) {
$this -> connections [ $id ][ 'clientData' ] .= $buffer -> input -> read ( $this -> maxRead );
$clientDataLen = strlen ( $this -> connections [ $id ][ 'clientData' ]);
if( $this -> connections [ $id ][ 'clientData' ][ $clientDataLen - 1 ] == "\n"
&& $this -> connections [ $id ][ 'clientData' ][ $clientDataLen - 2 ] == "\r" )
{
// remove the trailing \r\n
$line = substr ( $this -> connections [ $id ][ 'clientData' ], 0 ,
strlen ( $this -> connections [ $id ][ 'clientData' ]) - 2 );
$this -> connections [ $id ][ 'clientData' ] = '' ;
$this -> cmd ( $buffer , $id , $line );
}
}
}
protected function cmd ( $buffer , $id , $line ) {
switch ( $line ) {
case strncmp ( 'EHLO ' , $line , 4 ):
$this -> ev_write ( $id , "250-STARTTLS\r\n" );
$this -> ev_write ( $id , "250 OK ehlo\r\n" );
break;
case strncmp ( 'HELO ' , $line , 4 ):
$this -> ev_write ( $id , "250-STARTTLS\r\n" );
$this -> ev_write ( $id , "250 OK helo\r\n" );
break;
case strncmp ( 'QUIT' , $line , 3 ):
$this -> ev_write ( $id , "250 OK quit\r\n" );
$this -> ev_close ( $id );
break;
case strncmp ( 'STARTTLS' , $line , 3 ):
$this -> ev_write ( $id , "220 Ready to start TLS\r\n" );
$this -> connections [ $id ][ 'cnx' ] = EventBufferEvent :: sslFilter ( $this -> base ,
$this -> connections [ $id ][ 'cnx' ], $this -> ctx ,
EventBufferEvent :: SSL_ACCEPTING ,
EventBufferEvent :: OPT_CLOSE_ON_FREE );
$this -> connections [ $id ][ 'cnx' ]-> setCallbacks ([ $this , "ev_read" ], NULL , [ $this , 'ev_error' ], $id );
$this -> connections [ $id ][ 'cnx' ]-> enable ( Event :: READ | Event :: WRITE );
break;
default:
echo 'unknown command: ' . $line . "\n" ;
break;
}
}
}
new Handler ();