imapserver: implement NOTIFY extension from RFC 5465

NOTIFY is like IDLE, but where IDLE watches just the selected mailbox, NOTIFY
can watch all mailboxes. With NOTIFY, a client can also ask a server to
immediately return configurable fetch attributes for new messages, e.g. a
message preview, certain header fields, or simply the entire message.

Mild testing with evolution and fairemail.
This commit is contained in:
Mechiel Lukkien
2025-04-07 23:21:03 +02:00
parent 5a7d5fce98
commit 8bab38eac4
30 changed files with 1926 additions and 161 deletions

View File

@ -250,7 +250,7 @@ func tuntagged(t *testing.T, got imapclient.Untagged, dst any) {
gotv := reflect.ValueOf(got)
dstv := reflect.ValueOf(dst)
if gotv.Type() != dstv.Type().Elem() {
t.Fatalf("got %v, expected %v", gotv.Type(), dstv.Type().Elem())
t.Fatalf("got %#v, expected %#v", gotv.Type(), dstv.Type().Elem())
}
dstv.Elem().Set(gotv)
}
@ -262,6 +262,18 @@ func (tc *testconn) xnountagged() {
}
}
func (tc *testconn) readuntagged(exps ...imapclient.Untagged) {
tc.t.Helper()
for i, exp := range exps {
tc.conn.SetReadDeadline(time.Now().Add(3 * time.Second))
v, err := tc.client.ReadUntagged()
tcheck(tc.t, err, "reading untagged")
if !reflect.DeepEqual(v, exp) {
tc.t.Fatalf("got %#v, expected %#v, response %d/%d", v, exp, i+1, len(exps))
}
}
}
func (tc *testconn) transactf(status, format string, args ...any) {
tc.t.Helper()
tc.cmdf("", format, args...)