/** * Start serving requests to the application * @param Kelpie_Application */ public function start($app) { if (!($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) { throw new Kelpie_Server_Exception(socket_strerror(socket_last_error())); } if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) { throw new Kelpie_Server_Exception(socket_strerror(socket_last_error())); } if (!socket_bind($socket, $this->_host, $this->_port)) { throw new Kelpie_Server_Exception(socket_strerror(socket_last_error())); } if (!socket_listen($socket)) { throw new Kelpie_Server_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) = $app->call($env); $response = new Kelpie_Server_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); } }