blackbull.fault_injection.catalogue.h1_client¶
blackbull.fault_injection.catalogue.h1_client
¶
Named HTTP/1.1 client-side misbehaviour cases.
The last of the grid's four catalogues. Cells B, C and D shipped named sets (9, 4 and 11 cases); this cell had none — it was reachable only through the atheris and Hypothesis harnesses, which generate inputs rather than name them. That is a real difference in kind: a generated input tells you that something broke, a named case tells you which known mistake you are testing against, and only the second can be cited in a bug report or parametrized over by a downstream user.
Every case is raw bytes, because on this side the fault is the bytes.
A typed SendRequest step would be built from the same encoder the
production client uses, and could not emit a fault that encoder has —
the same reasoning that keeps the two fault servers off the production
send path.
The cases are drawn from RFC 9112's framing rules and the request- smuggling literature, so the names line up with what a reader is likely to be defending against.
absent_host()
¶
No Host header. RFC 9112 §3.2 makes this a 400.
bare_lf_terminators()
¶
Bare LF instead of CRLF (RFC 9112 §2.2 makes recognising it a MAY).
Implementations legitimately differ, which is exactly why it belongs in a catalogue: the case is here to make the difference visible, not to assert one answer.
body_shorter_than_declared()
¶
Declares 100 bytes of body and sends 5, then stops.
chunk_size_not_hex()
¶
A chunk size that is not hexadecimal (RFC 9112 §7.1).
content_length_and_transfer_encoding()
¶
Both framing headers at once — RFC 9112 §6.1 says reject.
The classic CL.TE / TE.CL desync: whichever one the recipient honours determines where it thinks the body ends.
duplicate_transfer_encoding()
¶
Two Transfer-Encoding headers, the second not chunked.
head_never_ends()
¶
Headers that never reach the terminating CRLFCRLF.
negative_content_length()
¶
Content-Length: -1 — not a valid length.
nul_in_header_value()
¶
A NUL byte in a field value — not a valid field-vchar.
obs_fold_header()
¶
An obs-fold continuation line (RFC 9112 §5.2 deprecates it).
oversized_method_token()
¶
A 2 KiB method token — a head-budget case, not a parse case.
space_before_header_colon()
¶
Foo : bar — RFC 9112 §5.1 requires rejecting, not trimming.
Trimming is the defect: a proxy that trims and an origin that rejects see different header sets.
trickled_head()
¶
The request head one byte at a time — the slowloris primitive.
Nothing here is malformed; the fault is the rate, which is why the server's answer comes from its header deadline rather than its parser.
two_content_lengths()
¶
Two Content-Length headers that disagree (RFC 9112 §6.3).
The smuggling primitive: a recipient that picks one and a recipient that picks the other disagree about where the next request starts.