public function test_run() { $result = true; try { ob_start(); \veneer\app::run(); $output = ob_get_clean(); } catch (\Exception $e) { $result = false; } $this->assertTrue($result); }
/** * Main server method. This will loop as long as there is a master server * socket present and handle the flow of incoming requests. * * @param integer $max_request_size The maximum size (in bytes) of a request * @return bool */ public function server($max_request_size = 4096) { $r = array($this->socket); while (socket_select($r, $w = NULL, $e = NULL, $this->timeout) !== false) { $client = socket_accept($this->socket); /** * Since this is HTTP over sockets, you can't just assume that all of the * data will be sent in one packet and gathered with one recv(). Here we * parse the HTTP request according to RFC2616 (HTTP Message / Hypertext * Transfer Protocol -- HTTP/1.1) to read chunked messages and length * headers to read continuously until all parts of the HTTP message have * been received. */ $complete = false; $buf = $input = ''; while (!$complete) { $buf = socket_read($client, (int) $max_request_size); $input .= $buf; $request = \veneer\http\request::from_message($input); if (!$request) { continue; } if (array_key_exists('content-length', $request['headers'])) { $complete = strlen($request['body']) == $request['headers']['content-length']; } else { $complete = true; } } socket_getsockname($client, $request['http_host'], $request['server_port']); socket_getpeername($client, $request['remote_addr'], $request['remote_port']); self::set_environment($request); ob_start(); \veneer\app::run(); $response = ob_get_clean(); socket_write($client, $response); $status = preg_replace('~^[^\\s]+\\s~', '', array_shift(explode("\n", $response))); self::debug("[{$_SERVER['REMOTE_ADDR']}] " . "{$_SERVER['REQUEST_METHOD']} " . "{$_SERVER['REQUEST_URI']} - {$status}"); /** * Close the socket and add the master server socket back into the pool. The * socket_select() function modifies data passed to it so the master server * socket needs to be re-added. */ socket_close($client); $r = array($this->socket); self::reset(); } }
/** * Discover route matches and invoke any corresponding methods found. * Handles route parsing and route parameters using some simple * regular expression pattern matching and function calling. * * @param string $method The URL bit to match routes against * @param \veneer\http\response $response Response object * @return bool */ public function invoke($method, \veneer\http\response &$response) { $method = trim($method, '/'); $request = explode('/', $method); $this->response =& $response; $router = new \veneer\router(); $request_method = array_key_exists('REQUEST_METHOD', $_SERVER) ? strtolower($_SERVER['REQUEST_METHOD']) : 'get'; foreach (array('get', 'post', 'put', 'delete') as $http_method) { if ($http_method == $request_method) { if (isset($this->{$http_method})) { foreach ($this->{$http_method} as $route => $data) { $router->add_route($http_method, $route, $data); } } } } $data = null; $params = array(); $router->select_route($method, $data, $params); if (is_array($data) && array_key_exists('output_handler_param', $data)) { $handler_param = $data['output_handler_param']; } else { $handler_param = \veneer\app::get_default('output_handler_param'); } if (is_array($data) && array_key_exists('output_handler', $data)) { $default_handler = $data['output_handler']; } else { $default_handler = \veneer\app::get_default('output_handler'); } $this->response->configure_handler($handler_param, $default_handler, $this->request_params); $params = array_merge($this->request_params, $params); if ($fn = self::validate($data, $params)) { if (method_exists($this, $fn)) { call_user_func(array($this, $fn), $params); } } if (!$this->response->is_set()) { if ($request_method == 'options') { $this->response->set($this->retrieve_detail(), 200); } else { $this->response->set('Incomplete response data returned by endpoint', 500); } } }