Esempio n. 1
0
 public function onConnectedEvent($connSocket, $events, $arg)
 {
     $connId = $arg[0];
     Debug::netEvent(get_class($this) . '::' . __METHOD__ . '(' . $connId . ') invoked. ');
     //处理两种状态,一种是直接连接成功,一种是异步通知
     if (isset($this->checkConnEvPool[$connId])) {
         // 异步通知
         // 因为 注册 EV_WRITE 事件是非持久模式的,所以这里不用 delete, 只需要 unset pool 即可
         unset($this->checkConnSocketPool[$connId]);
         unset($this->checkConnEvPool[$connId]);
     }
     $evBuf = event_buffer_new($connSocket, array($this, 'onEvBufReadEvent'), array($this, 'onEvBufWriteEvent'), array($this, 'onEventEvent'), array($connId));
     event_buffer_base_set($evBuf, daemon::$eventBase);
     event_buffer_priority_set($evBuf, 10);
     event_buffer_watermark_set($evBuf, EV_READ, $this->evBufLowMark, $this->evBufHighMark);
     if (!event_buffer_enable($evBuf, EV_READ | EV_WRITE | EV_PERSIST)) {
         Debug::netErrorEvent(get_class($this) . '::' . __METHOD__ . ': can not set base of buffer. #' . $connId);
         //            socket_close($connSocket);
         fclose($connSocket);
         return;
     }
     // 调试这里时,浪费了很多时间,必须注意的是,以上 event 所用的变量如果在函数中,如果没有交给其他的变量引用,在函数结束时就会销毁,
     // 造成连接直接断或者bufferevent 不能触发。晕啊晕。
     $this->connSocketPool[$connId] = $connSocket;
     $this->connEvBufPool[$connId] = $evBuf;
     list($ip, $port) = explode(':', stream_socket_get_name($connSocket, true));
     $this->updateLastContact($connId);
     $this->onConnected($connId, $ip, $port);
 }
Esempio n. 2
0
 public function onAcceptEvent($bindSocket, $events, $arg)
 {
     $bindSocketId = $arg[0];
     Debug::netEvent(get_class($this) . '::' . __METHOD__ . '(' . $bindSocketId . ') invoked.');
     // add to accept next event
     // why not use EV_PERSIST
     event_add($this->bindSocketEvPool[$bindSocketId]);
     $connSocket = stream_socket_accept($this->bindSocketPool[$bindSocketId]);
     if (!$connSocket) {
         Debug::netErrorEvent(get_class($this) . ': can not accept new TCP-socket');
         return;
     }
     stream_set_blocking($connSocket, 0);
     list($ip, $port) = explode(':', stream_socket_get_name($connSocket, true));
     $connId = daemon::getNextConnId();
     $evBuf = event_buffer_new($connSocket, array($this, 'onEvBufReadEvent'), array($this, 'onEvBufWriteEvent'), array($this, 'onEventEvent'), array($connId));
     event_buffer_base_set($evBuf, daemon::$eventBase);
     event_buffer_priority_set($evBuf, 10);
     event_buffer_watermark_set($evBuf, EV_READ, $this->evBufLowMark, $this->evBufHighMark);
     if (!event_buffer_enable($evBuf, EV_READ | EV_WRITE | EV_PERSIST)) {
         Debug::netErrorEvent(get_class($this) . '::' . __METHOD__ . ': can not set base of buffer. #' . $connId);
         //close socket
         stream_socket_shutdown($connSocket, STREAM_SHUT_RDWR);
         fclose($connSocket);
         return;
     }
     // 调试这里时,浪费了很多时间,必须注意的是,以上 event 所用的变量如果在函数中,如果没有交给其他的变量引用,在函数结束时就会销毁,
     // 造成连接直接断或者bufferevent 不能触发。晕啊晕。
     $this->connSocketPool[$connId] = $connSocket;
     $this->connEvBufPool[$connId] = $evBuf;
     $this->updateLastContact($connId);
     $this->onAccepted($connId, $ip, $port);
 }
Esempio n. 3
0
 /**
  * Initialize a new stream listener
  */
 public function __construct($stream)
 {
     $this->stream = $stream;
     stream_set_blocking($this->stream, 0);
     $this->event = event_buffer_new($this->stream, array($this, '_read'), array($this, '_write'), array($this, '_error'));
     Loop::attachBuffer($this);
     event_buffer_timeout_set($this->event, 2, 5);
     event_buffer_watermark_set($this->event, EV_READ, 0, 0xffffff);
     event_buffer_priority_set($this->event, 10);
     event_buffer_enable($this->event, EV_READ | EV_PERSIST);
 }
 private function accept($socket, $flag, $base)
 {
     $connection = @stream_socket_accept($socket, 0);
     $connectionId = $this->getIdByConnection($connection);
     stream_set_blocking($connection, 0);
     $buffer = event_buffer_new($connection, array($this, 'onRead'), array($this, 'onWrite'), array($this, 'onError'), $connectionId);
     event_buffer_base_set($buffer, $this->base);
     event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
     event_buffer_priority_set($buffer, 10);
     event_buffer_enable($buffer, EV_READ | EV_WRITE | EV_PERSIST);
     $this->clients[$connectionId] = $connection;
     $this->buffers[$connectionId] = $buffer;
     $this->_onOpen($connectionId);
 }
Esempio n. 5
0
 protected function addClient($socket, $flag, $base)
 {
     $connection = stream_socket_accept($socket);
     stream_set_blocking($connection, 0);
     $id = md5(time() . rand() . $flag);
     $client = new $this->client_type($this, $id, $connection);
     $buffer = event_buffer_new($connection, [$this, 'read'], NULL, [$this, 'error'], $client);
     event_buffer_base_set($buffer, $base);
     event_buffer_timeout_set($buffer, self::CONNECTION_TIMEOUT, self::CONNECTION_TIMEOUT);
     event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
     event_buffer_priority_set($buffer, self::EVENT_PRIORITY);
     event_buffer_enable($buffer, EV_READ | EV_PERSIST);
     $client->setBuffer($buffer);
 }
Esempio n. 6
0
 public function accept($socket, $flag, $base)
 {
     Logger::getInstance()->outDebug("Try to accept new connection.");
     $this->id++;
     $connection = stream_socket_accept($socket);
     stream_set_blocking($connection, 0);
     $buffer = event_buffer_new($connection, array($this, 'onRead'), NULL, array($this, 'onError'), $this->id);
     event_buffer_base_set($buffer, $this->base);
     event_buffer_timeout_set($buffer, 180, 180);
     event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
     event_buffer_priority_set($buffer, 10);
     event_buffer_enable($buffer, EV_READ | EV_PERSIST);
     $this->connections[$this->id] = $connection;
     $this->buffers[$this->id] = $buffer;
 }
Esempio n. 7
0
function ev_accept($socket, $flag, $base)
{
    static $id = 0;
    $connection = stream_socket_accept($socket);
    stream_set_blocking($connection, 0);
    $id += 1;
    $buffer = event_buffer_new($connection, 'ev_read', NULL, 'ev_error', $id);
    event_buffer_base_set($buffer, $base);
    event_buffer_timeout_set($buffer, 30, 30);
    event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
    event_buffer_priority_set($buffer, 10);
    event_buffer_enable($buffer, EV_READ | EV_PERSIST);
    // we need to save both buffer and connection outside
    $GLOBALS['connections'][$id] = $connection;
    $GLOBALS['buffers'][$id] = $buffer;
}
 function ev_accept($socket, $flag, $base)
 {
     static $id = 0;
     $connection = stream_socket_accept($socket);
     stream_set_blocking($connection, 0);
     $id++;
     // increase on each accept
     $buffer = event_buffer_new($connection, array(__CLASS__, 'ev_read'), array(__CLASS__, 'ev_write'), array(__CLASS__, 'ev_error'), $id);
     event_buffer_base_set($buffer, $base);
     event_buffer_timeout_set($buffer, 30, 30);
     event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
     event_buffer_priority_set($buffer, 10);
     event_buffer_enable($buffer, EV_READ | EV_PERSIST);
     // we need to save both buffer and connection outside
     self::$connections[$id] = $connection;
     self::$buffers[$id] = $buffer;
 }
 public function ev_accept($socket, $flag, $base)
 {
     static $id = 0;
     // stream_socket_accept — 接受由 stream_socket_server() 创建的套接字连接
     $connection = stream_socket_accept($socket);
     stream_set_blocking($connection, 0);
     $id++;
     // event_buffer_new — Create new buffered event
     $buffer = event_buffer_new($connection, [__CLASS__, 'ev_read'], [__CLASS__, 'ev_write'], [__CLASS__, 'ev_error'], $id);
     // event_buffer_base_set — Associate buffered event with an event base
     event_buffer_base_set($buffer, $base);
     // event_buffer_timeout_set — Set read and write timeouts for a buffered event
     event_buffer_timeout_set($buffer, 30, 30);
     // event_buffer_watermark_set — Set the watermarks for read and write events
     event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
     // event_buffer_priority_set — Assign a priority to a buffered event
     event_buffer_priority_set($buffer, 10);
     // event_buffer_enable — Enable a buffered event
     event_buffer_enable($buffer, EV_READ | EV_PERSIST);
     self::$connections[$id] = $connection;
     self::$buffers[$id] = $buffer;
 }
 /**
  * Obsluga nowych polaczen
  * @param resource (stream) $pSock             socket wykorzystywany do komunikacji
  * @param int $pFlag                           flaga okreslajaca zdarzenie 
  *                                             {EV_TIMEOUT, EV_SIGNAL, EV_READ, EV_WRITE, EV_PERSIST}
  * @param resource (event base) $pBase         zdarzenie bazowe
  * @return boolean                             czy obsluzono nowe polaczenie
  */
 private function onConnection($pSock, $pFlag, $pBase)
 {
     // jesli za duzo polaczen, czekamy az beda jakies dostepne
     if (count($this->connections) == $this->maxConnections) {
         return false;
     }
     // unikalny identyfikator polaczenia
     static $connection_id = 0;
     $connection_id++;
     $sock = stream_socket_accept($pSock);
     stream_set_blocking($sock, 0);
     $buffer = event_buffer_new($sock, [$this, 'onRead'], null, [$this, 'onError'], $connection_id);
     event_buffer_base_set($buffer, $pBase);
     if ($this->timeout > 0) {
         event_buffer_timeout_set($buffer, $this->timeout, $this->timeout);
     }
     event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
     event_buffer_enable($buffer, EV_READ | EV_PERSIST);
     $connection = new DaemonConnection($connection_id, $sock);
     $connection->setEventBuffer($buffer);
     $this->setConnection($connection);
     $this->log("New connection (id = " . $connection_id . ")...");
     return true;
 }
Esempio n. 11
0
 public function setWatermark($low = null, $high = null)
 {
     if ($low != null) {
         $this->lowMark = $low;
     }
     if ($high != null) {
         $this->highMark = $high;
     }
     event_buffer_watermark_set($this->buffer, EV_READ, $this->lowMark, $this->highMark);
 }
Esempio n. 12
0
 public function onAcceptEvent($stream, $events, $arg)
 {
     $sockId = $arg[0];
     if (Daemon::$settings['logevents']) {
         Daemon::log('[WORKER ' . Daemon::$worker->pid . '] ' . get_class($this) . '::' . __METHOD__ . '(' . $sockId . ') invoked.');
     }
     if ($this->checkAccept()) {
         Daemon::$worker->addEvent($this->socketEvents[$sockId]);
     }
     if (Daemon::$useSockets) {
         $conn = @socket_accept($stream);
         if (!$conn) {
             return;
         }
         socket_set_nonblock($conn);
         if (Daemon::$sockets[$sockId][1] === 2) {
             $addr = '';
         } else {
             socket_getpeername($conn, $host, $port);
             $addr = $host === '' ? '' : $host . ':' . $port;
         }
     } else {
         $conn = @stream_socket_accept($stream, 0, $addr);
         if (!$conn) {
             return;
         }
         stream_set_blocking($conn, 0);
     }
     if (!$this->onAccept(Daemon::$worker->connCounter + 1, $addr)) {
         Daemon::log('Connection is not allowed (' . $addr . ')');
         if (Daemon::$useSockets) {
             socket_close($conn);
         } else {
             fclose($conn);
         }
         return;
     }
     $connId = ++Daemon::$worker->connCounter;
     Daemon::$worker->pool[$connId] = $conn;
     Daemon::$worker->poolApp[$connId] = $this;
     $this->poolQueue[$connId] = array();
     $this->poolState[$connId] = array();
     if ($this->directReads) {
         $ev = event_new();
         if (!event_set($ev, Daemon::$worker->pool[$connId], EV_READ | EV_PERSIST, array($this, 'onReadEvent'), $connId)) {
             Daemon::log(get_class($this) . '::' . __METHOD__ . ': Couldn\'t set event on accepted socket #' . $connId);
             return;
         }
         event_base_set($ev, Daemon::$worker->eventBase);
         event_add($ev);
         $this->readEvents[$connId] = $ev;
     }
     $buf = event_buffer_new(Daemon::$worker->pool[$connId], $this->directReads ? NULL : array($this, 'onReadEvent'), array($this, 'onWriteEvent'), array($this, 'onFailureEvent'), array($connId));
     if (!event_buffer_base_set($buf, Daemon::$worker->eventBase)) {
         throw new Exception('Couldn\'t set base of buffer.');
     }
     event_buffer_priority_set($buf, 10);
     event_buffer_watermark_set($buf, EV_READ, $this->initialLowMark, $this->initialHighMark);
     event_buffer_enable($buf, $this->directReads ? EV_WRITE | EV_PERSIST : EV_READ | EV_WRITE | EV_PERSIST);
     $this->buf[$connId] = $buf;
     $this->onAccepted($connId, $addr);
 }
Esempio n. 13
0
 public function ev_accept($socket, $flag, $argument)
 {
     $this->log("ev_accept(..., {$flag}, ...)");
     $to = ini_get("default_socket_timeout");
     $connection = stream_socket_accept($socket, $to, $peer);
     stream_set_blocking($connection, 0);
     $readCb = array($this, 'ev_read');
     $writeCb = array($this, 'ev_write');
     $errCb = array($this, 'ev_error');
     $id = uniqid();
     $buffer = event_buffer_new($connection, $readCb, $writeCb, $errCb, $id);
     event_buffer_base_set($buffer, $this->base);
     event_buffer_timeout_set($buffer, self::TIMEOUT_SECONDS, self::TIMEOUT_SECONDS);
     event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
     event_buffer_priority_set($buffer, 10);
     event_buffer_enable($buffer, EV_READ | EV_PERSIST);
     $this->fire('connection', $connection);
     $request = new ServerRequest($this->base);
     $request->client_id = $id;
     $request->server = $this;
     $request->connection = $connection;
     $request->ev_buffer = $buffer;
     $request->peer = $peer;
     $response = new ServerResponse($request);
     $response->client_id = $id;
     $response->server = $this;
     $response->connection = $connection;
     $response->ev_buffer = $buffer;
     $this->clients[$id] = array('socket' => $connection, 'buffer' => $buffer, 'request' => $request, 'response' => $response, 'disconnect' => false);
 }
Esempio n. 14
0
/**
 * Handle new connection events. Add new clients to the list. The server will write a welcome message to each client
 * Sets the following functions to handle I/O events
 * 'ev_read()', 'ev_write()', 'ev_error()'
 *
 * @param $socket resource
 * @param $flag   int A flag indicating the event. Consists of the following flags: EV_TIMEOUT, EV_SIGNAL, EV_READ, EV_WRITE and EV_PERSIST.
 * @param $base   resource created by event_base_new()
 */
function ev_accept($socket, $flag, $base)
{
    global $clients;
    static $next_id = 0;
    $connection = stream_socket_accept($socket);
    stream_set_blocking($connection, 0);
    $next_id++;
    $buffer = event_buffer_new($connection, 'ev_read', 'ev_write', 'ev_error', $next_id);
    event_buffer_base_set($buffer, $base);
    event_buffer_timeout_set($buffer, GSMTP_TIMEOUT, GSMTP_TIMEOUT);
    event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
    event_buffer_priority_set($buffer, 10);
    event_buffer_enable($buffer, EV_READ | EV_PERSIST);
    $clients[$next_id]['socket'] = $connection;
    // new socket
    $clients[$next_id]['ev_buffer'] = $buffer;
    // new socket
    $clients[$next_id]['state'] = 0;
    $clients[$next_id]['mail_from'] = '';
    $clients[$next_id]['helo'] = '';
    $clients[$next_id]['rcpt_to'] = '';
    $clients[$next_id]['error_c'] = 0;
    $clients[$next_id]['read_buffer'] = '';
    $clients[$next_id]['read_buffer_ready'] = false;
    // true if the buffer is ready to be fetched
    $clients[$next_id]['response'] = '';
    // response messages are placed here, before they go on the write buffer
    $clients[$next_id]['time'] = time();
    $address = stream_socket_get_name($clients[$next_id]['socket'], true);
    $clients[$next_id]['address'] = $address;
    process_smtp($next_id);
    if (strlen($clients[$next_id]['response']) > 0) {
        event_buffer_write($buffer, $clients[$next_id]['response']);
        add_response($next_id, null);
    }
}
Esempio n. 15
0
 /**
  * 添加事件
  * @see BaseEvent::add()
  */
 public function add($fd, $flag, $func, $args = null, $read_timeout = 1000, $write_timeout = 1000)
 {
     $event_key = (int) $fd;
     $real_flag = EV_READ | EV_PERSIST;
     switch ($flag) {
         // 链接事件
         case self::EV_ACCEPT:
             break;
             // 数据可读事件
         // 数据可读事件
         case self::EV_READ:
             $this->eventBuffer[$event_key] = event_buffer_new($fd, array($this, 'bufferCallBack'), NULL, array($this, 'bufferCallBackErr'), array('args' => $args, 'func' => $func, 'fd' => $fd));
             event_buffer_base_set($this->eventBuffer[$event_key], $this->eventBase);
             event_buffer_timeout_set($this->eventBuffer[$event_key], ceil($read_timeout / 1000), ceil($write_timeout / 1000));
             event_buffer_watermark_set($this->eventBuffer[$event_key], EV_READ, 0, 0xffffff);
             // event_buffer_priority_set($this->eventBuffer[$event_key], 10);
             event_buffer_enable($this->eventBuffer[$event_key], EV_READ | EV_PERSIST);
             return true;
             // 数据可写事件,这个事件目前没有用到
         // 数据可写事件,这个事件目前没有用到
         case self::EV_WRITE:
             $real_flag = EV_WRITE | EV_PERSIST;
             break;
             // 信号监听事件
         // 信号监听事件
         case self::EV_SIGNAL:
             $real_flag = EV_SIGNAL | EV_PERSIST;
             // 创建一个用于监听的event
             $this->eventSignal[$event_key] = event_new();
             // 设置监听处理函数
             if (!event_set($this->eventSignal[$event_key], $fd, $real_flag, $func, $args)) {
                 return false;
             }
             // 设置event base
             if (!event_base_set($this->eventSignal[$event_key], $this->eventBase)) {
                 return false;
             }
             // 添加事件
             if (!event_add($this->eventSignal[$event_key])) {
                 return false;
             }
             return true;
             break;
             // 监控文件描述符可读事件
         // 监控文件描述符可读事件
         case self::EV_NOINOTIFY:
             $real_flag = EV_READ | EV_PERSIST;
             break;
     }
     // 创建一个用于监听的event
     $this->allEvents[$event_key][$flag] = event_new();
     // 设置监听处理函数
     if (!event_set($this->allEvents[$event_key][$flag], $fd, $real_flag, $func, $args)) {
         return false;
     }
     // 设置event base
     if (!event_base_set($this->allEvents[$event_key][$flag], $this->eventBase)) {
         return false;
     }
     // 添加事件
     if (!event_add($this->allEvents[$event_key][$flag])) {
         return false;
     }
     return true;
 }
Esempio n. 16
0
 /**
  * Calling this method will make sure that the onRead callback is only
  * called when the buffersize exceeds the given argument.
  *
  * @param int $bufferSize
  * @return void
  */
 public function setReadBufferSize($bufferSize)
 {
     event_buffer_watermark_set($this->resource, self::READ, $bufferSize, null);
 }
Esempio n. 17
0
 public function readConn($connId)
 {
     static $roles = array(1 => 'FCGI_RESPONDER', 2 => 'FCGI_AUTHORIZER', 3 => 'FCGI_FILTER');
     static $reqtypes = array(1 => 'FCGI_BEGIN_REQUEST', 2 => 'FCGI_ABORT_REQUEST', 3 => 'FCGI_END_REQUEST', 4 => 'FCGI_PARAMS', 5 => 'FCGI_STDIN', 6 => 'FCGI_STDOUT', 7 => 'FCGI_STDERR', 8 => 'FCGI_DATA', 9 => 'FCGI_GET_VALUES', 10 => 'FCGI_GET_VALUES_RESULT', 11 => 'FCGI_UNKNOWN_TYPE', 11 => 'FCGI_MAXTYPE');
     $state = sizeof($this->poolState[$connId]);
     if ($state === 0) {
         $header = $this->read($connId, 8);
         if ($header === FALSE) {
             return;
         }
         $r = unpack('Cver/Ctype/nreqid/nconlen/Cpadlen/Creserved', $header);
         if ($r['conlen'] > 0) {
             event_buffer_watermark_set($this->buf[$connId], EV_READ, $r['conlen'], 0xffffff);
         }
         $this->poolState[$connId][0] = $r;
         ++$state;
     } else {
         $r = $this->poolState[$connId][0];
     }
     if ($state === 1) {
         $c = $r['conlen'] === 0 ? '' : $this->read($connId, $r['conlen']);
         if ($c === FALSE) {
             return;
         }
         if ($r['padlen'] > 0) {
             event_buffer_watermark_set($this->buf[$connId], EV_READ, $r['padlen'], 0xffffff);
         }
         $this->poolState[$connId][1] = $c;
         ++$state;
     } else {
         $c = $this->poolState[$connId][1];
     }
     if ($state === 2) {
         $pad = $r['padlen'] === 0 ? '' : $this->read($connId, $r['padlen']);
         if ($pad === FALSE) {
             return;
         }
         $this->poolState[$connId][2] = $pad;
     } else {
         $pad = $this->poolState[$connId][2];
     }
     $this->poolState[$connId] = array();
     $type =& $r['type'];
     $r['ttype'] = isset($reqtypes[$type]) ? $reqtypes[$type] : $type;
     $rid = $connId . '-' . $r['reqid'];
     if (Daemon::$settings['mod' . $this->modname . 'logrecords']) {
         Daemon::log('[DEBUG] FastCGI-record #' . $r['type'] . ' (' . $r['ttype'] . '). Request ID: ' . $rid . '. Content length: ' . $r['conlen'] . ' (' . strlen($c) . ') Padding length: ' . $r['padlen'] . ' (' . strlen($pad) . ')');
     }
     if ($type == 1) {
         ++Daemon::$worker->queryCounter;
         $rr = unpack('nrole/Cflags', $c);
         $req = new stdClass();
         $req->attrs = new stdClass();
         $req->attrs->request = array();
         $req->attrs->get = array();
         $req->attrs->post = array();
         $req->attrs->cookie = array();
         $req->attrs->server = array();
         $req->attrs->files = array();
         $req->attrs->session = NULL;
         $req->attrs->connId = $connId;
         $req->attrs->trole = $roles[$rr['role']];
         $req->attrs->flags = $rr['flags'];
         $req->attrs->id = $r['reqid'];
         $req->attrs->params_done = FALSE;
         $req->attrs->stdin_done = FALSE;
         $req->attrs->stdinbuf = '';
         $req->attrs->stdinlen = 0;
         $req->attrs->chunked = FALSE;
         if (Daemon::$settings['mod' . $this->modname . 'logqueue']) {
             Daemon::log('[WORKER ' . Daemon::$worker->pid . '] new request queued.');
         }
         Daemon::$worker->queue[$rid] = $req;
         $this->poolQueue[$connId][$req->attrs->id] = $req;
     } elseif (isset(Daemon::$worker->queue[$rid])) {
         $req = Daemon::$worker->queue[$rid];
     } else {
         Daemon::log('Unexpected FastCGI-record #' . $r['type'] . ' (' . $r['ttype'] . '). Request ID: ' . $rid . '.');
         return;
     }
     if ($type === 2) {
         $req->abort();
     } elseif ($type === 4) {
         if ($c === '') {
             $req->attrs->params_done = TRUE;
             $req = Daemon::$appResolver->getRequest($req, $this);
             if ($req instanceof stdClass) {
                 $this->endRequest($req, 0, 0);
                 unset(Daemon::$worker->queue[$rid]);
             } else {
                 if (Daemon::$settings['mod' . $this->modname . 'sendfile'] && (!Daemon::$settings['mod' . $this->modname . 'sendfileonlybycommand'] || isset($req->attrs->server['USE_SENDFILE'])) && !isset($req->attrs->server['DONT_USE_SENDFILE'])) {
                     $fn = tempnam(Daemon::$settings['mod' . $this->modname . 'sendfiledir'], Daemon::$settings['mod' . $this->modname . 'sendfileprefix']);
                     $req->sendfp = fopen($fn, 'wb');
                     $req->header('X-Sendfile: ' . $fn);
                 }
                 Daemon::$worker->queue[$rid] = $req;
             }
         } else {
             $p = 0;
             while ($p < $r['conlen']) {
                 if (($namelen = ord($c[$p])) < 128) {
                     ++$p;
                 } else {
                     $u = unpack('Nlen', chr(ord($c[$p]) & 0x7f) . binarySubstr($c, $p + 1, 3));
                     $namelen = $u['len'];
                     $p += 4;
                 }
                 if (($vlen = ord($c[$p])) < 128) {
                     ++$p;
                 } else {
                     $u = unpack('Nlen', chr(ord($c[$p]) & 0x7f) . binarySubstr($c, $p + 1, 3));
                     $vlen = $u['len'];
                     $p += 4;
                 }
                 $req->attrs->server[binarySubstr($c, $p, $namelen)] = binarySubstr($c, $p + $namelen, $vlen);
                 $p += $namelen + $vlen;
             }
         }
     } elseif ($type === 5) {
         if ($c === '') {
             $req->attrs->stdin_done = TRUE;
         }
         $req->stdin($c);
     }
     if ($req->attrs->stdin_done && $req->attrs->params_done) {
         if (($order = ini_get('request_order')) || ($order = ini_get('variables_order'))) {
             for ($i = 0, $s = strlen($order); $i < $s; ++$i) {
                 $char = $order[$i];
                 if ($char == 'G') {
                     $req->attrs->request += $req->attrs->get;
                 } elseif ($char == 'P') {
                     $req->attrs->request += $req->attrs->post;
                 } elseif ($char == 'C') {
                     $req->attrs->request += $req->attrs->cookie;
                 }
             }
         } else {
             $req->attrs->request = $req->attrs->get + $req->attrs->post + $req->attrs->cookie;
         }
         $this->timeLastReq = time();
     }
 }
 protected function InitSocket()
 {
     stream_set_blocking($this->Socket, 0);
     stream_set_read_buffer($this->Socket, 4096);
     stream_set_write_buffer($this->Socket, 4096);
     $this->BufferEvent = event_buffer_new($this->Socket, array($this, 'evcb_doReceive'), array($this, 'evcb_WriteFin'), array($this, 'evcb_ClientBufferError'), $this->Socket);
     if (!$this->BufferEvent) {
         //            echo "Buffer Event Error $this\n";
         @stream_socket_shutdown($this->Socket, STREAM_SHUT_RDWR);
         @fclose($this->Socket);
     }
     event_buffer_watermark_set($this->BufferEvent, EV_WRITE, 1, 1);
     event_buffer_base_set($this->BufferEvent, $this->BaseEvent);
     event_buffer_enable($this->BufferEvent, EV_READ | EV_WRITE);
     $this->Server->IncCurrentConnected();
 }
Esempio n. 19
0
 private function master($connection, $flag, $base)
 {
     $connectionId = $this->getIdByConnection($connection);
     $buffer = event_buffer_new($connection, array($this, 'onRead'), array($this, 'onWrite'), array($this, 'onError'), $connectionId);
     event_buffer_base_set($buffer, $this->base);
     event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
     event_buffer_priority_set($buffer, 10);
     event_buffer_enable($buffer, EV_READ | EV_WRITE | EV_PERSIST);
     $this->buffers[$connectionId] = $buffer;
     event_del($this->master_event);
     event_free($this->master_event);
     unset($this->master_event);
 }
Esempio n. 20
0
 /**
  * Set the marks for read and write events.
  *
  * Libevent does not invoke read callback unless there is at least lowmark
  * bytes in the input buffer; if the read buffer is beyond the highmark,
  * reading is stopped. On output, the write callback is invoked whenever
  * the buffered data falls below the lowmark
  *
  * @see event_buffer_timeout_set
  *
  * @throws EventException
  *
  * @param int $events   Any combination of EV_READ and EV_WRITE.
  * @param int $lowmark  Low watermark.
  * @param int $highmark High watermark.
  *
  * @return EventBuffer
  */
 public function setWatermark($events, $lowmark = self::DEFAULT_LOWMARK, $highmark = self::DEFAULT_HIGHMARK)
 {
     event_buffer_watermark_set($this->resource, $events, $lowmark, $highmark);
     return $this;
 }
Esempio n. 21
0
 private function monitor($conn, $buffer)
 {
     event_buffer_set_callback($buffer, [$this, 'readcb'], null, [$this, 'errorcb'], $conn);
     event_buffer_timeout_set($buffer, 1200, 1200);
     event_buffer_watermark_set($buffer, EV_READ, 1, null);
     event_buffer_enable($buffer, EV_READ | EV_PERSIST | EVLOOP_NONBLOCK);
     unset($this->unauthorized[(int) $conn]);
     $this->buffers[(int) $conn] = $buffer;
 }
Esempio n. 22
0
 public function writeMask($low = NULL, $high = NULL)
 {
     if ($low === NULL) {
         $low = 1;
     }
     if ($high === NULL) {
         $high = 0xffffff;
     }
     if (!event_buffer_watermark_set($this->writeBuf, EV_WRITE, $low, $high)) {
         throw new Exception('writeMask(' . $low . ',' . $high . ') failed.');
     }
     return $this;
 }
Esempio n. 23
0
 public function read_request_header()
 {
     $header = event_buffer_read($this->offer_event, 4);
     $length = current(unpack('N', $header));
     if ($length > $this->max_message_length) {
         error_log("Worker {$this->worker_pid} received request length {$length}, aborting");
         exit(0);
     }
     event_buffer_watermark_set($this->offer_event, EV_READ, $length, $length);
     event_buffer_set_callback($this->offer_event, array($this, 'read_request'), null, array($this, 'read_request_error'), $length);
     event_buffer_enable($this->offer_event, EV_READ);
 }
Esempio n. 24
0
 /**
  * Reads data from the connection's buffer.
  * @param integer Connection's ID.
  * @return void
  */
 public function readConn($connId)
 {
     $state = sizeof($this->poolState[$connId]);
     if ($state === 0) {
         $header = $this->read($connId, 8);
         if ($header === false) {
             return;
         }
         $r = unpack('Cver/Ctype/nreqid/nconlen/Cpadlen/Creserved', $header);
         if ($r['conlen'] > 0) {
             event_buffer_watermark_set($this->buf[$connId], EV_READ, $r['conlen'], 0xffffff);
         }
         $this->poolState[$connId][0] = $r;
         ++$state;
     } else {
         $r = $this->poolState[$connId][0];
     }
     if ($state === 1) {
         $c = $r['conlen'] === 0 ? '' : $this->read($connId, $r['conlen']);
         if ($c === false) {
             return;
         }
         if ($r['padlen'] > 0) {
             event_buffer_watermark_set($this->buf[$connId], EV_READ, $r['padlen'], 0xffffff);
         }
         $this->poolState[$connId][1] = $c;
         ++$state;
     } else {
         $c = $this->poolState[$connId][1];
     }
     if ($state === 2) {
         $pad = $r['padlen'] === 0 ? '' : $this->read($connId, $r['padlen']);
         if ($pad === false) {
             return;
         }
         $this->poolState[$connId][2] = $pad;
     } else {
         $pad = $this->poolState[$connId][2];
     }
     $this->poolState[$connId] = array();
     $type =& $r['type'];
     $r['ttype'] = isset(self::$requestTypes[$type]) ? self::$requestTypes[$type] : $type;
     $rid = $connId . '-' . $r['reqid'];
     if ($this->config->logrecords->value) {
         Daemon::log('[DEBUG] FastCGI-record #' . $r['type'] . ' (' . $r['ttype'] . '). Request ID: ' . $rid . '. Content length: ' . $r['conlen'] . ' (' . strlen($c) . ') Padding length: ' . $r['padlen'] . ' (' . strlen($pad) . ')');
     }
     if ($type == self::FCGI_BEGIN_REQUEST) {
         ++Daemon::$process->reqCounter;
         $rr = unpack('nrole/Cflags', $c);
         $req = new stdClass();
         $req->attrs = new stdClass();
         $req->attrs->request = array();
         $req->attrs->get = array();
         $req->attrs->post = array();
         $req->attrs->cookie = array();
         $req->attrs->server = array();
         $req->attrs->files = array();
         $req->attrs->session = null;
         $req->attrs->connId = $connId;
         $req->attrs->trole = self::$roles[$rr['role']];
         $req->attrs->flags = $rr['flags'];
         $req->attrs->id = $r['reqid'];
         $req->attrs->params_done = false;
         $req->attrs->stdin_done = false;
         $req->attrs->stdinbuf = '';
         $req->attrs->stdinlen = 0;
         $req->attrs->chunked = false;
         $req->attrs->noHttpVer = true;
         $req->queueId = $rid;
         if ($this->config->logqueue->value) {
             Daemon::$process->log('new request queued.');
         }
         Daemon::$process->queue[$rid] = $req;
         $this->poolQueue[$connId][$req->attrs->id] = $req;
     } elseif (isset(Daemon::$process->queue[$rid])) {
         $req = Daemon::$process->queue[$rid];
     } else {
         Daemon::log('Unexpected FastCGI-record #' . $r['type'] . ' (' . $r['ttype'] . '). Request ID: ' . $rid . '.');
         return;
     }
     if ($type === self::FCGI_ABORT_REQUEST) {
         $req->abort();
     } elseif ($type === self::FCGI_PARAMS) {
         if ($c === '') {
             $req->attrs->params_done = true;
             $req = Daemon::$appResolver->getRequest($req, $this);
             if ($req instanceof stdClass) {
                 $this->endRequest($req, 0, 0);
                 unset(Daemon::$process->queue[$rid]);
             } else {
                 if ($this->config->sendfile->value && (!$this->config->sendfileonlybycommand->value || isset($req->attrs->server['USE_SENDFILE'])) && !isset($req->attrs->server['DONT_USE_SENDFILE'])) {
                     $fn = tempnam($this->config->sendfiledir->value, $this->config->sendfileprefix->value);
                     $req->sendfp = fopen($fn, 'wb');
                     $req->header('X-Sendfile: ' . $fn);
                 }
                 Daemon::$process->queue[$rid] = $req;
             }
         } else {
             $p = 0;
             while ($p < $r['conlen']) {
                 if (($namelen = ord($c[$p])) < 128) {
                     ++$p;
                 } else {
                     $u = unpack('Nlen', chr(ord($c[$p]) & 0x7f) . binarySubstr($c, $p + 1, 3));
                     $namelen = $u['len'];
                     $p += 4;
                 }
                 if (($vlen = ord($c[$p])) < 128) {
                     ++$p;
                 } else {
                     $u = unpack('Nlen', chr(ord($c[$p]) & 0x7f) . binarySubstr($c, $p + 1, 3));
                     $vlen = $u['len'];
                     $p += 4;
                 }
                 $req->attrs->server[binarySubstr($c, $p, $namelen)] = binarySubstr($c, $p + $namelen, $vlen);
                 $p += $namelen + $vlen;
             }
         }
     } elseif ($type === self::FCGI_STDIN) {
         if ($c === '') {
             $req->attrs->stdin_done = true;
         }
         $req->stdin($c);
     }
     if ($req->attrs->stdin_done && $req->attrs->params_done) {
         if ($this->variablesOrder === null) {
             $req->attrs->request = $req->attrs->get + $req->attrs->post + $req->attrs->cookie;
         } else {
             for ($i = 0, $s = strlen($this->variablesOrder); $i < $s; ++$i) {
                 $char = $this->variablesOrder[$i];
                 if ($char == 'G') {
                     $req->attrs->request += $req->attrs->get;
                 } elseif ($char == 'P') {
                     $req->attrs->request += $req->attrs->post;
                 } elseif ($char == 'C') {
                     $req->attrs->request += $req->attrs->cookie;
                 }
             }
         }
         Daemon::$process->timeLastReq = time();
     }
 }