/**
  * Handles the connection with the connected client in a proper way the given
  * protocol type and version expects for example.
  *
  * @param \AppserverIo\Psr\Socket\SocketInterface        $connection The connection to handle
  * @param \AppserverIo\Server\Interfaces\WorkerInterface $worker     The worker how started this handle
  *
  * @return bool Weather it was responsible to handle the firstLine or not.
  * @throws \Exception
  */
 public function handle(SocketInterface $connection, WorkerInterface $worker)
 {
     // register shutdown handler once to avoid strange memory consumption problems
     $this->registerShutdown();
     // add connection ref to self
     $this->connection = $connection;
     $this->worker = $worker;
     $serverConfig = $this->getServerConfig();
     // get instances for short calls
     $requestContext = $this->getRequestContext();
     $parser = $this->getParser();
     // Get our query parser
     $queryParser = $parser->getQueryParser();
     // Get the request and response
     $request = $parser->getRequest();
     $response = $parser->getResponse();
     // init keep alive settings
     $keepAliveTimeout = (int) $serverConfig->getKeepAliveTimeout();
     $keepAliveMax = (int) $serverConfig->getKeepAliveMax();
     // init keep alive connection flag
     $keepAliveConnection = false;
     // init the request parser
     $parser->init();
     do {
         // try to handle request if its a http request
         try {
             // reset connection info to server vars
             $requestContext->setServerVar(ServerVars::REMOTE_ADDR, $connection->getAddress());
             $requestContext->setServerVar(ServerVars::REMOTE_PORT, $connection->getPort());
             // start time measurement for keep-alive timeout
             $keepaliveStartTime = microtime(true);
             // time settings
             $requestContext->setServerVar(ServerVars::REQUEST_TIME, time());
             /**
              * Todo: maybe later on there have to be other time vars too especially for rewrite module.
              *
              * REQUEST_TIME_FLOAT
              * TIME_YEAR
              * TIME_MON
              * TIME_DAY
              * TIME_HOUR
              * TIME_MIN
              * TIME_SEC
              * TIME_WDAY
              * TIME
              */
             // process modules by hook REQUEST_PRE
             $this->processModules(ModuleHooks::REQUEST_PRE);
             // init keep alive connection flag
             $keepAliveConnection = false;
             // set first line from connection
             $line = $connection->readLine(self::HTTP_CONNECTION_READ_LENGTH, $keepAliveTimeout);
             /**
              * In the interest of robustness, servers SHOULD ignore any empty
              * line(s) received where a Request-Line is expected.
              * In other words, if
              * the server is reading the protocol stream at the beginning of a
              * message and receives a CRLF first, it should ignore the CRLF.
              *
              * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.1
              */
             if (in_array($line, array("\r\n", "\n"))) {
                 // ignore the first CRLF and go on reading the expected start-line.
                 $line = $connection->readLine(self::HTTP_CONNECTION_READ_LENGTH);
             }
             // parse read line
             $parser->parseStartLine($line);
             /**
              * Parse headers in a proper way
              *
              * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
              */
             $messageHeaders = '';
             while (!in_array($line, array("\r\n", "\n"))) {
                 // read next line
                 $line = $connection->readLine();
                 // enhance headers
                 $messageHeaders .= $line;
             }
             // parse headers
             $parser->parseHeaders($messageHeaders);
             // process connection type keep-alive
             if (strcasecmp($request->getHeader(Protocol::HEADER_CONNECTION), Protocol::HEADER_CONNECTION_VALUE_KEEPALIVE) === 0) {
                 // calculate keep-alive idle time for comparison with keep-alive timeout
                 $keepAliveIdleTime = microtime(true) - $keepaliveStartTime;
                 // only if max connections or keep-alive timeout not reached yet
                 if ($keepAliveMax > 0 && $keepAliveIdleTime < $keepAliveTimeout) {
                     // enable keep alive connection
                     $keepAliveConnection = true;
                     // set keep-alive headers
                     $response->addHeader(Protocol::HEADER_CONNECTION, Protocol::HEADER_CONNECTION_VALUE_KEEPALIVE);
                     $response->addHeader(Protocol::HEADER_KEEP_ALIVE, "timeout: {$keepAliveTimeout}, max: {$keepAliveMax}");
                     // decrease keep-alive max
                     --$keepAliveMax;
                 }
             }
             // check if message body will be transmitted
             if ($request->hasHeader(Protocol::HEADER_CONTENT_LENGTH)) {
                 // get content-length header
                 if (($contentLength = (int) $request->getHeader(Protocol::HEADER_CONTENT_LENGTH)) > 0) {
                     // check if given content length is not greater than post_max_size from php ini
                     if ($this->getPostMaxSize() < $contentLength) {
                         // throw 500 server error
                         throw new \Exception(sprintf("Post max size '%s' exceeded", $this->getPostMaxSize(false)), 500);
                     }
                     // copy connection stream to body stream by given content length
                     $request->copyBodyStream($connection->getConnectionResource(), $contentLength);
                     // get content out for oldschool query parsing todo: refactor query parsing
                     $content = $request->getBodyContent();
                     // check if request has to be parsed depending on Content-Type header
                     if ($queryParser->isParsingRelevant($request->getHeader(Protocol::HEADER_CONTENT_TYPE))) {
                         // checks if request has multipart formdata or not
                         preg_match('/boundary=(.*)$/', $request->getHeader(Protocol::HEADER_CONTENT_TYPE), $boundaryMatches);
                         // check if boundaryMatches are found
                         // todo: refactor content string var to be able to use bodyStream
                         if (count($boundaryMatches) > 0) {
                             $parser->parseMultipartFormData($content);
                         } else {
                             $queryParser->parseStr($content);
                         }
                     }
                 }
             }
             // set parsed query and multipart form params to request
             $request->setParams($queryParser->getResult());
             // init connection & protocol server vars
             $this->initServerVars();
             // process modules by hook REQUEST_POST
             $this->processModules(ModuleHooks::REQUEST_POST);
             // if no module dispatched response throw internal server error 500
             if (!$response->hasState(HttpResponseStates::DISPATCH)) {
                 throw new \Exception('Response state is not dispatched', 500);
             }
         } catch (SocketReadTimeoutException $e) {
             // break the request processing due to client timeout
             break;
         } catch (SocketReadException $e) {
             // break the request processing due to peer reset
             break;
         } catch (SocketServerException $e) {
             // break the request processing
             break;
         } catch (\Exception $e) {
             // set status code given by exception
             // if 0 is comming set 500 by default
             $response->setStatusCode($e->getCode() ? $e->getCode() : 500);
             $this->renderErrorPage($e);
         }
         // process modules by hook RESPONSE_PRE
         $this->processModules(ModuleHooks::RESPONSE_PRE);
         // send response to connected client
         $this->prepareResponse();
         // send response to connected client
         $this->sendResponse();
         // process modules by hook RESPONSE_POST
         $this->processModules(ModuleHooks::RESPONSE_POST);
         // check if keep alive-loop is finished to close connection before log access and init vars
         // to avoid waiting on non keep alive requests for that
         if ($keepAliveConnection !== true) {
             $connection->close();
         }
         // log informations for access log etc...
         $this->logAccess();
         // init context vars afterwards to avoid performance issues
         $requestContext->initVars();
         // init the request parser for next request
         $parser->init();
     } while ($keepAliveConnection === true);
     // close connection if not closed yet
     $connection->close();
 }
 /**
  * Parses the request body and tries to unpack the remote method
  * instance from it.
  *
  * @param \AppserverIo\Psr\Socket\SocketInterface $connection    The package remote method instance
  * @param integer                                 $contentLength The content length to read
  *
  * @return object The unpacked remote method object/result
  */
 public function parseBody(SocketInterface $connection, $contentLength)
 {
     $rawResponse = stream_get_contents($connection->getConnectionResource(), $contentLength);
     return RemoteMethodProtocol::unpack($rawResponse);
 }