-
Notifications
You must be signed in to change notification settings - Fork 329
imapserver: Add CONDSTORE and QRESYNC extension support #690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v2
Are you sure you want to change the base?
Conversation
Ref #687 which contained the previous version of this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM apart from these comments!
imapserver/select.go
Outdated
} | ||
} | ||
|
||
shouldSendModSeqStatus := c.enabled.Has(imap.CapIMAP4rev2) || c.server.options.caps().Has(imap.CapCondStore) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think IMAP4rev2 has CONDSTORE folded in? Is there a reason to send mod seq when it's enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMAP4rev2 requires QRESYNC which on the other hand requires CONDSTORE. I added support in capability check for this chain
imapserver/imapmemserver/mailbox.go
Outdated
msg.modSeq = mbox.highestModSeq | ||
mbox.highestModSeq++ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we bump mbox.highestModSeq
before setting the message's mod seq?
If we bump mbox.highestModSeq
after, then it's not the highest mod seq, it's the next mod seq.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, fixed
return | ||
} | ||
|
||
if options.ChangedSince > 0 && msg.modSeq <= options.ChangedSince { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be msg.modSeq < options.ChangedSince
? In other words, we want to send the message if CHANGEDSINCE equals MODSEQ.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RFC specifies that the message's modSeq must be strictly greater than the CHANGEDSINCE value (we have the opposite condition)
imapserver/imapmemserver/mailbox.go
Outdated
var modifiedSeqNums []uint32 | ||
var modifiedMsgs []*message | ||
|
||
mbox.mutex.Lock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: we can use mbox.forEach
instead of manually locking/unlocking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, updated
imapserver/imapmemserver/mailbox.go
Outdated
mbox.highestModSeq++ | ||
msg.modSeq = mbox.highestModSeq |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we handle the mod seq bump inside msg.store
? This would make it so we don't forget bumping it if we call this function from elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, updated
imapserver/imapmemserver/mailbox.go
Outdated
|
||
for i, seqNum := range modifiedSeqNums { | ||
msg := modifiedMsgs[i] | ||
mbox.Mailbox.tracker.QueueMessageFlags(seqNum, msg.uid, msg.flagList(), mbox.tracker) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to move the QueueMessageFlags
call outside of the mbox.forEach
loop?
msg.flagList
can only be called with the mailbox mutex locked. QueueMessageFlags
never blocks.
imapserver/imapmemserver/mailbox.go
Outdated
} | ||
|
||
if !flags.Silent && len(modifiedMsgs) > 0 { | ||
for i, seqNum := range modifiedSeqNums { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of open-coding this, could we accumulate an imap.SeqSet
of modified message sequence numbers in the loop above, and pass that to mbox.Fetch
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update the whole logic with an accumulator
…ptions; readSearchKeyWithAtom should return errors instead of swallowing them; tag in search response should be quoted; replaced deprecated strings.Title
|
||
if expunge { | ||
w := &ExpungeWriter{} | ||
w := &ExpungeWriter{conn: c} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@emersion this is an unrelated bug, conn was missing
Capabilities
Imapclientflags
Implementing changes requested