/** * 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'))); } } }
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; }