blackbull.server.permessage_deflate¶
blackbull.server.permessage_deflate
¶
WebSocket compression negotiation and per-connection codec state.
Keep RSV1 framing in the WebSocket codec and recipient; negotiated context takeover governs reuse across messages.
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, *, max_length=None)
¶
Inflate one whole compressed message. Raises zlib.error on bad data.
With max_length set, the inflated output is bounded by zlib
itself rather than measured after the fact: a bomb is refused
without ever being built. Asking for max_length + 1 is what
makes "exactly at the bound" and "one byte over" distinguishable
in a single call — zlib stops at the byte it was given, so a
return of exactly max_length bytes is ambiguous on its own.
Raises MessageTooLarge when the peer's message inflates
past the bound. unconsumed_tail is the other half of that
check: zlib stops early when it hits the limit, so leftover input
means there was more to come even if the output landed on the
boundary.
OutboundCompressor
¶
Streaming compressor for outbound permessage-deflate messages.
Symmetric to 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:
paramsis theDeflateParamsto install on the connection (orNoneto decline).response_valueis the bytes to put afterSec-WebSocket-Extensions:in the 101 response (orNonewhen 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.
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.
negotiate_offer(headers)
¶
Apply the settings gate and negotiate the RFC 7692 offer in headers.
The one way both handshakes (HTTP/1.1 and the RFC 8441 path) decide on
permessage-deflate. Returns what negotiate returns: (params,
response_value), both None when nothing was offered, the offer was
declined, or ws_permessage_deflate is off.