示例#1
0
 protected function readNextChunk() : \Generator
 {
     if ($this->expectContinue) {
         $expect = $this->expectContinue;
         $this->expectContinue = null;
         $this->continued = true;
         (yield $expect->write(Http::getStatusLine(Http::CONTINUE) . "\r\n"));
     }
     return (yield $this->stream->read($this->bufferSize));
 }
示例#2
0
 /**
  * {@inheritdoc}
  */
 public function upgradeConnection(HttpDriverContext $context, SocketStream $socket, HttpRequest $request, callable $action) : \Generator
 {
     if ($this->isPrefaceRequest($request)) {
         return yield from $this->upgradeConnectionDirect($context, $socket, $request, $action);
     }
     $settings = @\base64_decode($request->getHeaderLine('HTTP2-Settings'));
     if ($settings === false) {
         throw new StatusException(Http::CODE_BAD_REQUEST, 'HTTP/2 settings are not properly encoded');
     }
     // Discard request body before switching to HTTP/2.
     (yield $request->getBody()->discard());
     if ($this->logger) {
         $this->logger->info('{ip} "{method} {target} HTTP/{protocol}" {status} {size}', ['ip' => $request->getClientAddress(), 'method' => $request->getMethod(), 'target' => $request->getRequestTarget(), 'protocol' => $request->getProtocolVersion(), 'status' => Http::SWITCHING_PROTOCOLS, 'size' => '-']);
     }
     $buffer = Http::getStatusLine(Http::SWITCHING_PROTOCOLS, $request->getProtocolVersion()) . "\r\n";
     $buffer .= "Connection: upgrade\r\n";
     $buffer .= "Upgrade: h2c\r\n";
     (yield $socket->write($buffer . "\r\n"));
     $conn = new Connection($socket, new HPack($this->hpackContext), $this->logger);
     (yield $conn->performServerHandshake(new Frame(Frame::SETTINGS, $settings)));
     if ($this->logger) {
         $this->logger->info('HTTP/{protocol} connection from {peer} upgraded to HTTP/2', ['protocol' => $request->getProtocolVersion(), 'peer' => $socket->getRemoteAddress()]);
     }
     $remotePeer = $socket->getRemoteAddress();
     try {
         while (null !== ($received = (yield $conn->nextRequest($context)))) {
             new Coroutine($this->processRequest($conn, $action, ...$received), true);
         }
     } finally {
         try {
             $conn->shutdown();
         } finally {
             if ($this->logger) {
                 $this->logger->debug('Closed HTTP/2 connection to {peer}', ['peer' => $remotePeer]);
             }
         }
     }
 }