implement the imap metadata extension, rfc 5464

this allows setting per-mailbox and per-server annotations (metadata). we have
a fixed maximum for total number of annotations (1000) and their total size
(1000000 bytes). this size isn't held against the regular quota for simplicity.
we send unsolicited metadata responses when a connection is in the idle
command and a change to a metadata item is made.

we currently only implement the /private/ namespace.  we should implement the
/shared/ namespace, for mox-global metadata annotations.  only the admin should
be able to configure those, probably through the config file, cli, or admin web
interface.

for issue #290
This commit is contained in:
Mechiel Lukkien
2025-02-17 22:44:51 +01:00
parent 9dff879164
commit f30c44eddb
17 changed files with 820 additions and 41 deletions

View File

@ -97,6 +97,7 @@ func (t syncliteral) writeTo(c *conn, w io.Writer) {
type readerSizeSyncliteral struct {
r io.Reader
size int64
lit8 bool
}
func (t readerSizeSyncliteral) pack(c *conn) string {
@ -104,11 +105,19 @@ func (t readerSizeSyncliteral) pack(c *conn) string {
if err != nil {
panic(err)
}
return fmt.Sprintf("{%d}\r\n", t.size) + string(buf)
var lit string
if t.lit8 {
lit = "~"
}
return fmt.Sprintf("%s{%d}\r\n", lit, t.size) + string(buf)
}
func (t readerSizeSyncliteral) writeTo(c *conn, w io.Writer) {
fmt.Fprintf(w, "{%d}\r\n", t.size)
var lit string
if t.lit8 {
lit = "~"
}
fmt.Fprintf(w, "%s{%d}\r\n", lit, t.size)
defer c.xtrace(mlog.LevelTracedata)()
if _, err := io.Copy(w, io.LimitReader(t.r, t.size)); err != nil {
panic(err)