Repository navigation
Releases
Releases · BeaverMail/beavermaild
BeaverMail 0.4.0
- IMAP BODYSTRUCTURE of a multipart includes the
BOUNDARYparameter, as RFC 3501 7.4.2 asks for
the full MIME parameter list. - IMAP BINARY of a quoted-printable part with stray control bytes returns the whole part with those
bytes kept (RFC 2045 6.7); it used to stop at the first such byte. - IMAP ENVELOPE address lists (also inside BODYSTRUCTURE of message/rfc822 parts) are written
back to back, without a space between addresses, as the RFC 3501 grammar requires. - Login with an unknown or malformed user name now fails like a wrong password (IMAP
NO,
SMTP535) and counts toward the attempt limit; IMAP and SMTP used to drop the connection,
which also told existing users apart from unknown ones. - IMAP BODYSTRUCTURE carries the extension data of every part (RFC 3501 7.4.2): MD5,
Content-Disposition with its parameters (attachment file names), language and location. An
unknown transfer encoding is reported as it is instead of7BIT. - IMAP URLAUTH (RFC 4467) and URLAUTH=BINARY (RFC 5524):
GENURLAUTHsigns message URLs with a
per-mailbox key (mechanism INTERNAL, HMAC-SHA256),URLFETCHreturns the data of valid URLs
(withBODY,BINARY,BODYPARTSTRUCTUREitems; with BINARY the structure describes the
decoded part) and NIL otherwise,RESETKEYrevokes keys.
Accessauthuser,anonymousanduser+nameare honoured,submit+is refused. SELECT and
EXAMINE sendOK [URLMECH INTERNAL]. - IMAP CATENATE (RFC 4469):
APPEND ... CATENATE (TEXT {n} URL "...")builds a message from
literals and parts of the user's messages (RFC 5092 URLs); an invalid URL answers
NO [BADURL ...], also within MULTIAPPEND. - IMAP CONTEXT=SEARCH and CONTEXT=SORT (RFC 5267):
RETURN (PARTIAL lo:hi), andRETURN (UPDATE)
keeps the result current withESEARCH ADDTO/REMOVEFROMuntilCANCELUPDATEor another
SELECT; at most 8 updating contexts per session, more getNO [NOUPDATE]. - IMAP UIDBATCHES (draft-ietf-mailmaint-imap-uidbatches):
UIDBATCHES size [first:last]splits
the selected mailbox into UID ranges, newest first; sizes under 500 answerNO [TOOFEW]. - IMAP APPEND: a refused synchronizing literal (too large, or after an invalid part) ends the
command with a tagged NO instead of closing the connection. - IMAP NOTIFY (RFC 5465):
NOTIFY SET [STATUS]/NOTIFY NONEwith the SELECTED,
SELECTED-DELAYED, PERSONAL, INBOXES, SUBSCRIBED, SUBTREE and MAILBOXES filters and the
MessageNew (with FETCH items), MessageExpunge, FlagChange, MailboxName and SubscriptionChange
events, pushed between commands and during IDLE; other events answerNO [BADEVENT ...]. - IMAP BINARY (RFC 3516):
FETCH BINARY[part],BINARY.PEEK[part](also partial) and
BINARY.SIZE[part]return the part decoded from base64 or quoted-printable, as a literal8 when
it holds NUL; an undecodable encoding answersNO [UNKNOWN-CTE].APPENDtakes literal8 (~{n}); parts
holding NUL are stored base64-encoded, soBODY[...]stays a valid literal andBINARY[...]
still returns the original bytes. - IMAP MULTIAPPEND (RFC 3502): one
APPENDstores several messages, all or none, with one
APPENDUIDset. The size cap applies to the messages of a command together. - IMAP CONDSTORE is on only after a CONDSTORE enabling command (RFC 7162 3.1:
ENABLE,
SELECT ... (CONDSTORE),FETCH/SEARCHwithMODSEQ,CHANGEDSINCE,UNCHANGEDSINCE,
STATUS (HIGHESTMODSEQ)), not from login: until then noMODSEQin FETCH and no
HIGHESTMODSEQon SELECT. The first such command with a mailbox selected sends
* OK [HIGHESTMODSEQ n]. - IMAP ESEARCH (RFC 4731) and ESORT (RFC 5267):
SEARCH/SORT RETURN (MIN MAX ALL COUNT)answer
* ESEARCH (TAG ...), withMODSEQwhen the program uses it. - IMAP
SORT=DISPLAY(RFC 5957:DISPLAYFROM,DISPLAYTO) andTHREAD=ORDEREDSUBJECT(RFC 5256). - IMAP
ID(RFC 2971) in every state. Command lines may be up to 64 KiB (was 8 KiB),
and a longer one closes the connection once past the limit instead of being read whole first. - IMAP oversized literals (RFC 7888 4): a synchronizing
APPENDover the size limit gets
NO [TOOBIG]before upload; a non-synchronizing one (APPENDor a search literal) gets
* BYE [TOOBIG]and the connection closes, instead of its bytes being read as commands. - IMAP
SELECT/EXAMINEclose the selected mailbox first, even when they fail, and say so with
* OK [CLOSED](RFC 7162, required with CONDSTORE advertised); a failedSELECTleft the previous
mailbox selected. - IMAP QRESYNC (RFC 7162):
ENABLE QRESYNC,SELECT/EXAMINE ... (QRESYNC (uidvalidity modseq [known-uids]))answersVANISHED (EARLIER)and the messages changed since,UID FETCH ... (CHANGEDSINCE n VANISHED), andVANISHEDinstead ofEXPUNGEonce enabled. Without an expunge
history,VANISHED (EARLIER)lists every missing UID of the known range belowUIDNEXT, as the
RFC allows. - IMAP flag-change
FETCHresponses (fromSTORE, an implicit\Seenor another session) carry
UIDandMODSEQonce CONDSTORE is enabled (RFC 7162 3.2.4); reselecting a mailbox keeps
announcing inFLAGSthe keywords the session has already seen there.PERMANENTFLAGSlists
those keywords as well as\*. - IMAP
STOREupdates all the messages of a range in one storage transaction (per 256) instead of
one per message, so under load it waits for the account write lock once. - IMAP: claiming the
\Recentof new messages no longer queues on the account write lock; the
storage CAS picks the one session that gets it. Every session seeing a new message queued for the
lock though only the first could claim it, which slowed every command that syncs (LIST, STATUS...). - MySQL:
interpolateParams=trueis added to the DSN unless set (one round trip per query instead of
prepare, execute and close), and the pool keeps up to 25 idle connections instead of 5, so busy
periods no longer reopen connections. BEAVER_PPROF=127.0.0.1:6060serves Go's profiler (CPU, block, mutex, goroutines) on a loopback
address whileserveruns; off by default. Write locks held over 250 ms or waited on past their
timeout are logged at WARN.- IMAP
EXPUNGE/CLOSEdelete all the\Deletedmessages in one storage transaction (per 256
messages) instead of one per message, so under load they wait for the account write lock once. - Mail storage: deleting a message no longer scans every message on the server to decide whether its
blob file is still used (17 ms per deleted message at 10k messages, growing with the whole server).
A background GC removes unreferenced blob files once an hour, after a one-hour grace period, so
disk space comes back with that delay. It also removes the files of sent queue entries and failed
APPENDs, which were never deleted, and it cannot race an APPEND of the same content. - Mail storage: writes of one account run one at a time inside the process, so a large transaction
(APPEND touches the mailbox, the email counter and the quota) no longer loses every retry to smaller
ones under load and fails with "too much write contention". The optimistic CAS check still guards
writers in other processes. - IMAP: a command that still fails on write contention answers
NO [INUSE] Mailbox busy, try again
(RFC 5530) and the session goes on; the connection was dropped. - IMAP logs: a session dropped by a server-side error is logged at WARN as
imap command failedwith the
command name, account, selected mailbox and client address (never the arguments); a client that
disconnects stays at DEBUG. Both were a bare DEBUGimap sessionline. - IMAP: listing a mailbox while another session expunges from it skips the deleted messages; it
failed with "not found" and dropped the connection (thousands of times in the imaptest stress test).
COPY/MOVEof a message expunged by another session answerNOinstead of disconnecting. - IMAP
\Recentunder concurrency: a session reports\Recentonly for messages it took, after
loading them, so a message arriving between the two steps is no longer\Recentin two sessions
(found by the imaptest stress test). Taking\Recentno longer bumpsMODSEQ. - IMAP
CREATEno longer subscribes the new folder (RFC 3501; clients such as Thunderbird subscribe
themselves). Existing folders and folders created by plugins stay subscribed. An explicit subscription
outlivesDELETE:LIST (SUBSCRIBED)returns it as\NonExistent,LSUBas\Noselect,CREATE
of the same name takes it back andUNSUBSCRIBEdrops it. - IMAP
COPY/MOVEset\Recenton the new messages (RFC 3501); it was cleared. - IMAP
EXPUNGE/CLOSEact on the stored flags, so\Deletedset by another session counts, and only
delete a message still in the mailbox and still\Deleted: a message moved away meanwhile was
deleted from its new folder, and one already expunged dropped the connection. - IMAP: changes reported to a session always come from a full reload; flag changes made together with
new or expunged messages were lost. - IMAP: every command except
FETCH,STORE,SEARCH,SORTandTHREADreports changes made by other
sessions to the selected mailbox (EXISTS,EXPUNGE,FETCH FLAGS,RECENT) before its tagged reply,
as RFC 3501 requires; onlyIDLEdid, soNOOP/CHECKshowed a stale mailbox. A new message is
\Recentonly for the firstSELECTsession that sees it (anAPPENDinto the selected mailbox
included), soSTATUSno longer counts it as recent. - IMAP:
STOREon a message expunged by another session skips it andFETCHof its body answersNO
(RFC 2180); both dropped the connection. - IMAP ENVELOPE puts an obsolete source route (
<@route:user@domain>) in the route slot; the address
came out empty. - IMAP: a mailbox deleted and created again gets a new
UIDVALIDITY; it was always 1, and the reused
mailbox id restarted UIDs from 1, so cli...
BeaverMail 0.3.0
- License: GNU AGPL v3.0 only (
AGPL-3.0-only), copyright BLUEBOX SOFTWARE S.L. Contributions under the
CLA. Third-party notices in NOTICE. - Antispam plugin rewritten on the rspamd rules: rspamd symbol names, default scores and actions (greylist 4,
add header 6, reject 15). The config format changed: rewrite<data_dir>/antispam/config.jsonfrom
examples/antispam/config.json.examplebefore upgrading; see docs/antispam-ops.md.
The list files keep their names. - Security policy: SECURITY.md.