# _ws_handler

URL: /pounce/api/_ws_handler/
Section: api
Description: WebSocket connection handler — HTTP/1.1 upgrade lifecycle.

Extracted from ``worker.py`` to keep protocol-specific connection handling
separate from the core Worker lifecycle.  The worker delegates to
``handle_websocket()`` when it detects an HTTP/1.1 WebSocket upgrade.

Connection flow:
    H1 request → detect ``Connection: Upgrade`` + ``Upgrade: websocket``
    → build ASGI ``websocket`` scope → 101 Switching Protocols
    → wsproto frame loop → app(scope, receive, send)

---

> For a complete page index, fetch /pounce/llms.txt.

Open LLM text
(/pounce/api/_ws_handler/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpounce%2Fapi%2F_ws_handler%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpounce%2Fapi%2F_ws_handler%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpounce%2Fapi%2F_ws_handler%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpounce%2Fapi%2F_ws_handler%2Findex.txt)

Module

#
`_ws_handler`

WebSocket connection handler — HTTP/1.1 upgrade lifecycle.

Extracted from`worker.py`to keep protocol-specific connection handling
separate from the core Worker lifecycle. The worker delegates to
`handle_websocket()`when it detects an HTTP/1.1 WebSocket upgrade.

Connection flow:

```
H1 request → detect ``Connection: Upgrade`` + ``Upgrade: websocket``
→ build ASGI ``websocket`` scope → 101 Switching Protocols
→ wsproto frame loop → app(scope, receive, send)
```

3Functions

## Functions

`_permessage_deflate_offer`

1

`str | None`

▼

Return the client's ``permessage-deflate`` extension offer segment.

Scans ever…

`def _permessage_deflate_offer(headers: tuple[tuple[bytes, bytes], ...]) -> str | None`

Return the client's`permessage-deflate`extension offer segment.

Scans every`Sec-WebSocket-Extensions`header for a comma-separated
`permessage-deflate`token and returns that single extension segment
(token plus any`;`-delimited parameters) so it can be fed verbatim to
wsproto's RFC 7692 negotiation. Returns`None`when the client did not
offer permessage-deflate.

##### Parameters

Name
Type
Description

`headers`
`tuple[tuple[bytes, bytes], ...]`

##### Returns

`str | None`

`_client_requested_permessage_deflate`

1

`bool`

▼

Return True when the client offered permessage-deflate.

`def _client_requested_permessage_deflate(headers: tuple[tuple[bytes, bytes], ...]) -> bool`

##### Parameters

Name
Type
Description

`headers`
`tuple[tuple[bytes, bytes], ...]`

##### Returns

`bool`

`handle_websocket`

11

`None`

▼

Handle a WebSocket connection after HTTP/1.1 upgrade detection.

**Lifecycle:**…

async

`async def handle_websocket(app: ASGIApp, config: ServerConfig, logger: logging.Logger, request: RequestReceived, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, client: tuple[str, int], server: tuple[str, int], client_str: str, *, worker_id: int | None = None, lifespan_state: dict[str, Any] | None = None) -> None`

Handle a WebSocket connection after HTTP/1.1 upgrade detection.

Lifecycle:

- Build ASGI`websocket`scope

- Push`websocket.connect`to the receive queue

- Run the ASGI app — it sends`websocket.accept`(or close)

- Read WebSocket frames and feed to receive queue

- App sends`websocket.send` / `websocket.close` (/pounce/api/protocols/ws/#WSProtocol)

- Clean up when either side disconnects

##### Parameters

Name
Type
Description

`app`
`ASGIApp`

The ASGI application callable.

`config`
`ServerConfig (/pounce/api/config/#ServerConfig)`

Immutable server configuration.

`logger`
`logging.Logger`

Logger scoped to the worker.

`request`
`RequestReceived (/pounce/api/protocols/_base/#RequestReceived)`

The parsed HTTP request that triggered the upgrade.

`reader`
`asyncio.StreamReader`

Asyncio stream reader for the connection.

`writer`
`asyncio.StreamWriter`

Asyncio stream writer for the connection.

`client`
`tuple[str, int]`

`(host, port)`of the remote peer.

`server`
`tuple[str, int]`

`(host, port)`of the local endpoint.

`client_str`
`str`

Formatted`"host:port"`string for logging.

`worker_id`
`int | None`

Default:`None`

`lifespan_state`
`dict[str, Any] | None`

Default:`None`
