Added support for LISTing a single POP3 message
authorDan Fandrich <dan@coneharvesters.com>
Thu, 17 Mar 2011 23:59:30 +0000 (16:59 -0700)
committerDan Fandrich <dan@coneharvesters.com>
Thu, 17 Mar 2011 23:59:30 +0000 (16:59 -0700)
Added tests for a number of POP3 LIST operations, including one
that shows a curl problem when listing no messages, so is
disabled.

lib/pop3.c
lib/pop3.h
tests/data/DISABLED
tests/data/Makefile.am
tests/data/test808 [new file with mode: 0644]
tests/data/test809 [new file with mode: 0644]
tests/data/test810 [new file with mode: 0644]
tests/data/test811 [new file with mode: 0644]
tests/ftpserver.pl

index 65169cf..e48c9b4 100644 (file)
@@ -436,6 +436,24 @@ static CURLcode pop3_state_list_resp(struct connectdata *conn,
   return result;
 }
 
+/* for LIST response with a given message */
+static CURLcode pop3_state_list_single_resp(struct connectdata *conn,
+                                     int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != 'O') {
+    failf(data, "Invalid message. %c", pop3code);
+    result = CURLE_REMOTE_FILE_NOT_FOUND;
+  }
+
+  state(conn, POP3_STOP);
+  return result;
+}
+
 /* start the DO phase for RETR */
 static CURLcode pop3_retr(struct connectdata *conn)
 {
@@ -460,7 +478,10 @@ static CURLcode pop3_list(struct connectdata *conn)
   if(result)
     return result;
 
-  state(conn, POP3_LIST);
+  if (strlen(pop3c->mailbox))
+    state(conn, POP3_LIST_SINGLE);
+  else
+    state(conn, POP3_LIST);
   return result;
 }
 
@@ -523,6 +544,10 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
       result = pop3_state_list_resp(conn, pop3code, pop3c->state);
       break;
 
+    case POP3_LIST_SINGLE:
+      result = pop3_state_list_single_resp(conn, pop3code, pop3c->state);
+      break;
+
     case POP3_QUIT:
       /* fallthrough, just stop! */
     default:
@@ -747,7 +772,7 @@ CURLcode pop3_perform(struct connectdata *conn,
   /* If mailbox is empty, then assume user wants listing for mail IDs,
    * otherwise, attempt to retrieve the mail-id stored in mailbox
    */
-  if (strlen(pop3c->mailbox))
+  if (strlen(pop3c->mailbox) && !conn->data->set.ftp_list_only)
     result = pop3_retr(conn);
   else
     result = pop3_list(conn);
index 337421c..1525673 100644 (file)
@@ -33,6 +33,7 @@ typedef enum {
   POP3_PASS,
   POP3_STARTTLS,
   POP3_LIST,
+  POP3_LIST_SINGLE,
   POP3_RETR,
   POP3_QUIT,
   POP3_LAST  /* never used */
index b6071cb..9ac123b 100644 (file)
@@ -3,3 +3,4 @@
 # per line.
 # Lines starting with '#' letters are treated as comments.
 564
+811
index c3c68ca..502abec 100644 (file)
@@ -70,7 +70,8 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46           \
  test313 test1115 test578 test579 test1116 test1200 test1201 test1202     \
  test1203 test1117 test1118 test1119 test1120 test1300 test1301 test1302 \
  test1303 test320 test321 test322 test323 test324 test1121 test581 test580 \
- test1304 test1305 test1306 test1307 test582 test583
+ test1304 test1305 test1306 test1307 test582 test583 test808 test809       \
+ test810 test811
 
 filecheck:
        @mkdir test-place; \
diff --git a/tests/data/test808 b/tests/data/test808
new file mode 100644 (file)
index 0000000..756801c
--- /dev/null
@@ -0,0 +1,41 @@
+<testcase>
+<info>
+<keywords>
+POP3
+LIST
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+REPLY LIST +OK 808 100
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+pop3
+</server>
+ <name>
+POP3 LIST one message
+ </name>
+ <command>
+pop3://%HOSTIP:%POP3PORT/808 -l -u user:secret
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER user\r
+PASS secret\r
+LIST 808\r
+QUIT\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test809 b/tests/data/test809
new file mode 100644 (file)
index 0000000..29358e0
--- /dev/null
@@ -0,0 +1,45 @@
+<testcase>
+<info>
+<keywords>
+POP3
+LIST
+FAILURE
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+REPLY LIST -ERR no such message
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+pop3
+</server>
+ <name>
+POP3 LIST invalid message
+ </name>
+ <command>
+pop3://%HOSTIP:%POP3PORT/809 -l -u user:secret
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+78
+</errorcode>
+<protocol>
+USER user\r
+PASS secret\r
+LIST 809\r
+QUIT\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test810 b/tests/data/test810
new file mode 100644 (file)
index 0000000..d4f7597
--- /dev/null
@@ -0,0 +1,45 @@
+<testcase>
+<info>
+<keywords>
+POP3
+LIST
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+# When doing LIST, we get the default list output hard-coded in the test
+# POP3 server
+<datacheck>
+1 100\r
+2 4294967400\r
+4 200\r
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+pop3
+</server>
+ <name>
+POP3 LIST messages
+ </name>
+ <command>
+pop3://%HOSTIP:%POP3PORT/ -u user:secret
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER user\r
+PASS secret\r
+LIST \r
+QUIT\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test811 b/tests/data/test811
new file mode 100644 (file)
index 0000000..850e5e2
--- /dev/null
@@ -0,0 +1,43 @@
+<testcase>
+<info>
+<keywords>
+POP3
+LIST
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+REPLY LIST +OK but no messages\r\n.
+</servercmd>
+<datacheck>
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+pop3
+</server>
+ <name>
+POP3 LIST no messages available
+ </name>
+ <command>
+pop3://%HOSTIP:%POP3PORT/ -u user:secret
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER user\r
+PASS secret\r
+LIST \r
+QUIT\r
+</protocol>
+</verify>
+</testcase>
index bbbf7be..182511f 100755 (executable)
@@ -392,6 +392,7 @@ sub protocolsetup {
     elsif($proto eq 'pop3') {
         %commandfunc = (
             'RETR' => \&RETR_pop3,
+            'LIST' => \&LIST_pop3,
         );
         %displaytext = (
             'USER' => '+OK We are happy you popped in!',
@@ -683,6 +684,29 @@ sub RETR_pop3 {
      return 0;
 }
 
+sub LIST_pop3 {
+
+# this is a built-in fake-message list
+my @pop3list=(
+"1 100\r\n",
+"2 4294967400\r\n",    # > 4 GB
+"4 200\r\n", # Note that message 3 is a simulated "deleted" message
+);
+
+     logmsg "retrieve a message list\n";
+
+     sendcontrol "+OK Listing starts\r\n";
+
+     for my $d (@pop3list) {
+         sendcontrol $d;
+     }
+
+     # end with the magic 5-byte end of listing marker
+     sendcontrol "\r\n.\r\n";
+
+     return 0;
+}
+
 ################
 ################ FTP commands
 ################