Handle the Sec-WebSocket-Extensions HTTP request header. Accept or reject each extension proposed in the client request. Negotiate parameters for accepted extensions. Per :rfc:`6455`, negotiation rules are defined by the specification of each extension.
(
self,
headers: Headers,
)
| 310 | return origin |
| 311 | |
| 312 | def process_extensions( |
| 313 | self, |
| 314 | headers: Headers, |
| 315 | ) -> tuple[str | None, list[Extension]]: |
| 316 | """ |
| 317 | Handle the Sec-WebSocket-Extensions HTTP request header. |
| 318 | |
| 319 | Accept or reject each extension proposed in the client request. |
| 320 | Negotiate parameters for accepted extensions. |
| 321 | |
| 322 | Per :rfc:`6455`, negotiation rules are defined by the specification of |
| 323 | each extension. |
| 324 | |
| 325 | To provide this level of flexibility, for each extension proposed by |
| 326 | the client, we check for a match with each extension available in the |
| 327 | server configuration. If no match is found, the extension is ignored. |
| 328 | |
| 329 | If several variants of the same extension are proposed by the client, |
| 330 | it may be accepted several times, which won't make sense in general. |
| 331 | Extensions must implement their own requirements. For this purpose, |
| 332 | the list of previously accepted extensions is provided. |
| 333 | |
| 334 | This process doesn't allow the server to reorder extensions. It can |
| 335 | only select a subset of the extensions proposed by the client. |
| 336 | |
| 337 | Other requirements, for example related to mandatory extensions or the |
| 338 | order of extensions, may be implemented by overriding this method. |
| 339 | |
| 340 | Args: |
| 341 | headers: WebSocket handshake request headers. |
| 342 | |
| 343 | Returns: |
| 344 | ``Sec-WebSocket-Extensions`` HTTP response header and list of |
| 345 | accepted extensions. |
| 346 | |
| 347 | Raises: |
| 348 | InvalidHandshake: If the Sec-WebSocket-Extensions header is invalid. |
| 349 | |
| 350 | """ |
| 351 | response_header_value: str | None = None |
| 352 | |
| 353 | extension_headers: list[ExtensionHeader] = [] |
| 354 | accepted_extensions: list[Extension] = [] |
| 355 | |
| 356 | header_values = headers.get_all("Sec-WebSocket-Extensions") |
| 357 | |
| 358 | if header_values and self.available_extensions: |
| 359 | parsed_header_values: list[ExtensionHeader] = sum( |
| 360 | [parse_extension(header_value) for header_value in header_values], [] |
| 361 | ) |
| 362 | |
| 363 | for name, request_params in parsed_header_values: |
| 364 | for ext_factory in self.available_extensions: |
| 365 | # Skip non-matching extensions based on their name. |
| 366 | if ext_factory.name != name: |
| 367 | continue |
| 368 | |
| 369 | # Skip non-matching extensions based on their params. |
no test coverage detected