mirror of
https://github.com/axllent/mailpit.git
synced 2026-03-03 03:57:01 +00:00
Fix: Support optional UIDL argument in POP3 server (#552)
* fix: use single-line response when UIDL has an argument
The test changes included here don't necessarily deal with the fact that
the response used to be multi-line: the failure wouldn't occur during
the `c.Uidl()` calls, but rather on the next one as the client would
still have data from the server to receive, causing a parsing error like
so:
pop3_test.go:103: strconv.Atoi: parsing "unique-id": invalid syntax
The server now correctly replies with a single line response when an
argument is passed, as required by [the spec][1]
[1]: https://www.rfc-editor.org/rfc/rfc1939.html#page-12
* fix: UIDL accepts at most one argument
This commit is contained in:
@@ -84,6 +84,43 @@ func TestPOP3(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
t.Log("Checking UIDL with multiple arguments")
|
||||
|
||||
_, err = c.Cmd("UIDL", false, 1, 2, 3)
|
||||
if err == nil {
|
||||
t.Error("UIDL with multiple arguments should return an error")
|
||||
return
|
||||
}
|
||||
|
||||
t.Log("Checking UIDL without a message id")
|
||||
|
||||
messageIDs, err := c.Uidl(0)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(messageIDs) != 50 {
|
||||
assertEqual(t, len(messageIDs), 50, "incorrect UIDL message count")
|
||||
}
|
||||
|
||||
t.Log("Checking UIDL with a message ID")
|
||||
|
||||
messageIDs, err = c.Uidl(50)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
assertEqual(t, len(messageIDs), 1, "incorrect UIDL message count")
|
||||
|
||||
t.Log("Checking UIDL with an invalid message ID")
|
||||
|
||||
if _, err := c.Uidl(51); err == nil {
|
||||
t.Errorf("UIDL 51 should return an error")
|
||||
return
|
||||
}
|
||||
|
||||
t.Log("Deleting 25 messages")
|
||||
|
||||
for i := 1; i <= 25; i++ {
|
||||
|
||||
@@ -239,11 +239,31 @@ func handleTransactionCommand(conn net.Conn, cmd string, args []string, messages
|
||||
sendResponse(conn, ".")
|
||||
}
|
||||
case "UIDL":
|
||||
sendResponse(conn, "+OK unique-id listing follows")
|
||||
for row, m := range messages {
|
||||
sendResponse(conn, fmt.Sprintf("%d %s", row+1, m.ID))
|
||||
if len(args) > 1 {
|
||||
sendResponse(conn, "-ERR UIDL takes at most one argument")
|
||||
} else if len(args) == 1 {
|
||||
nr, err := strconv.Atoi(args[0])
|
||||
if err != nil {
|
||||
sendResponse(conn, "-ERR no such message")
|
||||
return
|
||||
}
|
||||
|
||||
if nr < 1 || nr > len(messages) {
|
||||
sendResponse(conn, "-ERR no such message")
|
||||
return
|
||||
}
|
||||
|
||||
m := messages[nr-1]
|
||||
|
||||
sendResponse(conn, fmt.Sprintf("+OK %d %s", nr, m.ID))
|
||||
} else {
|
||||
sendResponse(conn, "+OK unique-id listing follows")
|
||||
for row, m := range messages {
|
||||
sendResponse(conn, fmt.Sprintf("%d %s", row+1, m.ID))
|
||||
}
|
||||
sendResponse(conn, ".")
|
||||
}
|
||||
sendResponse(conn, ".")
|
||||
|
||||
case "RETR":
|
||||
if len(args) != 1 {
|
||||
sendResponse(conn, "-ERR no such message")
|
||||
|
||||
Reference in New Issue
Block a user