Esempio n. 1
0
 /**
  * Handle the request
  *
  * @param  Aspamia_Http_Request $request
  * @return Aspamia_Http_Response
  */
 public function handle(Aspamia_Http_Request $request)
 {
     if ($this->_config['document_root']) {
         $document_root = $this->_config['document_root'];
     } else {
         $document_root = getcwd();
     }
     $file = rtrim($document_root, '/') . '/' . trim($request->getUri(), '/');
     if (!file_exists($file)) {
         // not found - 404
         return self::_errorResponse(404, "The requested URL does not exist");
     }
     if (!is_readable($file)) {
         // not readable - 403
         return self::_errorResponse(403, "You have no permissions to read the requested URL");
     }
     if (!$this->_config['follow_symlinks'] && is_link($file)) {
         // symlink and we can't follow - 404
         return self::_errorResponse(404, "The requested URL does not exist");
     }
     if (is_dir($file)) {
         // Directory - look for index file
         foreach ($this->_config['directory_index'] as $index) {
             $index = $file . '/' . $index;
             if (file_exists($index) && is_file($index)) {
                 return $this->_serveFile($index);
             }
         }
         // No index found - can we do directory listing?
         if ($this->_config['list_directories']) {
             return $this->_serveDirListing($file);
         } else {
             // Directory and can't list
             return self::_errorResponse(403, "Directory listing not allowed");
         }
     }
     if (is_file($file)) {
         return $this->_serveFile($file);
     } else {
         // So what the hell it is?
         require_once 'Aspamia/Http/Server/Handler/Exception.php';
         throw new Aspamia_Http_Server_Handler_Exception("No idea how to serve '{$file}'");
     }
 }
Esempio n. 2
0
 /**
  * Handle the request
  *
  * @param  Aspamia_Http_Request $request
  * @return Aspamia_Http_Response
  */
 public function handle(Aspamia_Http_Request $request)
 {
     if (!$this->_config['handler']) {
         require_once 'Aspamia/Http/Server/Handler/Exception.php';
         throw new Aspamia_Http_Server_Handler_Exception("No CGI handler was set");
     }
     if (isset($this->_config['document_root'])) {
         $document_root = $this->_config['document_root'];
     } else {
         $document_root = getcwd();
     }
     // Parse the URI
     $urlInfo = parse_url($request->getUri());
     // Build the translated path
     $script_path = rtrim($document_root, '/') . (isset($this->_config['handler_script']) ? '/' . ltrim($this->_config['handler_script']) : $urlInfo['path']);
     // Set up the environment
     $environment = array('SERVER_SOFTWARE ' => 'Aspamia/' . Aspamia_Http_Server::ASPAMIA_VERSION, 'SERVER_NAME' => $request->getLocalAddress(), 'SERVER_PROTOCOL' => 'HTTP/' . $request->getHttpVersion(), 'SERVER_PORT' => $this->_server->getConfig('bind_port'), 'DOCUMENT_ROOT' => $document_root, 'GATEWAY_INTERFACE' => 'CGI/1.1', 'REQUEST_METHOD' => $request->getMethod(), 'REQUEST_URI' => $request->getUri(), 'PATH_INFO' => $request->getUri(), 'PATH_TRANSLATED' => $script_path, 'SCRIPT_NAME' => $urlInfo['path'], 'REMOTE_ADDR' => $request->getRemoteAddress(), 'CONTENT_TYPE' => $request->getHeader('content-type'), 'CONTENT_LENGTH' => $request->getHeader('content-length'), 'PATH' => getenv('PATH'));
     if (isset($urlInfo['query'])) {
         $environment['QUERY_STRING'] = $urlInfo['query'];
     }
     // Add the HTTP headers to the environment
     $headers = $request->getAllHeaders();
     unset($headers['content-type'], $headers['content-length']);
     foreach ($headers as $header => $value) {
         $key = 'HTTP_' . strtoupper(strtr($header, '-', '_'));
         $environment[$key] = $value;
     }
     // Open the CGI handler process
     $cgi_proc = proc_open($this->_config['handler'], array(array('pipe', 'r'), array('pipe', 'w'), array('file', '/tmp/cgi-error.log', 'a')), $pipes, null, $environment);
     if (!$cgi_proc) {
         require_once 'Aspamia/Http/Server/Handler/Exception.php';
         throw new Aspamia_Http_Server_Handler_Exception("Unable to run CGI handler");
     }
     // Write body, if any, to the CGI STDIN
     fwrite($pipes[0], $request->getBody());
     fclose($pipes[0]);
     // Read the response headers
     $headerlines = Aspamia_Http_Message::readHeaders($pipes[1]);
     if (empty($headerlines)) {
         $headers = array('content-type' => 'text/plain', 'x-aspamia-message' => 'missing-cgi-headers');
         $code = 200;
         $message = 'Ok';
         $httpVersion = $request->getHttpVersion();
         $response = new Aspamia_Http_Response($code, $headerlines, '', $httpVersion, $message);
     } else {
         if (strpos($headerlines[0], 'HTTP/') === 0) {
             // Got a status line, use it
             $statusLine = explode(' ', array_shift($headerlines), 3);
             if (!count($statusLine) == 3) {
                 require_once 'Aspamia/Http/Server/Handler/Exception.php';
                 throw new Aspamia_Http_Server_Handler_Exception("Unable to read status line from CGI handler");
             }
             $code = (int) $statusLine[1];
             $message = $statusLine[2];
             $httpVersion = substr($statusLine[0], 5);
             $response = new Aspamia_Http_Response($code, $headerlines, '', $httpVersion, $message);
         } else {
             $response = new Aspamia_Http_Response(200, $headerlines, '', $request->getHttpVersion());
             if ($status = $response->getHeader('status')) {
                 $status = explode(' ', $status);
                 if (isset($status[0])) {
                     $response->setStatus((int) $status[0]);
                 }
                 if (isset($status[1])) {
                     $response->setMessage($status[1]);
                 }
                 $response->setHeader('status', false);
             }
         }
     }
     // Read the response body
     $body = stream_get_contents($pipes[1]);
     fclose($pipes[1]);
     // Close CGI process
     proc_close($cgi_proc);
     // Create the status line
     $response->setBody($body);
     $response->setHeader('content-length', strlen($body));
     return $response;
 }
Esempio n. 3
0
 protected function _readRequest($connection)
 {
     return Aspamia_Http_Request::read($connection);
 }
Esempio n. 4
0
 /**
  * Test that trying to set invalid header names throw an exception
  * 
  * @param string $header
  * 
  * @dataProvider      invalidHeaderProvider
  * @expectedException Aspamia_Http_Exception
  */
 public function testInvalidHeaderName($header)
 {
     $request = new Aspamia_Http_Request('GET', '/');
     $request->setHeader($header);
 }
Esempio n. 5
0
 /**
  * Try to match the request to a route
  * 
  * @param  string               $route
  * @param  Aspamia_Http_Request $request
  * @return boolean
  */
 protected function _routeMatch($route, $request)
 {
     return (bool) preg_match("#^{$route}#", $request->getUri());
 }
Esempio n. 6
0
 /**
  * Read an HTTP request from an open socket and return it as an object
  *
  * Will not read the full body unless explicitly asked to.
  * 
  * @param  resource $connection
  * @param  boolean  $read_body
  * @return Aspamia_Http_Request
  */
 public static function read($connection, $read_body = false)
 {
     // Get the local and remote address of the connection
     $localAddress = stream_socket_get_name($connection, false);
     $remoteAddress = stream_socket_get_name($connection, true);
     $headerlines = self::readHeaders($connection);
     if (empty($headerlines)) {
         require_once 'Aspamia/Http/Exception.php';
         throw new Aspamia_Http_Exception("Unable to read request: headers are empty");
     }
     $requestline = explode(' ', array_shift($headerlines), 3);
     if (!count($requestline) == 3) {
         require_once 'Aspamia/Http/Exception.php';
         throw new Aspamia_Http_Exception("Unable to read request: invalid HTTP request line '{$headerlines[0]}'");
     }
     $protocol = explode('/', $requestline[2]);
     if (!($protocol[0] == 'HTTP' && ($protocol[1] == '1.1' || $protocol[1] == '1.0'))) {
         require_once 'Aspamia/Http/Exception.php';
         throw new Aspamia_Http_Exception("Unsupported protocol version: {$requestline[2]}");
     }
     $method = strtoupper($requestline[0]);
     $uri = $requestline[1];
     $headers = array();
     foreach ($headerlines as $line) {
         $header = explode(":", $line, 2);
         if (!count($header) == 2) {
             require_once 'Aspamia/Http/Exception.php';
             throw new Aspamia_Http_Exception("Invalid HTTP header format: {$line}");
         }
         $headers[strtolower(trim($header[0]))] = trim($header[1]);
     }
     $request = new Aspamia_Http_Request($method, $uri, $headers);
     $request->_httpVersion = $protocol[1];
     $request->_socket = $connection;
     $request->_localAddress = $localAddress;
     $request->_remoteAddress = $remoteAddress;
     if ($read_body) {
         $request->_readBody();
     }
     return $request;
 }
Esempio n. 7
0
 /**
  * Called after the request is recieved. The request object is passed in
  *
  * @param Aspamia_Http_Request $request
  */
 public function postRequest(Aspamia_Http_Request $request)
 {
     $this->_log->info("Request: {$request->getMethod()} {$request->getUri()}");
 }