/** * @param \swoole_server $serv * @param $fd * @param $from_id * @param $data */ function onReceive($serv, $fd, $from_id, $data) { $parser = new \HttpParser(); if (empty($this->buffers[$fd])) { $this->clearBuffer($fd); } $this->buffers[$fd] .= $data; $buffer =& $this->buffers[$fd]; $nparsed =& $this->nparsed[$fd]; $nparsed = $parser->execute($buffer, $nparsed); if ($parser->hasError()) { $serv->close($fd, $from_id); } else { if ($parser->isFinished()) { $this->clearBuffer($fd); $_SERVER = $parser->getEnvironment(); $_GET = array(); if (!empty($_SERVER['QUERY_STRING'])) { parse_str($_SERVER['QUERY_STRING'], $_GET); } if (!empty($_SERVER['REQUEST_BODY'])) { parse_str($_SERVER['REQUEST_BODY'], $_POST); } if (!empty($_SERVER['HTTP_COOKIE'])) { $_COOKIE = self::parseCookie($_SERVER['HTTP_COOKIE']); } $this->currentFd = $fd; call_user_func($this->_onRequest, $this); } } }
/** * Start serving requests to the application * @param callable */ public function start($app) { if (!($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) { throw new Exception(socket_strerror(socket_last_error())); } if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) { throw new Exception(socket_strerror(socket_last_error())); } if (!socket_bind($socket, $this->_host, $this->_port)) { throw new Exception(socket_strerror(socket_last_error())); } if (!socket_listen($socket)) { throw new Exception(socket_strerror(socket_last_error())); } while ($client = socket_accept($socket)) { $data = ''; $nparsed = 0; $h = new \HttpParser(); while ($d = socket_read($client, 1024 * 1024 * 1024)) { $data .= $d; $nparsed = $h->execute($data, $nparsed); if ($h->isFinished()) { break; } if ($h->hasError()) { socket_close($client); continue 2; // Skip to accept next connection.. } } $env = $h->getEnvironment(); global $argv; $env['SERVER_NAME'] = $this->_host; $env['SERVER_PORT'] = $this->_port; $env['SCRIPT_FILENAME'] = $argv[0]; socket_getpeername($client, $address); $env['REMOTE_ADDR'] = $address; list($status, $headers, $body) = call_user_func($app, $env); $response = new Response(); $response->setStatus($status); $response->setHeaders($headers); $response->setBody($body); foreach ($response as $chunk) { $len = strlen($chunk); $offset = 0; while ($offset < $len) { if (false === ($n = @socket_write($client, substr($chunk, $offset), $len - $offset))) { break 2; } $offset += $n; } } socket_close($client); } }
private function _child($socket, $app) { while ($client = socket_accept($socket)) { $data = ''; $nparsed = 0; $h = new HttpParser(); while ($d = socket_read($client, 1024 * 1024)) { $data .= $d; $nparsed = $h->execute($data, $nparsed); if ($h->isFinished()) { break; } if ($h->hasError()) { socket_close($client); continue 2; // } } $env = $h->getEnvironment(); $result = $app->call($env); $response = new Kelpie_Server_Response(); $response->setStatus($result[0]); $response->setHeaders($result[1]); $response->setBody($result[2]); foreach ($response as $chunk) { $len = strlen($chunk); $offset = 0; while ($offset < $len) { if (false === ($n = @socket_write($client, substr($chunk, $offset), $len - $offset))) { break 2; } $offset += $n; } } socket_close($client); } }