mirror of
https://github.com/mjl-/mox.git
synced 2025-07-19 03:26:37 +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:
@ -46,7 +46,7 @@ func TestAppend(t *testing.T) {
|
||||
|
||||
tc2.transactf("ok", "append inbox (\\Seen Label1 $label2) \" 1-Jan-2022 10:10:00 +0100\" {1+}\r\nx")
|
||||
tc2.xuntagged(imapclient.UntaggedExists(1))
|
||||
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 1})
|
||||
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UIDs: xparseUIDRange("1")})
|
||||
|
||||
tc.transactf("ok", "noop")
|
||||
uid1 := imapclient.FetchUID(1)
|
||||
@ -57,11 +57,11 @@ func TestAppend(t *testing.T) {
|
||||
|
||||
tc2.transactf("ok", "append inbox (\\Seen) \" 1-Jan-2022 10:10:00 +0100\" UTF8 ({47+}\r\ncontent-type: just completely invalid;;\r\n\r\ntest)")
|
||||
tc2.xuntagged(imapclient.UntaggedExists(2))
|
||||
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 2})
|
||||
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UIDs: xparseUIDRange("2")})
|
||||
|
||||
tc2.transactf("ok", "append inbox (\\Seen) \" 1-Jan-2022 10:10:00 +0100\" UTF8 ({31+}\r\ncontent-type: text/plain;\n\ntest)")
|
||||
tc2.xuntagged(imapclient.UntaggedExists(3))
|
||||
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 3})
|
||||
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UIDs: xparseUIDRange("3")})
|
||||
|
||||
// Messages that we cannot parse are marked as application/octet-stream. Perhaps
|
||||
// the imap client knows how to deal with them.
|
||||
@ -79,6 +79,15 @@ func TestAppend(t *testing.T) {
|
||||
}
|
||||
tc2.xuntagged(imapclient.UntaggedFetch{Seq: 2, Attrs: []imapclient.FetchAttr{uid2, xbs}})
|
||||
|
||||
// Multiappend with two messages.
|
||||
tc.transactf("ok", "noop") // Flush pending untagged responses.
|
||||
tc.transactf("ok", "append inbox {6+}\r\ntest\r\n {6+}\r\ntost\r\n")
|
||||
tc.xuntagged(imapclient.UntaggedExists(5))
|
||||
tc.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UIDs: xparseUIDRange("4:5")})
|
||||
|
||||
// Cancelled with zero-length message.
|
||||
tc.transactf("no", "append inbox {6+}\r\ntest\r\n {0+}\r\n")
|
||||
|
||||
tclimit := startArgs(t, false, false, true, true, "limit")
|
||||
defer tclimit.close()
|
||||
tclimit.client.Login("limit@mox.example", password0)
|
||||
@ -89,4 +98,25 @@ func TestAppend(t *testing.T) {
|
||||
// Second message would take account past limit.
|
||||
tclimit.transactf("no", "append inbox (\\Seen Label1 $label2) \" 1-Jan-2022 10:10:00 +0100\" {1+}\r\nx")
|
||||
tclimit.xcode("OVERQUOTA")
|
||||
|
||||
// Empty mailbox.
|
||||
tclimit.transactf("ok", `store 1 flags (\deleted)`)
|
||||
tclimit.transactf("ok", "expunge")
|
||||
|
||||
// Multiappend with first message within quota, and second message with sync
|
||||
// literal causing quota error. Request should get error response immediately.
|
||||
tclimit.transactf("no", "append inbox {1+}\r\nx {100000}")
|
||||
tclimit.xcode("OVERQUOTA")
|
||||
|
||||
// Again, but second message now with non-sync literal, which is fully consumed by server.
|
||||
tclimit.client.Commandf("", "append inbox {1+}\r\nx {4000+}")
|
||||
buf := make([]byte, 4000, 4002)
|
||||
for i := range buf {
|
||||
buf[i] = 'x'
|
||||
}
|
||||
buf = append(buf, "\r\n"...)
|
||||
_, err := tclimit.client.Write(buf)
|
||||
tclimit.check(err, "write append message")
|
||||
tclimit.response("no")
|
||||
tclimit.xcode("OVERQUOTA")
|
||||
}
|
||||
|
Reference in New Issue
Block a user