git » chasquid » commit 7e7c807

Implement VRFY and EXPN commands

author Alberto Bertogli
2016-05-07 00:34:12 UTC
committer Alberto Bertogli
2016-07-16 11:33:50 UTC
parent e32ba1ee86bcabdb4782cdcef8524cf64236017a

Implement VRFY and EXPN commands

We implement the VRFY and EXPN commands, but as no-ops. The RFC allows this,
and most implementations seem to do it this way too.

While at it, merge the tests for simple commands like these into one.

chasquid.go +19 -1
chasquid_test.go +10 -17

diff --git a/chasquid.go b/chasquid.go
index 4a207fc..9beacf1 100644
--- a/chasquid.go
+++ b/chasquid.go
@@ -325,6 +325,10 @@ loop:
 			code, msg = c.NOOP(params)
 		case "RSET":
 			code, msg = c.RSET(params)
+		case "VRFY":
+			code, msg = c.VRFY(params)
+		case "EXPN":
+			code, msg = c.EXPN(params)
 		case "MAIL":
 			code, msg = c.MAIL(params)
 		case "RCPT":
@@ -397,8 +401,22 @@ func (c *Conn) RSET(params string) (code int, msg string) {
 	return 250, msgs[rand.Int()%len(msgs)]
 }
 
+func (c *Conn) VRFY(params string) (code int, msg string) {
+	// 252 can be used for cases like ours, when we don't really want to
+	// confirm or deny anything.
+	// See https://tools.ietf.org/html/rfc2821#section-3.5.3.
+	return 252, "You have a strange feeling for a moment, then it passes."
+}
+
+func (c *Conn) EXPN(params string) (code int, msg string) {
+	// 252 can be used for cases like ours, when we don't really want to
+	// confirm or deny anything.
+	// See https://tools.ietf.org/html/rfc2821#section-3.5.3.
+	return 252, "You feel disoriented for a moment."
+}
+
 func (c *Conn) NOOP(params string) (code int, msg string) {
-	return 250, "noooooooooooooooooooop"
+	return 250, "You hear a faint typing noise."
 }
 
 func (c *Conn) MAIL(params string) (code int, msg string) {
diff --git a/chasquid_test.go b/chasquid_test.go
index 9676297..4ed0d4b 100644
--- a/chasquid_test.go
+++ b/chasquid_test.go
@@ -155,30 +155,23 @@ func TestRcptBeforeMail(t *testing.T) {
 	}
 }
 
-func TestHelp(t *testing.T) {
-	c := mustDial(t, false)
-	defer c.Close()
-
-	if err := c.Text.PrintfLine("HELP"); err != nil {
-		t.Fatalf("Failed to write HELP: %v", err)
+func simpleCmd(t *testing.T, c *smtp.Client, cmd string, expected int) {
+	if err := c.Text.PrintfLine(cmd); err != nil {
+		t.Fatalf("Failed to write %s: %v", cmd, err)
 	}
 
-	if _, _, err := c.Text.ReadResponse(214); err != nil {
-		t.Errorf("Incorrect HELP response: %v", err)
+	if _, _, err := c.Text.ReadResponse(expected); err != nil {
+		t.Errorf("Incorrect %s response: %v", cmd, err)
 	}
 }
 
-func TestNoop(t *testing.T) {
+func TestSimpleCommands(t *testing.T) {
 	c := mustDial(t, false)
 	defer c.Close()
-
-	if err := c.Text.PrintfLine("NOOP"); err != nil {
-		t.Fatalf("Failed to write NOOP: %v", err)
-	}
-
-	if _, _, err := c.Text.ReadResponse(250); err != nil {
-		t.Errorf("Incorrect NOOP response: %v", err)
-	}
+	simpleCmd(t, c, "HELP", 214)
+	simpleCmd(t, c, "NOOP", 250)
+	simpleCmd(t, c, "VRFY", 252)
+	simpleCmd(t, c, "EXPN", 252)
 }
 
 func TestReset(t *testing.T) {