Skip to content

blackbull.protocol.http1

blackbull.protocol.http1

The HTTP/1.1 message codec (RFC 9112), shared by the server and the client.

Both roles read a head, a field section, a body and a trailer section with the same rules. A role chooses its start-line grammar and how it answers an error: MessageError is 400 to the server and ProtocolError to the client. Rules on which the roles differ are in the role policy section below.

ChunkedDecoder

Yield the data of a chunked body in slices, then read its trailer.

wait runs each read as await wait(read, payload), where payload is whether the read returns body octets; a role bounds and meters reads there. Lines are bounded by line_max; the trailer section, when trailer_max, by that total. EOF part-way raises EOFError.

next() async

The next data slice, or None after the trailer section.

FieldsTooLarge

Bases: MessageError

A head line, chunk line or trailer section is over its limit.

section is true for a whole trailer section, false for one line.

IncompleteReadError

Bases: EOFError

A reader's peer closed mid-read; partial is what had arrived.

The caller answers a truncated head and an idle close differently, so partial is part of the contract.

LineCache

Bases: dict

Field lines one peer repeats, mapped to their parsed pairs; size is the bytes of the lines held.

MessageError

Bases: ValueError

The message breaks RFC 9112; its reader cannot tell where it ends.

ReadLimitExceeded

Bases: Exception

A bounded read passed its byte budget; seen is what it read.

The reader reports and the protocol decides the status (docs/about/internals.md §One breach, two verdicts).

Unimplemented

Bases: MessageError

Well-formed, but uses a transfer coding or method the recipient lacks.

UnsupportedVersion

Bases: MessageError

A well-formed HTTP-version with a major version other than 1.

connection_options(headers)

The lowercase Connection options of a Headers, or MessageError for one that is not a token.

content_length(index)

The agreed Content-Length in a Headers index, or None.

parse_head(head, max_line, cache, request)

(start, pairs, index) of a message head.

start is (method, request-target, HTTP-version) for a request and (HTTP-version, status) for a response. Field names are lowercase tchar and values carry no edge SP/HTAB and no CTL. A line over max_line is FieldsTooLarge. cache holds lines this peer sent before.

persistent(version, headers)

Whether the connection persists after this message: close ends it, and HTTP/1.0 needs keep-alive.

request_framing(headers)

(Content-Length or None, chunked) of a request's Headers.

RFC 9112 §6.1: a request has no close-delimited body, so a Transfer-Encoding other than exactly chunked cannot be read: chunked not alone at the end is MessageError, another coding or a parameter is Unimplemented. §6.3: CL with TE is an error.

response_framing(headers, method, status)

(mode, length, reusable, switched) of a response to method.

RFC 9112 §6.3: method and status come first (HEAD, 1xx, 204, 304 have no body; a 2xx to CONNECT and a 101 switch protocols). A response whose final coding is not chunked ends at the close (item 4), where a request is refused. A 1xx or 204 declaring a body is not reusable (§6.1).