Expose BODYSTRUCTURE octet count as MessagePart.size#184
Conversation
BODYSTRUCTURE reports each part's body size in octets, but the value was dropped when building MessagePart from a BodyStructure. Carry it through as an optional size property (nil when the server reports 0/absent) so clients can show size labels and apply download caps without fetching part bytes.
odrobnik
left a comment
There was a problem hiding this comment.
Request changes: the new conversion drops a legitimate BODYSTRUCTURE octet count of zero. In the pinned NIOIMAP 0.3.0 parser, body-fld-octets is required and parsed as an unsigned number; a missing field makes the body structure invalid and never reaches this converter, while 0 is preserved as a valid reported size. The model should retain 0 so callers can distinguish a known-empty part from unavailable size metadata. The remaining construction, recursion, and Codable paths inspected are consistent. Builds and tests were not run, per review instructions.
Findings:
- MEDIUM
Sources/SwiftMail/IMAP/Models/MessagePart+BodyStructure.swift:45— When an IMAP server reports a valid empty MIME part withbody-fld-octetsequal to0, this branch storesnilinstead of the reported zero. A client usingsizeto show exact metadata or to allow only known-within-cap downloads then treats the empty part as unknown-size and may hide its size or refuse to fetch it. NIOIMAP 0.3.0 does not use zero as a missing-field sentinel: the octet field is mandatory in its parser, and a missing value produces an invalid BODYSTRUCTURE that is ignored by SwiftMail's handlers.
body-fld-octets is mandatory in BODYSTRUCTURE, so NIOIMAP 0.3.0 never uses 0 as a missing-field sentinel: a missing value makes the body structure invalid and never reaches this converter. Collapsing 0 to nil made a known-empty part indistinguishable from unavailable size metadata, so callers showing exact sizes or enforcing download caps would wrongly treat empty parts as unknown-size. Addresses review feedback on #184. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Expose BODYSTRUCTURE octet count as MessagePart.size (supersedes #184)
|
Thanks @appinteractive for the contribution — exposing the BODYSTRUCTURE octet count is a great addition! 🙏 We took care of the review nitpick (a reported octet count of |
What
BODYSTRUCTURE reports each body part's size in octets, but the value was dropped when building
MessagePartfrom a parsedBodyStructure. This carries it through as a new optional property:NIOIMAP parses a missing/zero field as
0, which is surfaced asnil.Why
With part sizes available from the envelope/structure fetch alone, clients can show size labels and enforce download caps (e.g. skip auto-fetching a 40 MB scan for a thumbnail) without fetching any part bytes. We use this in a mail client that builds an attachment metadata index from BODYSTRUCTURE during sync.
Changes
MessagePart: newsize: Int?property, threaded through both public initializers and theCodableimplementation (encoded withencodeIfPresent, so existing archives decode fine).MessagePart+BodyStructure: readfields.octetCountwhen flattening singleparts;> 0becomes the size, otherwisenil.MessagePartSizeTests: singlepart carries the octet count, zero yieldsnil, multipart children each carry their own size.Note: the size is the encoded (transfer-encoding) octet count per RFC 3501 — for base64 parts roughly 4/3 of the decoded file size. Documented as "as reported by BODYSTRUCTURE" to keep that semantic.