Skip to content

blackbull.server.permessage_deflate

blackbull.server.permessage_deflate

permessage-deflate (RFC 7692) negotiation and per-message codec.

This module is small on purpose. It does two things:

  1. Handshake: parse a peer's Sec-WebSocket-Extensions offer, decide whether to accept permessage-deflate, and produce the response-side Sec-WebSocket-Extensions header value.

  2. Per-connection state: hold the streaming inflate/deflate state plus the *_no_context_takeover flags so :class:WebSocketRecipient can decompress inbound messages and :class:WebSocketSender can compress outbound ones.

The actual wire-level use of RSV1 happens in :mod:ws_codec and :mod:recipient; this module just owns the policy + state.

DeflateParams dataclass

Per-connection permessage-deflate parameters as negotiated.

InboundDecompressor

Streaming decompressor for inbound permessage-deflate messages.

The peer (client) is doing the compression here, so the no_context_takeover flag we care about is client_no_context_takeover. When set, the inflater is recreated for every message; otherwise the same inflater is reused so the sliding-window context carries forward across messages.

decompress(payload)

Inflate one whole compressed message. Raises zlib.error on bad data.

OutboundCompressor

Streaming compressor for outbound permessage-deflate messages.

Symmetric to :class:InboundDecompressor: the no_context_takeover flag that matters here is server_no_context_takeover (we are the server), deciding whether to reset the deflater between messages.

compress(payload)

Compress one whole message; strip the trailing 0x00 0x00 0xff 0xff per RFC 7692 §7.2.1.

negotiate(offer_header)

Decide whether to accept permessage-deflate based on the client's offer.

Returns (params, response_value) where:

  • params is the :class:DeflateParams to install on the connection (or None to decline).
  • response_value is the bytes to put after Sec-WebSocket-Extensions: in the 101 response (or None when declining).

Policy: accept context-takeover by default on both sides (better compression). Honour server_no_context_takeover and client_no_context_takeover when the client asks for them. Ignore unknown parameter names — that's what RFC 7692 §5.1 calls for.

offer_header is the raw bytes of the client's Sec-WebSocket-Extensions header (or None when absent). The client may send multiple comma-separated offers; we pick the first one that names permessage-deflate and that we can satisfy.