Skip to content

Commit b5812ce

Browse files
committed
imapmemserver: send FLAGS updates
1 parent 90a1a90 commit b5812ce

File tree

1 file changed

+45
-20
lines changed

1 file changed

+45
-20
lines changed

imapserver/imapmemserver/mailbox.go

+45-20
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type Mailbox struct {
2323
subscribed bool
2424
l []*message
2525
uidNext imap.UID
26+
flags map[imap.Flag]struct{}
2627
}
2728

2829
// NewMailbox creates a new mailbox.
@@ -32,6 +33,7 @@ func NewMailbox(name string, uidValidity uint32) *Mailbox {
3233
uidValidity: uidValidity,
3334
name: name,
3435
uidNext: 1,
36+
flags: make(map[imap.Flag]struct{}),
3537
}
3638
}
3739

@@ -148,6 +150,8 @@ func (mbox *Mailbox) appendBytes(buf []byte, options *imap.AppendOptions) *imap.
148150
mbox.l = append(mbox.l, msg)
149151
mbox.tracker.QueueNumMessages(uint32(len(mbox.l)))
150152

153+
mbox.addFlagsLocked(options.Flags)
154+
151155
return &imap.AppendData{
152156
UIDValidity: mbox.uidValidity,
153157
UID: msg.uid,
@@ -168,7 +172,7 @@ func (mbox *Mailbox) SetSubscribed(subscribed bool) {
168172
}
169173

170174
func (mbox *Mailbox) selectDataLocked() *imap.SelectData {
171-
flags := mbox.flagsLocked()
175+
flags := flagMapToList(mbox.flags)
172176

173177
permanentFlags := make([]imap.Flag, len(flags))
174178
copy(permanentFlags, flags)
@@ -183,24 +187,17 @@ func (mbox *Mailbox) selectDataLocked() *imap.SelectData {
183187
}
184188
}
185189

186-
func (mbox *Mailbox) flagsLocked() []imap.Flag {
187-
m := make(map[imap.Flag]struct{})
188-
for _, msg := range mbox.l {
189-
for flag := range msg.flags {
190-
m[flag] = struct{}{}
190+
func (mbox *Mailbox) addFlagsLocked(flags []imap.Flag) {
191+
changed := false
192+
for _, flag := range flags {
193+
if _, ok := mbox.flags[canonicalFlag(flag)]; !ok {
194+
changed = true
191195
}
196+
mbox.flags[canonicalFlag(flag)] = struct{}{}
192197
}
193-
194-
var l []imap.Flag
195-
for flag := range m {
196-
l = append(l, flag)
198+
if changed {
199+
mbox.tracker.QueueMailboxFlags(flagMapToList(mbox.flags))
197200
}
198-
199-
sort.Slice(l, func(i, j int) bool {
200-
return l[i] < l[j]
201-
})
202-
203-
return l
204201
}
205202

206203
func (mbox *Mailbox) Expunge(w *imapserver.ExpungeWriter, uids *imap.UIDSet) error {
@@ -393,16 +390,31 @@ func (mbox *MailboxView) staticSearchCriteria(criteria *imap.SearchCriteria) {
393390
}
394391

395392
func (mbox *MailboxView) Store(w *imapserver.FetchWriter, numSet imap.NumSet, flags *imap.StoreFlags, options *imap.StoreOptions) error {
396-
mbox.forEach(numSet, func(seqNum uint32, msg *message) {
397-
msg.store(flags)
398-
mbox.Mailbox.tracker.QueueMessageFlags(seqNum, msg.uid, msg.flagList(), mbox.tracker)
399-
})
393+
mbox.store(numSet, flags)
400394
if !flags.Silent {
395+
// TODO: this sends message flags updates before mailbox flags update
401396
return mbox.Fetch(w, numSet, &imap.FetchOptions{Flags: true})
402397
}
403398
return nil
404399
}
405400

401+
func (mbox *MailboxView) store(numSet imap.NumSet, flags *imap.StoreFlags) {
402+
mbox.mutex.Lock()
403+
defer mbox.mutex.Unlock()
404+
405+
// We need to announce the new flags via a FLAGS response before sending
406+
// FETCH FLAGS responses
407+
switch flags.Op {
408+
case imap.StoreFlagsSet, imap.StoreFlagsAdd:
409+
mbox.addFlagsLocked(flags.Flags)
410+
}
411+
412+
mbox.forEachLocked(numSet, func(seqNum uint32, msg *message) {
413+
msg.store(flags)
414+
mbox.Mailbox.tracker.QueueMessageFlags(seqNum, msg.uid, msg.flagList(), mbox.tracker)
415+
})
416+
}
417+
406418
func (mbox *MailboxView) Poll(w *imapserver.UpdateWriter, allowExpunge bool) error {
407419
return mbox.tracker.Poll(w, allowExpunge)
408420
}
@@ -484,3 +496,16 @@ func staticNumRange(start, stop *uint32, max uint32) {
484496
*start, *stop = *stop, *start
485497
}
486498
}
499+
500+
func flagMapToList(m map[imap.Flag]struct{}) []imap.Flag {
501+
var l []imap.Flag
502+
for flag := range m {
503+
l = append(l, flag)
504+
}
505+
506+
sort.Slice(l, func(i, j int) bool {
507+
return l[i] < l[j]
508+
})
509+
510+
return l
511+
}

0 commit comments

Comments
 (0)