Skip to content

Commit ae41d74

Browse files
committed
imapmemserver: send FLAGS updates
1 parent 84a2562 commit ae41d74

File tree

1 file changed

+44
-20
lines changed

1 file changed

+44
-20
lines changed

imapserver/imapmemserver/mailbox.go

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Mailbox struct {
2525
subscribed bool
2626
l []*message
2727
uidNext uint32
28+
flags map[imap.Flag]struct{}
2829
}
2930

3031
// NewMailbox creates a new mailbox.
@@ -33,6 +34,7 @@ func NewMailbox(name string) *Mailbox {
3334
tracker: imapserver.NewMailboxTracker(0),
3435
name: name,
3536
uidNext: 1,
37+
flags: make(map[imap.Flag]struct{}),
3638
}
3739
}
3840

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

154+
mbox.addFlagsLocked(options.Flags)
155+
152156
return &imap.AppendData{
153157
UIDValidity: uidValidity,
154158
UID: msg.uid,
@@ -169,7 +173,7 @@ func (mbox *Mailbox) SetSubscribed(subscribed bool) {
169173
}
170174

171175
func (mbox *Mailbox) selectDataLocked() *imap.SelectData {
172-
flags := mbox.flagsLocked()
176+
flags := flagMapToList(mbox.flags)
173177

174178
permanentFlags := make([]imap.Flag, len(flags))
175179
copy(permanentFlags, flags)
@@ -184,24 +188,17 @@ func (mbox *Mailbox) selectDataLocked() *imap.SelectData {
184188
}
185189
}
186190

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

207204
func (mbox *Mailbox) Expunge(w *imapserver.ExpungeWriter, uids *imap.SeqSet) error {
@@ -351,16 +348,30 @@ func (mbox *MailboxView) Search(numKind imapserver.NumKind, criteria *imap.Searc
351348
}
352349

353350
func (mbox *MailboxView) Store(w *imapserver.FetchWriter, numKind imapserver.NumKind, seqSet imap.SeqSet, flags *imap.StoreFlags) error {
354-
mbox.forEach(numKind, seqSet, func(seqNum uint32, msg *message) {
355-
msg.store(flags)
356-
mbox.Mailbox.tracker.QueueMessageFlags(seqNum, msg.uid, msg.flagList(), mbox.tracker)
357-
})
351+
mbox.store(numKind, seqSet, flags)
358352
if !flags.Silent {
359353
return mbox.Fetch(w, numKind, seqSet, []imap.FetchItem{imap.FetchItemFlags})
360354
}
361355
return nil
362356
}
363357

358+
func (mbox *MailboxView) store(numKind imapserver.NumKind, seqSet imap.SeqSet, flags *imap.StoreFlags) {
359+
mbox.mutex.Lock()
360+
defer mbox.mutex.Unlock()
361+
362+
// We need to announce the new flags via a FLAGS response before sending
363+
// FETCH FLAGS responses
364+
switch flags.Op {
365+
case imap.StoreFlagsSet, imap.StoreFlagsAdd:
366+
mbox.addFlagsLocked(flags.Flags)
367+
}
368+
369+
mbox.forEachLocked(numKind, seqSet, func(seqNum uint32, msg *message) {
370+
msg.store(flags)
371+
mbox.Mailbox.tracker.QueueMessageFlags(seqNum, msg.uid, msg.flagList(), mbox.tracker)
372+
})
373+
}
374+
364375
func (mbox *MailboxView) Poll(w *imapserver.UpdateWriter, allowExpunge bool) error {
365376
return mbox.tracker.Poll(w, allowExpunge)
366377
}
@@ -427,3 +438,16 @@ func (mbox *MailboxView) staticSeqSet(seqSet imap.SeqSet, numKind imapserver.Num
427438
}
428439
}
429440
}
441+
442+
func flagMapToList(m map[imap.Flag]struct{}) []imap.Flag {
443+
var l []imap.Flag
444+
for flag := range m {
445+
l = append(l, flag)
446+
}
447+
448+
sort.Slice(l, func(i, j int) bool {
449+
return l[i] < l[j]
450+
})
451+
452+
return l
453+
}

0 commit comments

Comments
 (0)