mirror of
https://github.com/mjl-/mox.git
synced 2025-07-12 18:24:35 +03:00
imapserver: implement MULTIAPPEND extension, rfc 3502
MULTIAPPEND modifies the existing APPEND command to allow multiple messages. it is somewhat more involved than a regular append of a single message since the operation (of adding multiple messages) must be atomic. either all are added, or none are. we check as early as possible if the messages won't cause an over-quota error.
This commit is contained in:
@ -196,7 +196,8 @@ func (c *Conn) TLSConnectionState() *tls.ConnectionState {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Commandf writes a free-form IMAP command to the server.
|
||||
// Commandf writes a free-form IMAP command to the server. An ending \r\n is
|
||||
// written too.
|
||||
// If tag is empty, a next unique tag is assigned.
|
||||
func (c *Conn) Commandf(tag string, format string, args ...any) (rerr error) {
|
||||
defer c.recover(&rerr)
|
||||
|
@ -205,8 +205,8 @@ func (c *Conn) xrespCode() (string, CodeArg) {
|
||||
c.xspace()
|
||||
destUIDValidity := c.xnzuint32()
|
||||
c.xspace()
|
||||
uid := c.xnzuint32()
|
||||
codeArg = CodeAppendUID{destUIDValidity, uid}
|
||||
uids := c.xuidrange()
|
||||
codeArg = CodeAppendUID{destUIDValidity, uids}
|
||||
case "COPYUID":
|
||||
c.xspace()
|
||||
destUIDValidity := c.xnzuint32()
|
||||
|
@ -38,6 +38,7 @@ const (
|
||||
CapCreateSpecialUse Capability = "CREATE-SPECIAL-USE" // ../rfc/6154:296
|
||||
CapCompressDeflate Capability = "COMPRESS=DEFLATE" // ../rfc/4978:65
|
||||
CapListMetadata Capability = "LIST-METADTA" // ../rfc/9590:73
|
||||
CapMultiAppend Capability = "MULTIAPPEND" // ../rfc/3502:33
|
||||
)
|
||||
|
||||
// Status is the tagged final result of a command.
|
||||
@ -111,11 +112,11 @@ func (c CodeUint) CodeString() string {
|
||||
// "APPENDUID" response code.
|
||||
type CodeAppendUID struct {
|
||||
UIDValidity uint32
|
||||
UID uint32
|
||||
UIDs NumRange
|
||||
}
|
||||
|
||||
func (c CodeAppendUID) CodeString() string {
|
||||
return fmt.Sprintf("APPENDUID %d %d", c.UIDValidity, c.UID)
|
||||
return fmt.Sprintf("APPENDUID %d %s", c.UIDValidity, c.UIDs.String())
|
||||
}
|
||||
|
||||
// "COPYUID" response code.
|
||||
@ -391,6 +392,13 @@ func ParseNumSet(s string) (ns NumSet, rerr error) {
|
||||
return
|
||||
}
|
||||
|
||||
func ParseUIDRange(s string) (nr NumRange, rerr error) {
|
||||
c := Conn{br: bufio.NewReader(strings.NewReader(s))}
|
||||
defer c.recover(&rerr)
|
||||
nr = c.xuidrange()
|
||||
return
|
||||
}
|
||||
|
||||
// NumRange is a single number or range.
|
||||
type NumRange struct {
|
||||
First uint32 // 0 for "*".
|
||||
|
Reference in New Issue
Block a user