- [Post Office Protocol - Version 3, RFC 1939](https://tools.ietf.org/html/rfc1939)
- [Simple Mail Transfer Protocol, RFC 5321](https://tools.ietf.org/html/rfc5321)
- [SMTP Service Extension for Secure SMTP over Transport Layer Security, RFC 3207](https://tools.ietf.org/html/rfc3207)
+- [POP3 Extension Mechanism, RFC 2449](https://tools.ietf.org/html/rfc2449)
conn.doRSET()
case "UIDL":
conn.doUIDL()
+ case "CAPA":
+ conn.doCAPA()
default:
conn.err("unknown command")
}
conn.tp.PrintfLine(".")
}
+func (conn *connection) doCAPA() {
+ conn.ok("capabilitiy list")
+
+ caps := []string{
+ "USER",
+ "UIDL",
+ ".",
+ }
+ for _, c := range caps {
+ conn.tp.PrintfLine(c)
+ }
+}
+
func (conn *connection) getRequestedMessage() Message {
var cmd string
var idx int
t.Errorf("DELE the wrong message")
}
}
+
+func TestCapa(t *testing.T) {
+ s := newTestServer()
+
+ capaTest := func(t testing.TB, tp *textproto.Conn) string {
+ responseOK(t, tp)
+ if t.Failed() {
+ return ""
+ }
+
+ resp, err := tp.ReadDotLines()
+ if err != nil {
+ t.Error(err)
+ return ""
+ }
+
+ const (
+ capNeeded = iota
+ capSeen
+ capOK
+ )
+
+ caps := map[string]int{
+ "USER": capNeeded,
+ "UIDL": capNeeded,
+ }
+ for _, line := range resp {
+ if val, ok := caps[line]; ok {
+ if val == capNeeded {
+ caps[line] = capOK
+ } else {
+ t.Errorf("unxpected capa value %q", line)
+ }
+ } else {
+ caps[line] = capSeen
+ }
+ }
+ for c, val := range caps {
+ if val != capOK {
+ t.Errorf("unexpected capa value for %q: %d", c, val)
+ }
+ }
+ return ""
+ }
+
+ clientServerTest(t, s, []requestResponse{
+ {"CAPA", capaTest},
+ {"USER u", responseOK},
+ {"CAPA", capaTest},
+ {"PASS p", responseOK},
+ {"CAPA", capaTest},
+ {"QUIT", responseOK},
+ })
+}