Skip to content

Commit fc483b0

Browse files
committed
imapserver: add SupportedCaps
1 parent 1905c46 commit fc483b0

File tree

2 files changed

+51
-38
lines changed

2 files changed

+51
-38
lines changed

imapserver/capability.go

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ func (c *Conn) availableCaps() []imap.Cap {
2929
available := c.server.options.caps()
3030

3131
var caps []imap.Cap
32-
addAvailableCaps(&caps, available, []imap.Cap{
33-
imap.CapIMAP4rev2,
34-
imap.CapIMAP4rev1,
32+
addAvailableCaps(&caps, map[imap.Cap]bool{
33+
imap.CapIMAP4rev2: available.IMAP4rev1,
34+
imap.CapIMAP4rev1: available.IMAP4rev2,
3535
})
3636
if len(caps) == 0 {
3737
panic("imapserver: must support at least IMAP4rev1 or IMAP4rev2")
3838
}
3939

40-
if available.Has(imap.CapIMAP4rev1) {
40+
if available.IMAP4rev1 {
4141
caps = append(caps, []imap.Cap{
4242
imap.CapSASLIR,
4343
imap.CapLiteralMinus,
@@ -58,7 +58,7 @@ func (c *Conn) availableCaps() []imap.Cap {
5858
caps = append(caps, imap.CapLoginDisabled)
5959
}
6060
if c.state == imap.ConnStateAuthenticated || c.state == imap.ConnStateSelected {
61-
if available.Has(imap.CapIMAP4rev1) {
61+
if available.IMAP4rev1 {
6262
// IMAP4rev1-specific capabilities that don't require backend
6363
// support and are not applicable to IMAP4rev2
6464
caps = append(caps, []imap.Cap{
@@ -70,35 +70,35 @@ func (c *Conn) availableCaps() []imap.Cap {
7070

7171
// IMAP4rev1-specific capabilities which require backend support
7272
// and are not applicable to IMAP4rev2
73-
addAvailableCaps(&caps, available, []imap.Cap{
74-
imap.CapNamespace,
75-
imap.CapUIDPlus,
76-
imap.CapESearch,
77-
imap.CapSearchRes,
78-
imap.CapListExtended,
79-
imap.CapListStatus,
80-
imap.CapMove,
81-
imap.CapStatusSize,
82-
imap.CapBinary,
83-
imap.CapChildren,
73+
addAvailableCaps(&caps, map[imap.Cap]bool{
74+
imap.CapNamespace: available.Namespace,
75+
imap.CapUIDPlus: available.UIDPlus,
76+
imap.CapESearch: available.ESearch,
77+
//imap.CapSearchRes: available.SearchRes,
78+
imap.CapListExtended: available.ListExtended,
79+
imap.CapListStatus: available.ListStatus,
80+
imap.CapMove: available.Move,
81+
imap.CapStatusSize: available.StatusSize,
82+
//imap.CapBinary: available.Binary,
83+
//imap.CapChildren: available.Children,
8484
})
8585
}
8686

8787
// Capabilities which require backend support and apply to both
8888
// IMAP4rev1 and IMAP4rev2
89-
addAvailableCaps(&caps, available, []imap.Cap{
90-
imap.CapSpecialUse,
91-
imap.CapCreateSpecialUse,
92-
imap.CapLiteralPlus,
93-
imap.CapUnauthenticate,
89+
addAvailableCaps(&caps, map[imap.Cap]bool{
90+
imap.CapSpecialUse: available.SpecialUse,
91+
imap.CapCreateSpecialUse: available.CreateSpecialUse,
92+
imap.CapLiteralPlus: available.LiteralPlus,
93+
imap.CapUnauthenticate: available.Unauthenticate,
9494
})
9595
}
9696
return caps
9797
}
9898

99-
func addAvailableCaps(caps *[]imap.Cap, available imap.CapSet, l []imap.Cap) {
100-
for _, c := range l {
101-
if available.Has(c) {
99+
func addAvailableCaps(caps *[]imap.Cap, available map[imap.Cap]bool) {
100+
for c, ok := range available {
101+
if ok {
102102
*caps = append(*caps, c)
103103
}
104104
}

imapserver/server.go

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,30 @@ type Logger interface {
2121
Printf(format string, args ...interface{})
2222
}
2323

24+
// SupportedCaps describes capabilities supported by the server.
25+
type SupportedCaps struct {
26+
// IMAP protocol version
27+
IMAP4rev1 bool // RFC 3501
28+
IMAP4rev2 bool // RFC 9051
29+
30+
// Capabilities which are part of IMAP4rev2 and need to be explicitly
31+
// enabled by IMAP4rev1-only servers
32+
Namespace bool // RFC 2342
33+
UIDPlus bool // RFC 4315
34+
ESearch bool // RFC 4731
35+
ListExtended bool // RFC 5258
36+
ListStatus bool // RFC 5819
37+
Move bool // RFC 6851
38+
StatusSize bool // RFC 8438
39+
40+
// Capabilities which need to be explicitly enabled on both IMAP4rev1 and
41+
// IMAP4rev2 servers
42+
SpecialUse bool // RFC 6154
43+
CreateSpecialUse bool // RFC 6154
44+
LiteralPlus bool // RFC 7888
45+
Unauthenticate bool // RFC 8437
46+
}
47+
2448
// Options contains server options.
2549
//
2650
// The only required field is NewSession.
@@ -29,18 +53,7 @@ type Options struct {
2953
NewSession func(*Conn) (Session, *GreetingData, error)
3054
// Supported capabilities. If nil, only IMAP4rev1 is advertised. This set
3155
// must contain at least IMAP4rev1 or IMAP4rev2.
32-
//
33-
// The following capabilities are part of IMAP4rev2 and need to be
34-
// explicitly enabled by IMAP4rev1-only servers:
35-
//
36-
// - NAMESPACE
37-
// - UIDPLUS
38-
// - ESEARCH
39-
// - LIST-EXTENDED
40-
// - LIST-STATUS
41-
// - MOVE
42-
// - STATUS=SIZE
43-
Caps imap.CapSet
56+
Caps *SupportedCaps
4457
// Logger is a logger to print error messages. If nil, log.Default is used.
4558
Logger Logger
4659
// TLSConfig is a TLS configuration for STARTTLS. If nil, STARTTLS is
@@ -68,11 +81,11 @@ func (options *Options) wrapReadWriter(rw io.ReadWriter) io.ReadWriter {
6881
}
6982
}
7083

71-
func (options *Options) caps() imap.CapSet {
84+
func (options *Options) caps() *SupportedCaps {
7285
if options.Caps != nil {
7386
return options.Caps
7487
}
75-
return imap.CapSet{imap.CapIMAP4rev1: {}}
88+
return &SupportedCaps{IMAP4rev1: true}
7689
}
7790

7891
// Server is an IMAP server.

0 commit comments

Comments
 (0)