示例#1
0
 /**
  * Assert that the given response indicates a succeeded WebSocket handshake.
  */
 protected function assertHandshakeSucceeded(HttpResponse $response, string $nonce, array $protocols)
 {
     if ($response->getStatusCode() !== Http::SWITCHING_PROTOCOLS) {
         throw new \RuntimeException(\sprintf('Unexpected HTTP response code: %s', $response->getStatusCode()));
     }
     if (!\in_array('upgrade', $response->getHeaderTokenValues('Connection'), true)) {
         throw new \RuntimeException(\sprintf('HTTP connection header did not contain upgrade: "%s"', $response->getHeaderLine('Connection')));
     }
     if ('websocket' !== \strtolower($response->getHeaderLine('Upgrade'))) {
         throw new \RuntimeException(\sprintf('HTTP upgrade header did not specify websocket: "%s"', $response->getHeaderLine('Upgrade')));
     }
     if (\base64_encode(\sha1($nonce . self::GUID, true)) !== $response->getHeaderLine('Sec-WebSocket-Accept')) {
         throw new \RuntimeException('Failed to verify Sec-WebSocket-Accept HTTP header');
     }
     if ($response->hasHeader('Sec-WebSocket-Protocol')) {
         if (!\in_array($response->getHeaderLine('Sec-WebSocket-Protocol'), $protocols, true)) {
             throw new \OutOfRangeException(\sprintf('Unsupported protocol: "%s"', $response->getHeaderLine('Sec-WebSocket-Protocol')));
         }
     }
 }
示例#2
0
 /**
  * {@inheritdoc}
  */
 public function upgradeConnection(SocketStream $socket, HttpRequest $request, HttpResponse $response) : \Generator
 {
     $endpoint = $response->getAttribute(Endpoint::class);
     if (!$endpoint instanceof Endpoint) {
         throw new \InvalidArgumentException('No endpoint object passed to WebSocket handler');
     }
     if ($this->logger) {
         $this->logger->debug('HTTP/{protocol} connection from {peer} upgraded to WebSocket', ['protocol' => $request->getProtocolVersion(), 'peer' => $socket->getRemoteAddress()]);
     }
     $conn = new Connection($socket, false, $response->getHeaderLine('Sec-WebSocket-Protocol'));
     if ($this->logger) {
         $conn->setLogger($this->logger);
     }
     if ($deflate = $response->getAttribute(PerMessageDeflate::class)) {
         $conn->enablePerMessageDeflate($deflate);
     }
     yield from $this->delegateToEndpoint($conn, $endpoint);
 }
示例#3
0
 protected function shouldConnectionBeClosed(HttpResponse $response) : bool
 {
     if (!$this->keepAlive) {
         return true;
     }
     if ($response->getProtocolVersion() === '1.0' && !\in_array('keep-alive', $response->getHeaderTokenValues('Connection'), true)) {
         return true;
     }
     if (!$response->hasHeader('Content-Length') && 'chunked' !== \strtolower($response->getHeaderLine('Transfer-Encoding'))) {
         return true;
     }
     return false;
 }