Add the CHUNKING extension (RFC 3030)
Command.bdat parses "BDAT <size> [LAST]" strictly. The server
advertises CHUNKING and receives chunked messages on both handler
paths: the collecting path reassembles raw chunks (no dot-stuffing,
max_message_size enforced with 552), and BdatReader adapts the chunk
sequence into the streaming handler's reader, replying 250 between
chunks and handling RSET/QUIT/protocol violations mid-stream, with
unread remainder drained. Framing is strictly length-based: a BDAT
without a transaction still consumes its payload octets, and chunk
payloads that look like commands are data.
The client gains Extensions.chunking, bdat(chunk, last) (verbatim
transmission, one flush per chunk), and sendMessageChunked; the CLI
gains send --chunking, streaming stdin as BDAT chunks.
The exim-client torture script and the byte-for-byte gauntlet unit
test gain a BDAT section, and the VM interop suite delivers via
CHUNKING to real Postfix and Exim (18 subtests passing). BINARYMIME
remains deliberately unimplemented (BODY=BINARYMIME is rejected).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HBHFhoTYa8TU9GLwobfbx