Example #1
0
 /**
  * {@inheritdoc}
  */
 public function listen(callable $action) : Awaitable
 {
     return new Coroutine(function () use($action) {
         $factory = clone $this->factory;
         $factory->setTcpNoDelay(true);
         $this->server = (yield $factory->createSocketServer());
         $port = $this->server->getPort();
         $peer = $this->server->getAddress() . ($port ? ':' . $port : '');
         $context = new HttpDriverContext($peer, $factory->getPeerName(), $factory->isEncrypted(), $this->middlewares, $this->responders);
         $pending = new \SplObjectStorage();
         try {
             (yield $this->server->listen(function (SocketStream $socket) use($pending, $context, $action) {
                 $conn = new Connection($socket, $context);
                 if ($this->logger) {
                     $conn->setLogger($this->logger);
                 }
                 $pending->attach($conn);
                 while (null !== ($next = (yield $conn->nextRequest()))) {
                     new Coroutine($this->processRequest($conn, $context, $action, ...$next));
                 }
             }));
         } finally {
             $this->server = null;
             foreach ($pending as $task) {
                 $task->cancel(new \RuntimeException('FCGI server stopped'));
             }
         }
     });
 }
Example #2
0
 /**
  * Assemble an HTTP request from received FCGI params.
  */
 protected function buildRequest() : HttpRequest
 {
     static $extra = ['CONTENT_TYPE' => 'Content-Type', 'CONTENT_LENGTH' => 'Content-Length', 'CONTENT_MD5' => 'Content-MD5'];
     $uri = \strtolower($this->params['REQUEST_SCHEME'] ?? 'http') . '://';
     $uri .= $this->params['HTTP_HOST'] ?? $this->context->getPeerName();
     if (!empty($this->params['SERVER_PORT'])) {
         $uri .= ':' . (int) $this->params['SERVER_PORT'];
     }
     $uri = Uri::parse($uri . '/' . \ltrim($this->params['REQUEST_URI'] ?? '', '/'));
     $request = new HttpRequest($uri, $this->params['REQUEST_METHOD'] ?? Http::GET, [], '1.1');
     foreach ($this->params as $k => $v) {
         if ('HTTP_' === \substr($k, 0, 5)) {
             switch ($k) {
                 case 'HTTP_TRANSFER_ENCODING':
                 case 'HTTP_CONTENT_ENCODING':
                 case 'HTTP_KEEP_ALIVE':
                     // Skip these headers...
                     break;
                 default:
                     $request = $request->withAddedHeader(\str_replace('_', '-', \substr($k, 5)), (string) $v);
             }
         }
     }
     foreach ($extra as $k => $v) {
         if (isset($this->params[$k])) {
             $request = $request->withHeader($v, $this->params[$k]);
         }
     }
     $addresses = [$this->conn->getRemoteAddress()];
     if (isset($this->params['REMOTE_ADDR'])) {
         $addresses = \array_merge([$this->params['REMOTE_ADDR']], $addresses);
     }
     $request = $request->withAddress(...$addresses);
     $request = $request->withAttribute(HttpDriverContext::class, $this->context);
     return $request->withBody(new StreamBody(new ReadableChannelStream($this->body)));
 }