Multipart HTTP Response Parser
Use this skill when adding or fixing multipart response parsing, MIME boundary scanners, HTTP streaming body iterators, or sync/async APIs that yield parsed response parts.
Workflow
- Trace the response body lifecycle first: in-memory bytes, sync streaming, async streaming, decoder layers, stream-consumed checks, and response close behavior.
- Parse and validate
Content-Typebefore consuming the body. Treat media type and parameter names case-insensitively, let the lastboundaryparameter win, and reject CR/LF injection, empty/non-ASCII/NUL/leading-=boundaries, missing boundary, andmultipart/with an empty subtype. - Normalize body line scanning without losing bytes. Support LF, CRLF, CR, and delimiters split across chunks; do not include the line terminator immediately before a delimiter in part content.
- Accept only exact delimiter lines
--boundaryand--boundary--with optional trailing SP/HTAB. Ignore preamble and epilogue; if the first boundary-like line is malformed, raise the public decoding error. - Parse each part's headers until a blank line. Reject missing colon, empty names, leading whitespace on the first header, and continuation lines containing only SP/TAB.
- Preserve duplicate headers and continuation values through the project's header type instead of flattening them into a plain dict.
- Keep sync and async behavior equivalent. Streaming multipart iteration should consume the raw stream, close the response, and raise the stream-consumed error on repeat; buffered bodies should be repeatable.
- Add matrix tests for boundary parsing, delimiter variants, malformed framing, duplicate/continued headers, preamble/epilogue, streaming chunk splits, sync and async APIs, and repeat iteration semantics.
Rules
- Do not parse multipart bodies through text decoding; all boundary and body handling must be bytes-safe.
- Boundary-like lines inside a part body are content unless they are exact delimiter lines.
- A successful close delimiter with no preceding parts is a valid zero-part response.
- Public errors should use the library's existing decoding/stream-consumed exception types.
Source: Calvin-Corbett/thomas — distributed by TomeVault.