Skip to content

blackbull.fault_injection.scenario_h1_server

blackbull.fault_injection.scenario_h1_server

HTTP/1.1 server-side scenarios for a target client.

Output is raw bytes, assembled here rather than by the production sender.

CloseGracefully dataclass

Close cleanly (FIN) after whatever has been written.

Terminal. What the client sees is an orderly EOF, not the reset Abort sends.

EndChunkedBody dataclass

The zero-length chunk that terminates a chunked body, with any trailers; omit this step to stage a body that never terminates.

EndHeaders dataclass

The blank line that ends the head. Omit it to stage a head that never finishes.

ExpectRequest dataclass

Bases: _Expect

Read one request head and record whether it matched.

A fault staged against Expect: 100-continue tests nothing if the client never sent that header; the verdict lands on ScenarioH1ServerResult.expectations.

ScenarioH1Server dataclass

An ordered sequence of steps, plus a name for test parametrisation.

ScenarioH1ServerResult dataclass

What the executor observed while running a scenario.

Field names match ScenarioH2Result wherever the two mean the same thing.

SendChunk dataclass

One chunk of a chunked body (RFC 9112 §7.1).

declared_size sets the chunk-size line independently of the data — the single most common framing fault there is. extension appends a chunk extension; terminator can be replaced to stage a bad CRLF.

SendHeader dataclass

Emit a header; fold=True emits an obs-fold continuation (RFC 9112 §5.2).

SendStatusLine dataclass

Emit status-line fields without validation; malformed values are intentional.

StepOpH1Server

Bases: str, Enum

The v1 JSON tags, still read until v1 reading is removed.

WaitForRequest dataclass

Bases: _WaitFor

Block until a request head arrives, optionally one that matches.

On a pipelined connection (RFC 9112 §9.3.2) this is how a scenario breaks the POST and not the GET. Skipping desyncs the connection, because HTTP/1.1 responses are positional: a head passed over is one the scenario can no longer answer. ExpectRequest skips nothing.

parse_request_head(head)

Split a request head into the fields request_matches reads.

Lenient by necessity: it parses what a client under test actually sent. A malformed request line yields empty strings rather than raising, so a scenario matching on method simply will not match it.

request_matches(head, match)

Return True iff head satisfies every key in match.

Recognised keys: method, target, version, header, header_absent. Unknown keys fail closed — an unrecognised key is almost certainly a typo in a scenario, and silently matching on a key nobody reads would hide it.

header takes (name, value); pass value=None to match on presence alone. header_absent takes a name.

scenario_from_json(src)

Parse JSON Lines back to a ScenarioH1Server.

scenario_to_json(scenario)

Serialise scenario to JSON Lines (one step per line).