/** * Assert that the given HTTP request can be upgraded to the WebSocket protocol. */ protected function assertUpgradePossible(HttpRequest $request) { if ($request->getMethod() !== Http::GET) { throw new StatusException(Http::METHOD_NOT_ALLOWED, 'WebSocket upgrade requires an HTTP GET request', ['Allow' => Http::GET, 'Sec-Websocket-Version' => '13']); } if (!$request->hasHeader('Sec-Websocket-Key')) { throw new StatusException(Http::BAD_REQUEST, 'Missing Sec-Websocket-Key HTTP header', ['Sec-Websocket-Version' => '13']); } if (!\in_array('13', $request->getHeaderTokenValues('Sec-Websocket-Version'), true)) { throw new StatusException(Http::BAD_REQUEST, 'Secure websocket version 13 required', ['Sec-Websocket-Version' => '13']); } }
/** * Invoke HTTP/1 upgrade handlers in an attempt to update the connection based on the outcome of an action. * * @param HttpRequest $request * @param mixed $result * @return HttpResponse Or null if no connection upgrade is available. */ protected function upgradeResult(HttpRequest $request, $result) { $protocols = ['']; if (\in_array('upgrade', $request->getHeaderTokenValues('Connection'), true)) { $protocols = \array_merge($request->getHeaderTokenValues('Upgrade'), $protocols); } foreach ($protocols as $protocol) { foreach ($this->upgradeResultHandlers as $handler) { if ($handler->isUpgradeSupported($protocol, $request, $result)) { $response = $handler->createUpgradeResponse($request, $result); $response = $response->withAttribute(UpgradeResultHandler::class, $handler); return $response; } } } return $result; }
protected function serializeHeaders(HttpRequest $request, int $size = null) { if (\in_array('upgrade', $request->getHeaderTokenValues('Connection'))) { $request = $request->withHeader('Connection', 'upgrade'); } else { $request = $request->withHeader('Connection', $this->keepAlive ? 'keep-alive' : 'close'); } $buffer = \sprintf("%s %s HTTP/%s\r\n", $request->getMethod(), $request->getRequestTarget(), $request->getProtocolVersion()); if ($this->keepAlive) { $buffer .= \sprintf("Keep-Alive: timeout=%u\r\n", $this->pool->getMaxLifetime()); } if ($size === null) { $buffer .= "Transfer-Encoding: chunked\r\n"; } else { $buffer .= "Content-Length: {$size}\r\n"; } foreach ($request->getHeaders() as $name => $header) { $name = Http::normalizeHeaderName($name); foreach ($header as $value) { $buffer .= $name . ': ' . $value . "\r\n"; } } return $buffer; }
/** * Get all known hop IP addresses as provided by an HTTP proxy. * * @param HttpRequest $request * @return array */ public function getAddresses(HttpRequest $request) : array { $addresses = []; foreach ($this->addressHeaders as $name) { if ($request->hasHeader($name)) { foreach ($request->getHeaderTokenValues($name, false) as $ip) { $addresses[] = $ip; } } } return $addresses; }