/** * Run a hash database server. * * @return void */ public function run() { while ($this->conn = stream_socket_accept($this->sock, -1.0)) { try { stream_set_timeout($this->conn, $this->timeoutSec, $this->timeoutUsec); /** * Receive and parse HTTP headers. */ $headers_string = ''; $line = ''; while (!feof($this->conn) && ($line = fgets($this->conn)) !== false) { if (strlen(trim($line)) == 0) { break; } $headers_string .= $line; } if ($line === false) { $info = stream_get_meta_data($this->conn); $code = $info['timed_out'] ? 408 : 400; throw new TCHDBRequestException(self::$statuses[$code], $code); } $headers = HttpUtil::parseHeaders($headers_string); //print_r($headers); if (!$headers || !isset($headers['Request Method']) || !isset($headers['Request Url']) || !isset($headers['Host'])) { throw new TCHDBRequestException(self::$statuses[400], 400); } /** * Decode an URL. */ $key = ltrim($headers['Request Url'], '/'); if (strlen($key) == 0) { throw new TCHDBRequestException(self::$statuses[400], 400); } $key = rawurldecode($key); /** * Handle a request. */ switch (strtoupper($headers['Request Method'])) { case 'GET': $this->handleGet($key); break; case 'PUT': $this->handlePut($key, $headers); break; case 'DELETE': $this->handleDelete($key); break; default: $this->returnStatus(405); } } catch (TCHDBRequestException $e) { $this->returnStatus($e->getCode(), $e->getMessage()); } catch (Exception $e) { $this->returnStatus(500, $e->getMessage()); } fclose($this->conn); } }