Fixing bug where FtpServer returned an error if an unknown fact was used in OPTS MLST. Also, correctly handling the case if only file names (no facts) are wished by the client (FTPSERVER-412)

git-svn-id: https://svn.apache.org/repos/asf/mina/ftpserver/trunk@1101808 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_MLST.java b/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_MLST.java
index 9165d45..196d619 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_MLST.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_MLST.java
@@ -20,6 +20,8 @@
 package org.apache.ftpserver.command.impl;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.StringTokenizer;
 
 import org.apache.ftpserver.command.AbstractCommand;
@@ -55,22 +57,23 @@
 
         // get the listing types
         String argument = request.getArgument();
+
+        String listTypes;
+        String types[];
         int spIndex = argument.indexOf(' ');
         if (spIndex == -1) {
-            session.write(LocalizedFtpReply.translate(session, request, context,
-                    FtpReply.REPLY_503_BAD_SEQUENCE_OF_COMMANDS, "OPTS.MLST",
-                    null));
-            return;
+            types = new String[0];
+            listTypes = "";
+        } else {
+            listTypes = argument.substring(spIndex + 1);
+    
+            // parse all the type tokens
+            StringTokenizer st = new StringTokenizer(listTypes, ";");
+            types = new String[st.countTokens()];
+            for (int i = 0; i < types.length; ++i) {
+                types[i] = st.nextToken();
+            }
         }
-        String listTypes = argument.substring(spIndex + 1);
-
-        // parse all the type tokens
-        StringTokenizer st = new StringTokenizer(listTypes, ";");
-        String types[] = new String[st.countTokens()];
-        for (int i = 0; i < types.length; ++i) {
-            types[i] = st.nextToken();
-        }
-
         // set the list types
         String[] validatedTypes = validateSelectedTypes(types);
         if (validatedTypes != null) {
@@ -88,26 +91,20 @@
 
         // ignore null types
         if (types == null) {
-            return null;
+            return new String[0];
         }
 
+        List<String> selectedTypes = new ArrayList<String>();
         // check all the types
         for (int i = 0; i < types.length; ++i) {
-            boolean bMatch = false;
             for (int j = 0; j < AVAILABLE_TYPES.length; ++j) {
                 if (AVAILABLE_TYPES[j].equalsIgnoreCase(types[i])) {
-                    bMatch = true;
+                    selectedTypes.add(AVAILABLE_TYPES[j]);
                     break;
                 }
             }
-            if (!bMatch) {
-                return null;
-            }
         }
 
-        // set the user types
-        String[] selectedTypes = new String[types.length];
-        System.arraycopy(types, 0, selectedTypes, 0, types.length);
-        return selectedTypes;
+        return selectedTypes.toArray(new String[0]);
     }
 }
diff --git a/core/src/test/java/org/apache/ftpserver/clienttests/ListTest.java b/core/src/test/java/org/apache/ftpserver/clienttests/ListTest.java
index bb15c9b..cf82058 100644
--- a/core/src/test/java/org/apache/ftpserver/clienttests/ListTest.java
+++ b/core/src/test/java/org/apache/ftpserver/clienttests/ListTest.java
@@ -232,13 +232,51 @@
                 + TEST_FILE1.getName(), reply[1]);
     }
 
-    public void testOPTSMLSTInvalidType() throws Exception {
+    /**
+     * "Facts requested that are not
+     * supported, or that are inappropriate to the file or directory being
+     * listed should simply be omitted from the MLSx output."
+     * 
+     * http://tools.ietf.org/html/rfc3659#section-7.9
+     */
+    public void testOPTSMLSTUnknownFact() throws Exception {
         TEST_FILE1.createNewFile();
 
-        assertTrue(FTPReply.isNegativePermanent(client
+        assertTrue(FTPReply.isPositiveCompletion(client
                 .sendCommand("OPTS MLST Foo;Size")));
+        
+        assertTrue(FTPReply.isPositiveCompletion(client.sendCommand("MLST "
+                + TEST_FILE1.getName())));
+        
+        String[] reply = client.getReplyString().split("\\r\\n");
+        
+        assertEquals("Size=0; "
+                + TEST_FILE1.getName(), reply[1]);
     }
 
+    /**
+     * "Facts requested that are not
+     * supported, or that are inappropriate to the file or directory being
+     * listed should simply be omitted from the MLSx output."
+     * 
+     * http://tools.ietf.org/html/rfc3659#section-7.9
+     */
+    public void testOPTSMLSTNoFacts() throws Exception {
+        TEST_FILE1.createNewFile();
+
+        assertTrue(FTPReply.isPositiveCompletion(client
+                .sendCommand("OPTS MLST")));
+        
+        assertTrue(FTPReply.isPositiveCompletion(client.sendCommand("MLST "
+                + TEST_FILE1.getName())));
+        
+        String[] reply = client.getReplyString().split("\\r\\n");
+        
+        assertEquals(" "
+                + TEST_FILE1.getName(), reply[1]);
+    }
+
+    
     private FTPFile getFile(FTPFile[] files, String name) {
         for (int i = 0; i < files.length; i++) {
             FTPFile file = files[i];