perf(mail): fetch only headers for list/search (no body download)

list and search now fetch BODY.PEEK[HEADER] + BODYSTRUCTURE instead of the
whole RFC822 message, so listing a large mailbox no longer downloads every
message body and attachment. Header parsing reuses the same go-message path
(RFC2047 decoding/formatting preserved); has_attachments is derived from the
BODYSTRUCTURE tree. FetchFull keeps fetching the full message for get.

Validated end-to-end against a live IMAP account: list/search/get output
identical to the prior full-fetch behaviour, has_attachments correct.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-22 07:47:27 +01:00
parent a1440719ae
commit 8379fddbb2
4 changed files with 203 additions and 37 deletions
+13
View File
@@ -103,3 +103,16 @@ func ParseHeaderOnly(uid uint32, raw []byte) (Header, error) {
}
return m.Header, nil
}
// ParseHeaderBytes parses just a message's RFC822 header block (the bytes from
// an IMAP BODY[HEADER] fetch, with no body) into a Header, reusing the same
// RFC2047-decoding and formatting as ParseMessage. HasAttachments is left false:
// the caller, which holds the BODYSTRUCTURE, sets it. This lets list/search read
// headers without downloading message bodies.
func ParseHeaderBytes(uid uint32, raw []byte) (Header, error) {
mr, err := mail.CreateReader(bytes.NewReader(raw))
if err != nil {
return Header{}, err
}
return readHeader(mr, uid), nil
}