/** * Handles the request by calling the IPC server. * * This function will connect to the IPC server, send the request, and copy what the server sends back to the response. * * @param HTTPRequestInterface $httpRequest The request to handle (if null, an instance of HTTPRequestGlobal) * @param HTTPResponseInterface $httpResponse The response where to write the output (if null, an instance of HTTPResponseGlobal) */ public function handle(HTTPRequestInterface $httpRequest = null, HTTPResponseInterface $httpResponse = null) { if (!$httpRequest) { $httpRequest = new HTTPRequestGlobal(); } if (!$httpResponse) { $httpResponse = new HTTPResponseGlobal(); } if (($this->socket = stream_socket_client($this->bindAddress, $errNo, $errString)) === false) { throw new \RuntimeException('Could not create client socket: ' . $errString); } // writing request line $toWrite = $httpRequest->getMethod() . ' ' . $httpRequest->getURL() . ' HTTP/1.1' . "\r\n"; // TODO: HTTP version fwrite($this->socket, $toWrite); // writing headers foreach ($httpRequest->getHeadersList() as $header => $value) { $toWrite = $header . ': ' . $value . "\r\n"; fwrite($this->socket, $toWrite); } // writing data $toWrite = "\r\n" . $httpRequest->getRawData(); fwrite($this->socket, $toWrite); stream_socket_shutdown($this->socket, STREAM_SHUT_WR); fflush($this->socket); // reading response $response = HTTPResponseStream::build($httpResponse, true); $response->fwrite(stream_get_contents($this->socket)); $response->fflush(); unset($response); stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR); $httpResponse->flush(); }
/** * Handles the request described in $input. * * This function will go through all registered routes. All routes that match the requested URL will be called in the order of their registration. * The server passes a scope containing variables coming from it. See generateQueryScope for more infos. * * If no route is found or if an error is triggered, the server will start a pseudo-route. This will call all the before handles of the server and return a 404 or 500 code. * * @param HTTPRequestInterface $input The request to handle (if null, an instance of HTTPRequestGlobal) * @param HTTPResponseInterface $output The response where to write the output (if null, an instance of HTTPResponseGlobal) * @see generateQueryScope */ public function handle(HTTPRequestInterface $input = null, HTTPResponseInterface $output = null) { if (!$input) { $input = new HTTPRequestGlobal(); } if (!$output) { $output = new HTTPResponseGlobal(); } $this->log->debug('Starting handling of resource', ['url' => $input->getURL(), 'method' => $input->getMethod()]); $localScope = $this->generateQueryScope(); // updating $elapsedTime $atResourceHandlingStart = microtime(true); $localScope->elapsedTime = function () use($atResourceHandlingStart) { return microtime(true) - $atResourceHandlingStart; }; $this->currentResponsesStack[] = $output; try { if ($this->routesCollection->handle($input, $output, $localScope)) { $this->log->debug('Successful handling of resource', ['url' => $input->getURL(), 'method' => $input->getMethod()]); // flushing output if (isset($localScope->output) && $localScope->output instanceof OutputInterface) { $this->log->debug('Flushing the OutputInterface object'); $localScope->output->flush(); } else { $this->log->debug('No OutputInterface object has been found'); } } else { // handling 404 if we didn't find any handler $this->log->debug('Didn\'t find any route for request', ['url' => $input->getURL(), 'method' => $input->getMethod()]); $this->followPseudoRoute($input, $output, 404, $localScope); } // flush response $this->log->debug('Flushing the updated HTTPResponseInterface (with filters)'); $output->flush(); // gc_collect if ($nb = gc_collect_cycles()) { $this->log->notice('gc_collect_cycles() returned non-zero value: ' . $nb); } } catch (\Exception $exception) { try { $this->log->err($exception->getMessage(), $exception->getTrace()); } catch (\Exception $e) { } if ($this->printErrors) { $this->printError($exception, $output); } else { if (!$output->isHeadersListSent()) { $output->setStatusCode(500); } $output->appendData('A server-side error occured. Please try again later.'); } $output->flush(); } }