diff --git a/core/pom.xml b/core/pom.xml
index 9fc4264f..ce064eee 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -17,13 +17,13 @@
ftpserver-parentorg.apache.ftpserver
- 1.0.0-RC3-SNAPSHOT
+ 1.0.7-SNAPSHOT4.0.0org.apache.ftpserverftpserver-coreApache FtpServer Core
- 1.0.0-RC3-SNAPSHOT
+ 1.0.7-SNAPSHOTbundle
@@ -58,32 +58,25 @@
org.apache.felixmaven-bundle-plugin
- 1.4.1
+ 2.3.4true ${artifactId}The Apache Software Foundation
- org.apache.ftpserver;version=${pom.version},
- org.apache.ftpserver.command;version=${pom.version},
- org.apache.ftpserver.config.spring;version=${pom.version},
- org.apache.ftpserver.filesystem.nativefs;version=${pom.version},
- org.apache.ftpserver.ftpletcontainer;version=${pom.version},
- org.apache.ftpserver.listener;version=${pom.version},
- org.apache.ftpserver.main;version=${pom.version},
- org.apache.ftpserver.message;version=${pom.version},
- org.apache.ftpserver.ssl;version=${pom.version},
- org.apache.ftpserver.usermanager;version=${pom.version}
+ org.apache.ftpserver;version=${project.version},
+ org.apache.ftpserver.command;version=${project.version},
+ org.apache.ftpserver.config.spring;version=${project.version},
+ org.apache.ftpserver.filesystem.nativefs;version=${project.version},
+ org.apache.ftpserver.ftpletcontainer;version=${project.version},
+ org.apache.ftpserver.ipfilter;version=${project.version},
+ org.apache.ftpserver.listener;version=${project.version},
+ org.apache.ftpserver.main;version=${project.version},
+ org.apache.ftpserver.message;version=${project.version},
+ org.apache.ftpserver.ssl;version=${project.version},
+ org.apache.ftpserver.usermanager;version=${project.version}
- org.apache.ftpserver.command.impl,
- org.apache.ftpserver.command.impl.listing,
- org.apache.ftpserver.filesystem.nativefs.impl,
- org.apache.ftpserver.ftpletcontainer.impl,
- org.apache.ftpserver.impl, org.apache.ftpserver.listener.nio,
- org.apache.ftpserver.message.impl, org.apache.ftpserver.ssl.impl,
- org.apache.ftpserver.usermanager.impl,
- org.apache.ftpserver.util
-
+
org.springframework.beans.factory.config;resolution:=optional;version="2.5",
org.springframework.beans.factory.support;resolution:=optional;version="2.5",
org.springframework.beans.factory.xml;resolution:=optional;version="2.5",
@@ -108,7 +101,7 @@
- ${groupId}
+ ${project.groupId}ftplet-api
@@ -159,11 +152,6 @@
commons-codectest
-
- oro
- oro
- test
- hsqldbhsqldb
diff --git a/core/src/examples/java/org/apache/ftpserver/examples/EmbeddingFtpServer.java b/core/src/examples/java/org/apache/ftpserver/examples/EmbeddingFtpServer.java
index 6b970b09..3e3d5576 100644
--- a/core/src/examples/java/org/apache/ftpserver/examples/EmbeddingFtpServer.java
+++ b/core/src/examples/java/org/apache/ftpserver/examples/EmbeddingFtpServer.java
@@ -1,5 +1,3 @@
-package org.apache.ftpserver.examples;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -19,6 +17,8 @@
* under the License.
*/
+package org.apache.ftpserver.examples;
+
import java.io.File;
import org.apache.ftpserver.FtpServer;
@@ -27,6 +27,9 @@
import org.apache.ftpserver.ssl.SslConfigurationFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
+/**
+* @author Apache MINA Project*
+*/
public class EmbeddingFtpServer {
public static void main(String[] args) throws Exception {
diff --git a/core/src/examples/java/org/apache/ftpserver/examples/ManagingUsers.java b/core/src/examples/java/org/apache/ftpserver/examples/ManagingUsers.java
index bec4802d..e19cd828 100644
--- a/core/src/examples/java/org/apache/ftpserver/examples/ManagingUsers.java
+++ b/core/src/examples/java/org/apache/ftpserver/examples/ManagingUsers.java
@@ -25,8 +25,12 @@
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.SaltedPasswordEncryptor;
+import org.apache.ftpserver.usermanager.UserFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
+/**
+* @author Apache MINA Project*
+*/
public class ManagingUsers {
public static void main(String[] args) throws Exception {
@@ -35,11 +39,11 @@ public static void main(String[] args) throws Exception {
userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
UserManager um = userManagerFactory.createUserManager();
- BaseUser user = new BaseUser();
- user.setName("myNewUser");
- user.setPassword("secret");
- user.setHomeDirectory("ftproot");
-
+ UserFactory userFact = new UserFactory();
+ userFact.setName("myNewUser");
+ userFact.setPassword("secret");
+ userFact.setHomeDirectory("ftproot");
+ User user = userFact.createUser();
um.save(user);
}
}
diff --git a/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java b/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java
index cd0d7bb5..cdacad47 100644
--- a/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java
+++ b/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java
@@ -23,9 +23,7 @@
* Interface for providing the configuration for the control socket connections.
*
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
- *
+ * @author Apache MINA Project
*/
public interface ConnectionConfig {
@@ -60,4 +58,13 @@ public interface ConnectionConfig {
* @return true if anonymous logins are enabled
*/
boolean isAnonymousLoginEnabled();
+
+ /**
+ * Returns the maximum number of threads the server is allowed to create for
+ * processing client requests.
+ *
+ * @return the maximum number of threads the server is allowed to create for
+ * processing client requests.
+ */
+ int getMaxThreads();
}
diff --git a/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java b/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java
index 84e71117..b59bd874 100644
--- a/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java
@@ -24,9 +24,7 @@
/**
* Factory for creating connection configurations
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
- *
+ * @author Apache MINA Project
*/
public class ConnectionConfigFactory {
@@ -40,6 +38,8 @@ public class ConnectionConfigFactory {
private int loginFailureDelay = 500;
+ private int maxThreads = 0;
+
/**
* Create a connection configuration instances based on the configuration on this factory
* @return The {@link ConnectionConfig} instance
@@ -47,9 +47,9 @@ public class ConnectionConfigFactory {
public ConnectionConfig createConnectionConfig() {
return new DefaultConnectionConfig(anonymousLoginEnabled,
loginFailureDelay, maxLogins, maxAnonymousLogins,
- maxLoginFailures);
+ maxLoginFailures, maxThreads);
}
-
+
/**
* The delay in number of milliseconds between login failures. Important to
* make brute force attacks harder.
@@ -61,8 +61,8 @@ public int getLoginFailureDelay() {
}
/**
- * The maximum number of time an anonymous user can fail to login before getting disconnected
- * @return The maximum number of failer login attempts
+ * The maximum number of anonymous logins the server would allow at any given time
+ * @return The maximum number of anonymous logins
*/
public int getMaxAnonymousLogins() {
return maxAnonymousLogins;
@@ -101,6 +101,29 @@ public void setMaxLogins(final int maxLogins) {
this.maxLogins = maxLogins;
}
+ /**
+ * Returns the maximum number of threads the server is allowed to create for
+ * processing client requests.
+ *
+ * @return the maximum number of threads the server is allowed to create for
+ * processing client requests.
+ */
+ public int getMaxThreads() {
+ return maxThreads;
+ }
+
+ /**
+ * Sets the maximum number of threads the server is allowed to create for
+ * processing client requests.
+ *
+ * @param maxThreads
+ * the maximum number of threads the server is allowed to create
+ * for processing client requests.
+ */
+ public void setMaxThreads(int maxThreads) {
+ this.maxThreads = maxThreads;
+ }
+
/**
* Set if anonymous logins are allowed at the server
* @param anonymousLoginEnabled true if anonymous logins should be enabled
@@ -110,8 +133,8 @@ public void setAnonymousLoginEnabled(final boolean anonymousLoginEnabled) {
}
/**
- * Sets the maximum number of time an anonymous user can fail to login before getting disconnected
- * @param maxAnonymousLogins The maximum number of failer login attempts
+ * Sets the maximum number of anonymous logins the server would allow at any given time
+ * @param maxAnonymousLogins The maximum number of anonymous logins
*/
public void setMaxAnonymousLogins(final int maxAnonymousLogins) {
this.maxAnonymousLogins = maxAnonymousLogins;
diff --git a/core/src/main/java/org/apache/ftpserver/DataConnectionConfiguration.java b/core/src/main/java/org/apache/ftpserver/DataConnectionConfiguration.java
index b67fcfc8..6cdd11e8 100644
--- a/core/src/main/java/org/apache/ftpserver/DataConnectionConfiguration.java
+++ b/core/src/main/java/org/apache/ftpserver/DataConnectionConfiguration.java
@@ -26,8 +26,7 @@
/**
* Data connection configuration interface.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public interface DataConnectionConfiguration {
diff --git a/core/src/main/java/org/apache/ftpserver/DataConnectionConfigurationFactory.java b/core/src/main/java/org/apache/ftpserver/DataConnectionConfigurationFactory.java
index 20e2d080..0e2e3335 100644
--- a/core/src/main/java/org/apache/ftpserver/DataConnectionConfigurationFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/DataConnectionConfigurationFactory.java
@@ -21,19 +21,23 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.Collections;
import org.apache.ftpserver.impl.DefaultDataConnectionConfiguration;
import org.apache.ftpserver.impl.PassivePorts;
import org.apache.ftpserver.ssl.SslConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Data connection factory
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev: 701863 $, $Date: 2008-10-05 21:25:50 +0200 (Sun, 05 Oct 2008) $
+ * @author Apache MINA Project
*/
public class DataConnectionConfigurationFactory {
+ private Logger log = LoggerFactory.getLogger(DataConnectionConfigurationFactory.class);
+
// maximum idle time in seconds
private int idleTime = 300;
private SslConfiguration ssl;
@@ -45,7 +49,7 @@ public class DataConnectionConfigurationFactory {
private String passiveAddress;
private String passiveExternalAddress;
- private PassivePorts passivePorts = new PassivePorts(new int[] { 0 });
+ private PassivePorts passivePorts = new PassivePorts(Collections.emptySet(), true);
private boolean implicitSsl;
/**
@@ -212,6 +216,7 @@ public synchronized int requestPassivePort() {
// no available free port - wait for the release notification
if (dataPort == -1) {
try {
+ log.info("Out of passive ports, waiting for one to be released. Might be stuck");
wait();
} catch (InterruptedException ex) {
}
@@ -245,7 +250,7 @@ public String getPassivePorts() {
* @param passivePorts The passive ports string
*/
public void setPassivePorts(String passivePorts) {
- this.passivePorts = new PassivePorts(passivePorts);
+ this.passivePorts = new PassivePorts(passivePorts, true);
}
diff --git a/core/src/main/java/org/apache/ftpserver/DataConnectionException.java b/core/src/main/java/org/apache/ftpserver/DataConnectionException.java
index 246375cc..626cf80e 100644
--- a/core/src/main/java/org/apache/ftpserver/DataConnectionException.java
+++ b/core/src/main/java/org/apache/ftpserver/DataConnectionException.java
@@ -24,8 +24,7 @@
/**
* Thrown if a data connection can not be established
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DataConnectionException extends FtpException {
private static final long serialVersionUID = -1328383839917648987L;
@@ -67,6 +66,6 @@ public DataConnectionException(final Throwable th) {
* the original cause
*/
public DataConnectionException(final String msg, final Throwable th) {
- super(msg);
+ super(msg, th);
}
}
diff --git a/core/src/main/java/org/apache/ftpserver/FtpServer.java b/core/src/main/java/org/apache/ftpserver/FtpServer.java
index 08e6a2fb..6f84e496 100644
--- a/core/src/main/java/org/apache/ftpserver/FtpServer.java
+++ b/core/src/main/java/org/apache/ftpserver/FtpServer.java
@@ -27,8 +27,7 @@
* thread. Server implementation is used to create the server
* socket and handle client connection.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev: 701885 $, $Date: 2008-10-05 22:51:37 +0200 (Sun, 05 Oct 2008) $
+ * @author Apache MINA Project
*/
public interface FtpServer {
diff --git a/core/src/main/java/org/apache/ftpserver/FtpServerConfigurationException.java b/core/src/main/java/org/apache/ftpserver/FtpServerConfigurationException.java
index 232a6571..ae19a520 100644
--- a/core/src/main/java/org/apache/ftpserver/FtpServerConfigurationException.java
+++ b/core/src/main/java/org/apache/ftpserver/FtpServerConfigurationException.java
@@ -23,8 +23,7 @@
* Exception used during startup to indicate that the configuration is not
* correct.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class FtpServerConfigurationException extends RuntimeException {
diff --git a/core/src/main/java/org/apache/ftpserver/FtpServerFactory.java b/core/src/main/java/org/apache/ftpserver/FtpServerFactory.java
index 30c1a444..cac1aa8b 100644
--- a/core/src/main/java/org/apache/ftpserver/FtpServerFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/FtpServerFactory.java
@@ -27,8 +27,8 @@
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.ftpletcontainer.impl.DefaultFtpletContainer;
-import org.apache.ftpserver.impl.DefaultFtpServerContext;
import org.apache.ftpserver.impl.DefaultFtpServer;
+import org.apache.ftpserver.impl.DefaultFtpServerContext;
import org.apache.ftpserver.listener.Listener;
import org.apache.ftpserver.message.MessageResource;
@@ -36,8 +36,7 @@
* This is the starting point of all the servers. Creates server instances based on
* the provided configuration.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev: 701885 $, $Date: 2008-10-05 22:51:37 +0200 (Sun, 05 Oct 2008) $
+ * @author Apache MINA Project
*/
public class FtpServerFactory {
diff --git a/core/src/main/java/org/apache/ftpserver/command/AbstractCommand.java b/core/src/main/java/org/apache/ftpserver/command/AbstractCommand.java
index ef5b9993..43a06061 100644
--- a/core/src/main/java/org/apache/ftpserver/command/AbstractCommand.java
+++ b/core/src/main/java/org/apache/ftpserver/command/AbstractCommand.java
@@ -23,8 +23,7 @@
/**
* Common base class recommended for {@link Command} implementations
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public abstract class AbstractCommand implements Command {
diff --git a/core/src/main/java/org/apache/ftpserver/command/Command.java b/core/src/main/java/org/apache/ftpserver/command/Command.java
index ca520767..24c1dc1c 100644
--- a/core/src/main/java/org/apache/ftpserver/command/Command.java
+++ b/core/src/main/java/org/apache/ftpserver/command/Command.java
@@ -29,8 +29,7 @@
/**
* This interface encapsulates all the FTP commands.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public interface Command {
diff --git a/core/src/main/java/org/apache/ftpserver/command/CommandFactory.java b/core/src/main/java/org/apache/ftpserver/command/CommandFactory.java
index 713475d6..ced5bdad 100644
--- a/core/src/main/java/org/apache/ftpserver/command/CommandFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/command/CommandFactory.java
@@ -22,8 +22,7 @@
/**
* Command factory interface.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public interface CommandFactory {
diff --git a/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java b/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java
index 14e366a6..ad3a2316 100644
--- a/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java
@@ -73,8 +73,7 @@
/**
* Factory for {@link CommandFactory} instances
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class CommandFactoryFactory {
diff --git a/core/src/main/java/org/apache/ftpserver/command/NotSupportedCommand.java b/core/src/main/java/org/apache/ftpserver/command/NotSupportedCommand.java
index 3e501b39..0a7f14f8 100644
--- a/core/src/main/java/org/apache/ftpserver/command/NotSupportedCommand.java
+++ b/core/src/main/java/org/apache/ftpserver/command/NotSupportedCommand.java
@@ -31,8 +31,7 @@
* A command used primarily for overriding already installed commands when one
* wants to disable the command.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class NotSupportedCommand extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/ABOR.java b/core/src/main/java/org/apache/ftpserver/command/impl/ABOR.java
index 36d4dbb1..e1583bec 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/ABOR.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/ABOR.java
@@ -40,8 +40,7 @@
* Current implementation does not do anything. As here data transfers are not
* multi-threaded.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class ABOR extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/ACCT.java b/core/src/main/java/org/apache/ftpserver/command/impl/ACCT.java
index fd230c09..e57c6c4f 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/ACCT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/ACCT.java
@@ -36,8 +36,7 @@
* Acknowledges the ACCT (account) command with a 202 reply. The command however
* is irrelevant to any workings.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class ACCT extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java b/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java
index e769d2c7..c506d2e5 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java
@@ -52,8 +52,7 @@
* be appended to that file; otherwise the file specified in the pathname shall
* be created at the server site.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class APPE extends AbstractCommand {
@@ -162,6 +161,12 @@ public void execute(final FtpIoSession session,
// transfer data
long transSz = dataConnection.transferFromClient(session.getFtpletSession(), os);
+ // attempt to close the output stream so that errors in
+ // closing it will return an error to the client (FTPSERVER-119)
+ if(os != null) {
+ os.close();
+ }
+
LOG.info("File uploaded {}", fileName);
// notify the statistics component
@@ -169,11 +174,6 @@ public void execute(final FtpIoSession session,
.getFtpStatistics();
ftpStat.setUpload(session, file, transSz);
- // attempt to close the output stream so that errors in
- // closing it will return an error to the client (FTPSERVER-119)
- if(os != null) {
- os.close();
- }
} catch (SocketException e) {
LOG.debug("SocketException during file upload", e);
failure = true;
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/AUTH.java b/core/src/main/java/org/apache/ftpserver/command/impl/AUTH.java
index df1f8b4c..d3dfd17c 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/AUTH.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/AUTH.java
@@ -21,6 +21,8 @@
import java.io.IOException;
import java.security.GeneralSecurityException;
+import java.util.Arrays;
+import java.util.List;
import org.apache.ftpserver.command.AbstractCommand;
import org.apache.ftpserver.ftplet.FtpException;
@@ -40,8 +42,7 @@
*
* This server supports explicit SSL support.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class AUTH extends AbstractCommand {
@@ -49,6 +50,8 @@ public class AUTH extends AbstractCommand {
private final Logger LOG = LoggerFactory.getLogger(AUTH.class);
+ private static final List VALID_AUTH_TYPES = Arrays.asList("SSL", "TLS", "TLS-C", "TLS-P");
+
/**
* Execute command
*/
@@ -96,22 +99,17 @@ public void execute(final FtpIoSession session,
// check parameter
String authType = request.getArgument().toUpperCase();
- if (authType.equals("SSL")) {
- try {
- secureSession(session, "SSL");
- session.write(LocalizedFtpReply.translate(session, request, context,
- 234, "AUTH.SSL", null));
- } catch (FtpException ex) {
- throw ex;
- } catch (Exception ex) {
- LOG.warn("AUTH.execute()", ex);
- throw new FtpException("AUTH.execute()", ex);
+ if (VALID_AUTH_TYPES.contains(authType)) {
+ if(authType.equals("TLS-C")) {
+ authType = "TLS";
+ } else if(authType.equals("TLS-P")) {
+ authType = "SSL";
}
- } else if (authType.equals("TLS")) {
+
try {
- secureSession(session, "TLS");
+ secureSession(session, authType);
session.write(LocalizedFtpReply.translate(session, request, context,
- 234, "AUTH.TLS", null));
+ 234, "AUTH." + authType, null));
} catch (FtpException ex) {
throw ex;
} catch (Exception ex) {
@@ -149,6 +147,9 @@ private void secureSession(final FtpIoSession session, final String type)
session.getFilterChain().addFirst(SSL_SESSION_FILTER_NAME,
sslFilter);
+ if("SSL".equals(type)) {
+ session.getDataConnection().setSecure(true);
+ }
} else {
throw new FtpException("Socket factory SSL not configured");
}
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/CDUP.java b/core/src/main/java/org/apache/ftpserver/command/impl/CDUP.java
index 541643e2..90fee6ef 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/CDUP.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/CDUP.java
@@ -42,8 +42,7 @@
* systems having different syntaxes for naming the parent directory. The reply
* codes shall be identical to the reply codes of CWD.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class CDUP extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/CWD.java b/core/src/main/java/org/apache/ftpserver/command/impl/CWD.java
index 237e3421..c92cc1d6 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/CWD.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/CWD.java
@@ -42,8 +42,7 @@
* Transfer parameters are similarly unchanged. The argument is a pathname
* specifying a directory.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class CWD extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/DELE.java b/core/src/main/java/org/apache/ftpserver/command/impl/DELE.java
index 550504d7..3035e269 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/DELE.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/DELE.java
@@ -41,8 +41,7 @@
* This command causes the file specified in the pathname to be deleted at the
* server site.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DELE extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/DefaultCommandFactory.java b/core/src/main/java/org/apache/ftpserver/command/impl/DefaultCommandFactory.java
index b6ec7288..dea5a2e4 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/DefaultCommandFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/DefaultCommandFactory.java
@@ -34,8 +34,7 @@
*
* Internal class, do not use directly.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DefaultCommandFactory implements CommandFactory {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/EPRT.java b/core/src/main/java/org/apache/ftpserver/command/impl/EPRT.java
index 5fb10e69..81506a15 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/EPRT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/EPRT.java
@@ -43,8 +43,7 @@
*
* EPRT
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class EPRT extends AbstractCommand {
@@ -74,7 +73,7 @@ public void execute(final FtpIoSession session,
.getDataConnectionConfiguration();
if (!dataCfg.isActiveEnabled()) {
session.write(LocalizedFtpReply.translate(session, request, context,
- 510, "EPRT.disabled", null));
+ FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "EPRT.disabled", null));
return;
}
@@ -89,7 +88,7 @@ public void execute(final FtpIoSession session,
} catch (Exception ex) {
LOG.debug("Exception parsing host and port: " + arg, ex);
session.write(LocalizedFtpReply.translate(session, request, context,
- 510, "EPRT", null));
+ FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "EPRT", null));
return;
}
@@ -105,7 +104,7 @@ public void execute(final FtpIoSession session,
session,
request,
context,
- FtpReply.REPLY_553_REQUESTED_ACTION_NOT_TAKEN_FILE_NAME_NOT_ALLOWED,
+ FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS,
"EPRT.host", null));
return;
}
@@ -117,7 +116,7 @@ public void execute(final FtpIoSession session,
.getRemoteAddress()).getAddress();
if (!dataAddr.equals(clientAddr)) {
session.write(LocalizedFtpReply.translate(session, request,
- context, 510, "EPRT.mismatch", null));
+ context, FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "EPRT.mismatch", null));
return;
}
}
@@ -135,7 +134,7 @@ public void execute(final FtpIoSession session,
session,
request,
context,
- FtpReply.REPLY_552_REQUESTED_FILE_ACTION_ABORTED_EXCEEDED_STORAGE,
+ FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS,
"EPRT.invalid", null));
return;
}
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/EPSV.java b/core/src/main/java/org/apache/ftpserver/command/impl/EPSV.java
index 4f9ec1af..09c95830 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/EPSV.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/EPSV.java
@@ -44,8 +44,7 @@
* response code for entering passive mode using an extended address MUST be
* 229.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class EPSV extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/FEAT.java b/core/src/main/java/org/apache/ftpserver/command/impl/FEAT.java
index f2f5bb5f..e1558380 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/FEAT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/FEAT.java
@@ -37,8 +37,7 @@
* a server supports the FEAT command then it MUST advertise supported AUTH,
* PBSZ and PROT commands in the reply.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class FEAT extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/HELP.java b/core/src/main/java/org/apache/ftpserver/command/impl/HELP.java
index fcee7369..6a7ebcff 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/HELP.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/HELP.java
@@ -39,8 +39,7 @@
* may take an argument (e.g., any command name) and return more specific
* information as a response.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class HELP extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/LANG.java b/core/src/main/java/org/apache/ftpserver/command/impl/LANG.java
index 78214c1a..01422ccb 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/LANG.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/LANG.java
@@ -38,8 +38,7 @@
* process to determine in which language to present server greetings and the
* textual part of command responses.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class LANG extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java b/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java
index f0a26c1b..86f142e2 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java
@@ -54,8 +54,7 @@
* A null argument implies the user's current working or default directory. The
* data transfer is over the data connection.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class LIST extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/MD5.java b/core/src/main/java/org/apache/ftpserver/command/impl/MD5.java
index 10a46dbd..606b5be1 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/MD5.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/MD5.java
@@ -45,8 +45,7 @@
* Returns the MD5 value for a file or multiple files according to
* draft-twine-ftpmd5-00.txt.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class MD5 extends AbstractCommand {
@@ -90,7 +89,7 @@ public void execute(final FtpIoSession session,
fileNames = new String[] { argument };
}
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int i = 0; i < fileNames.length; i++) {
String fileName = fileNames[i].trim();
@@ -136,8 +135,14 @@ public void execute(final FtpIoSession session,
if (i > 0) {
sb.append(", ");
}
-
+ boolean nameHasSpaces = fileName.indexOf(' ') >= 0;
+ if(nameHasSpaces) {
+ sb.append('"');
+ }
sb.append(fileName);
+ if(nameHasSpaces) {
+ sb.append('"');
+ }
sb.append(' ');
sb.append(md5Hash);
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/MDTM.java b/core/src/main/java/org/apache/ftpserver/command/impl/MDTM.java
index c9e7861c..d67cd8bc 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/MDTM.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/MDTM.java
@@ -40,8 +40,7 @@
*
* Returns the date and time of when a file was modified.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class MDTM extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/MFMT.java b/core/src/main/java/org/apache/ftpserver/command/impl/MFMT.java
index 9ff73be3..db515b85 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/MFMT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/MFMT.java
@@ -40,8 +40,7 @@
* Specified in the following document:
* http://www.omz13.com/downloads/draft-somers-ftp-mfxx-00.html#anchor8
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class MFMT extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/MKD.java b/core/src/main/java/org/apache/ftpserver/command/impl/MKD.java
index e80862eb..6ad39d74 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/MKD.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/MKD.java
@@ -43,8 +43,7 @@
* a directory (if the pathname is absolute) or as a subdirectory of the current
* working directory (if the pathname is relative).
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class MKD extends AbstractCommand {
@@ -62,7 +61,7 @@ public void execute(final FtpIoSession session,
// argument check
String fileName = request.getArgument();
- if (fileName == null || fileName.indexOf(File.pathSeparatorChar) > -1) {
+ if (fileName == null) {
session.write(LocalizedFtpReply.translate(session, request, context,
FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS,
"MKD", null));
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java b/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java
index a1cfba9f..f1f49aa9 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java
@@ -52,8 +52,7 @@
* files in the specified directory. A null argument implies the user's current
* working or default directory. The data transfer is over the data connection
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class MLSD extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/MLST.java b/core/src/main/java/org/apache/ftpserver/command/impl/MLST.java
index 9ff5e57b..2c137c8f 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/MLST.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/MLST.java
@@ -43,8 +43,7 @@
*
* Returns info on the file over the control connection.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class MLST extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/MODE.java b/core/src/main/java/org/apache/ftpserver/command/impl/MODE.java
index 95637fae..4271b730 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/MODE.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/MODE.java
@@ -36,8 +36,7 @@
* The argument is a single Telnet character code specifying the data transfer
* modes described in the Section on Transmission Modes.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class MODE extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java b/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java
index 4cbfcb0b..61bdf59a 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java
@@ -53,8 +53,7 @@
* descriptor; a null argument implies the current directory. The server will
* return a stream of names of files and no other information.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class NLST extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/NOOP.java b/core/src/main/java/org/apache/ftpserver/command/impl/NOOP.java
index 2de01048..2c95d11f 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/NOOP.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/NOOP.java
@@ -37,8 +37,7 @@
* This command does not affect any parameters or previously entered commands.
* It specifies no action other than that the server send an OK reply.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class NOOP extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/OPTS.java b/core/src/main/java/org/apache/ftpserver/command/impl/OPTS.java
index 90ff2e3d..cc0742c3 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/OPTS.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/OPTS.java
@@ -41,8 +41,7 @@
* This command shall cause the server use optional features for the command
* specified.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class OPTS extends AbstractCommand {
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 ea17d84d..fe2b6a47 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;
@@ -36,8 +38,7 @@
* Client-Server listing negotation. Instruct the server what listing types to
* include in machine directory/file listings.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class OPTS_MLST extends AbstractCommand {
@@ -56,22 +57,23 @@ public void execute(final FtpIoSession session,
// 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;
- }
- 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();
+ 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();
+ }
}
-
// set the list types
String[] validatedTypes = validateSelectedTypes(types);
if (validatedTypes != null) {
@@ -89,26 +91,20 @@ private String[] validateSelectedTypes(final String types[]) {
// ignore null types
if (types == null) {
- return null;
+ return new String[0];
}
+ List selectedTypes = new ArrayList();
// 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].equals(types[i])) {
- bMatch = true;
+ if (AVAILABLE_TYPES[j].equalsIgnoreCase(types[i])) {
+ 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/main/java/org/apache/ftpserver/command/impl/OPTS_UTF8.java b/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_UTF8.java
index 7dac1c8d..a38d1bc6 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_UTF8.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/OPTS_UTF8.java
@@ -36,8 +36,7 @@
* UTF-8 and back. Note that the servers default encoding is UTF-8. So this
* command has no effect.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class OPTS_UTF8 extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/PASS.java b/core/src/main/java/org/apache/ftpserver/command/impl/PASS.java
index 93bc0920..e8f169f8 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/PASS.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/PASS.java
@@ -50,8 +50,7 @@
* The argument field is a Telnet string specifying the user's password. This
* command must be immediately preceded by the user name command.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class PASS extends AbstractCommand {
@@ -103,7 +102,14 @@ public void execute(final FtpIoSession session,
int currAnonLogin = stat.getCurrentAnonymousLoginNumber();
int maxAnonLogin = context.getConnectionConfig()
.getMaxAnonymousLogins();
+ if(maxAnonLogin == 0) {
+ LOG.debug("Currently {} anonymous users logged in, unlimited allowed", currAnonLogin);
+ } else {
+ LOG.debug("Currently {} out of {} anonymous users logged in", currAnonLogin, maxAnonLogin);
+ }
+
if (currAnonLogin >= maxAnonLogin) {
+ LOG.debug("Too many anonymous users logged in, user will be disconnected");
session
.write(LocalizedFtpReply
.translate(
@@ -119,7 +125,13 @@ public void execute(final FtpIoSession session,
// login limit check
int currLogin = stat.getCurrentLoginNumber();
int maxLogin = context.getConnectionConfig().getMaxLogins();
+ if(maxLogin == 0) {
+ LOG.debug("Currently {} users logged in, unlimited allowed", currLogin);
+ } else {
+ LOG.debug("Currently {} out of {} users logged in", currLogin, maxLogin);
+ }
if (maxLogin != 0 && currLogin >= maxLogin) {
+ LOG.debug("Too many users logged in, user will be disconnected");
session
.write(LocalizedFtpReply
.translate(
@@ -168,6 +180,19 @@ public void execute(final FtpIoSession session,
int oldMaxIdleTime = session.getMaxIdleTime();
if (authenticatedUser != null) {
+ if(!authenticatedUser.getEnabled()) {
+ session
+ .write(LocalizedFtpReply
+ .translate(
+ session,
+ request,
+ context,
+ FtpReply.REPLY_530_NOT_LOGGED_IN,
+ "PASS", null));
+ return;
+ }
+
+
session.setUser(authenticatedUser);
session.setUserArgument(null);
session.setMaxIdleTime(authenticatedUser.getMaxIdleTime());
@@ -197,6 +222,8 @@ public void execute(final FtpIoSession session,
.getMaxLoginFailures();
if (maxAllowedLoginFailues != 0
&& session.getFailedLogins() >= maxAllowedLoginFailues) {
+ LOG.warn("User exceeded the number of allowed failed logins, session will be closed");
+
session.close(false).awaitUninterruptibly(10000);
}
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/PASV.java b/core/src/main/java/org/apache/ftpserver/command/impl/PASV.java
index 200bc652..6ef1bf51 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/PASV.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/PASV.java
@@ -47,8 +47,7 @@
* upon receipt of a transfer command. The response to this command includes the
* host and port address this server is listening on.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class PASV extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/PBSZ.java b/core/src/main/java/org/apache/ftpserver/command/impl/PBSZ.java
index 6cb348b1..9f7d0237 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/PBSZ.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/PBSZ.java
@@ -34,8 +34,7 @@
*
* Protection buffer size.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class PBSZ extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/PORT.java b/core/src/main/java/org/apache/ftpserver/command/impl/PORT.java
index 1448a9c6..761dd4f3 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/PORT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/PORT.java
@@ -55,8 +55,7 @@
*
* where h1 is the high order 8 bits of the internet host address.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class PORT extends AbstractCommand {
@@ -85,16 +84,21 @@ public void execute(final FtpIoSession session,
.getDataConnectionConfiguration();
if (!dataCfg.isActiveEnabled()) {
session.write(LocalizedFtpReply.translate(session, request, context,
- 510, "PORT.disabled", null));
+ FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "PORT.disabled", null));
return;
}
InetSocketAddress address;
try {
address = SocketAddressEncoder.decode(request.getArgument());
+
+ // port must not be 0
+ if(address.getPort() == 0) {
+ throw new IllegalPortException("PORT port must not be 0");
+ }
} catch (IllegalInetAddressException e) {
session.write(LocalizedFtpReply.translate(session, request, context,
- 510, "PORT", null));
+ FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "PORT", null));
return;
} catch (IllegalPortException e) {
LOG.debug("Invalid data port: " + request.getArgument(), e);
@@ -104,7 +108,7 @@ public void execute(final FtpIoSession session,
session,
request,
context,
- FtpReply.REPLY_552_REQUESTED_FILE_ACTION_ABORTED_EXCEEDED_STORAGE,
+ FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS,
"PORT.invalid", null));
return;
} catch (UnknownHostException e) {
@@ -115,7 +119,7 @@ public void execute(final FtpIoSession session,
session,
request,
context,
- FtpReply.REPLY_553_REQUESTED_ACTION_NOT_TAKEN_FILE_NAME_NOT_ALLOWED,
+ FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS,
"PORT.host", null));
return;
}
@@ -127,7 +131,7 @@ public void execute(final FtpIoSession session,
.getRemoteAddress()).getAddress();
if (!address.getAddress().equals(clientAddr)) {
session.write(LocalizedFtpReply.translate(session, request,
- context, 510, "PORT.mismatch", null));
+ context, FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "PORT.mismatch", null));
return;
}
}
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/PROT.java b/core/src/main/java/org/apache/ftpserver/command/impl/PROT.java
index 7d50133c..119309c2 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/PROT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/PROT.java
@@ -37,8 +37,7 @@
*
* Data channel protection level.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class PROT extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/PWD.java b/core/src/main/java/org/apache/ftpserver/command/impl/PWD.java
index 8c0148f8..bb6902c9 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/PWD.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/PWD.java
@@ -38,8 +38,7 @@
* This command causes the name of the current working directory to be returned
* in the reply.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class PWD extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/QUIT.java b/core/src/main/java/org/apache/ftpserver/command/impl/QUIT.java
index fde131d9..128bb527 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/QUIT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/QUIT.java
@@ -27,6 +27,8 @@
import org.apache.ftpserver.impl.FtpIoSession;
import org.apache.ftpserver.impl.FtpServerContext;
import org.apache.ftpserver.impl.LocalizedFtpReply;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Internal class, do not use directly.
@@ -36,11 +38,12 @@
* This command terminates a USER and if file transfer is not in progress, the
* server closes the control connection.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class QUIT extends AbstractCommand {
+ private final Logger LOG = LoggerFactory.getLogger(QUIT.class);
+
/**
* Execute command
*/
@@ -51,6 +54,7 @@ public void execute(final FtpIoSession session,
session.write(LocalizedFtpReply.translate(session, request, context,
FtpReply.REPLY_221_CLOSING_CONTROL_CONNECTION, "QUIT", null));
+ LOG.debug("QUIT received, closing session");
session.close(false).awaitUninterruptibly(10000);
session.getDataConnection().closeDataConnection();
}
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/REIN.java b/core/src/main/java/org/apache/ftpserver/command/impl/REIN.java
index 88182fc6..e6d4385b 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/REIN.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/REIN.java
@@ -36,8 +36,7 @@
* This command flushes a USER, without affecting transfers in progress. The
* server state should otherwise be as when the user first connects.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class REIN extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/REST.java b/core/src/main/java/org/apache/ftpserver/command/impl/REST.java
index 70e7848b..a671af05 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/REST.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/REST.java
@@ -41,8 +41,7 @@
* followed by the appropriate FTP service command which shall cause file
* transfer to resume.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class REST extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java b/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java
index 16d2073c..ac3b4c88 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java
@@ -53,8 +53,7 @@
* connection. The status and contents of the file at the server site shall be
* unaffected.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class RETR extends AbstractCommand {
@@ -165,6 +164,11 @@ public void execute(final FtpIoSession session,
// transfer data
long transSz = dataConnection.transferToClient(session.getFtpletSession(), is);
+ // attempt to close the input stream so that errors in
+ // closing it will return an error to the client (FTPSERVER-119)
+ if(is != null) {
+ is.close();
+ }
LOG.info("File downloaded {}", fileName);
@@ -175,11 +179,6 @@ public void execute(final FtpIoSession session,
ftpStat.setDownload(session, file, transSz);
}
- // attempt to close the input stream so that errors in
- // closing it will return an error to the client (FTPSERVER-119)
- if(is != null) {
- is.close();
- }
} catch (SocketException ex) {
LOG.debug("Socket exception during data transfer", ex);
failure = true;
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/RMD.java b/core/src/main/java/org/apache/ftpserver/command/impl/RMD.java
index 32668c66..b934db76 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/RMD.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/RMD.java
@@ -42,8 +42,7 @@
* a directory (if the pathname is absolute) or as a subdirectory of the current
* working directory (if the pathname is relative).
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class RMD extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/RNFR.java b/core/src/main/java/org/apache/ftpserver/command/impl/RNFR.java
index a4b590ed..9548ab96 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/RNFR.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/RNFR.java
@@ -41,8 +41,7 @@
* This command must be immediately followed by a "rename to" command specifying
* the new file pathname.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class RNFR extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/RNTO.java b/core/src/main/java/org/apache/ftpserver/command/impl/RNTO.java
index 7b519673..54b7cbf1 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/RNTO.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/RNTO.java
@@ -41,8 +41,7 @@
* immediately preceding "rename from" command. Together the two commands cause
* a file to be renamed.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class RNTO extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/SITE.java b/core/src/main/java/org/apache/ftpserver/command/impl/SITE.java
index 4c79a8d0..52d3291e 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/SITE.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/SITE.java
@@ -38,8 +38,7 @@
*
* Handle SITE command.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SITE extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_DESCUSER.java b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_DESCUSER.java
index 7bef7151..c60bb7e3 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_DESCUSER.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_DESCUSER.java
@@ -41,8 +41,7 @@
*
* This SITE command returns the specified user information.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SITE_DESCUSER extends AbstractCommand {
@@ -97,7 +96,7 @@ public void execute(final FtpIoSession session,
}
// send the user information
- StringBuffer sb = new StringBuffer(128);
+ StringBuilder sb = new StringBuilder(128);
sb.append("\n");
sb.append("userid : ").append(user.getName()).append("\n");
sb.append("userpassword : ********\n");
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_HELP.java b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_HELP.java
index 5f572d59..bd4c9e47 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_HELP.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_HELP.java
@@ -34,8 +34,7 @@
*
* Show SITE help message.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SITE_HELP extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_STAT.java b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_STAT.java
index 2db027db..c39f496c 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_STAT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_STAT.java
@@ -38,8 +38,7 @@
*
* Show all statistics information.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SITE_STAT extends AbstractCommand {
@@ -64,7 +63,7 @@ public void execute(final FtpIoSession session,
// get statistics information
FtpStatistics stat = context.getFtpStatistics();
- StringBuffer sb = new StringBuffer(256);
+ StringBuilder sb = new StringBuilder(256);
sb.append('\n');
sb.append("Start Time : ").append(
DateUtils.getISO8601Date(stat.getStartTime().getTime()))
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_WHO.java b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_WHO.java
index 1f6769f1..c3d3a1d5 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_WHO.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_WHO.java
@@ -43,8 +43,7 @@
*
* Sends the list of all the connected users.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SITE_WHO extends AbstractCommand {
@@ -68,7 +67,7 @@ public void execute(final FtpIoSession session,
}
// print all the connected user information
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
Map sessions = session.getService()
.getManagedSessions();
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_ZONE.java b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_ZONE.java
index 62235ce6..64d41afe 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/SITE_ZONE.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/SITE_ZONE.java
@@ -36,8 +36,7 @@
*
* Displays the FTP server timezone in RFC 822 format.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SITE_ZONE extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/SIZE.java b/core/src/main/java/org/apache/ftpserver/command/impl/SIZE.java
index 9c18f784..99665fe5 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/SIZE.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/SIZE.java
@@ -39,8 +39,7 @@
*
* Returns the size of the file in bytes.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SIZE extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/STAT.java b/core/src/main/java/org/apache/ftpserver/command/impl/STAT.java
index 5f4896bf..2618f28d 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/STAT.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/STAT.java
@@ -22,6 +22,12 @@
import java.io.IOException;
import org.apache.ftpserver.command.AbstractCommand;
+import org.apache.ftpserver.command.impl.listing.DirectoryLister;
+import org.apache.ftpserver.command.impl.listing.LISTFileFormater;
+import org.apache.ftpserver.command.impl.listing.ListArgument;
+import org.apache.ftpserver.command.impl.listing.ListArgumentParser;
+import org.apache.ftpserver.ftplet.FtpException;
+import org.apache.ftpserver.ftplet.FtpFile;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.impl.FtpIoSession;
@@ -36,11 +42,14 @@
* This command shall cause a status response to be sent over the control
* connection in the form of a reply.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class STAT extends AbstractCommand {
+ private static final LISTFileFormater LIST_FILE_FORMATER = new LISTFileFormater();
+
+ private DirectoryLister directoryLister = new DirectoryLister();
+
/**
* Execute command
*/
@@ -51,9 +60,49 @@ public void execute(final FtpIoSession session,
// reset state variables
session.resetState();
- // write the status info
- session.write(LocalizedFtpReply.translate(session, request, context,
- FtpReply.REPLY_211_SYSTEM_STATUS_REPLY, "STAT", null));
+ if(request.getArgument() != null) {
+ ListArgument parsedArg = ListArgumentParser.parse(request.getArgument());
+
+ // check that the directory or file exists
+ FtpFile file = null;
+ try {
+ file = session.getFileSystemView().getFile(parsedArg.getFile());
+ if(!file.doesExist()) {
+ session.write(LocalizedFtpReply.translate(session, request, context,
+ FtpReply.REPLY_450_REQUESTED_FILE_ACTION_NOT_TAKEN, "LIST",
+ null));
+ return;
+ }
+
+ String dirList = directoryLister.listFiles(parsedArg,
+ session.getFileSystemView(), LIST_FILE_FORMATER);
+
+ int replyCode;
+ if(file.isDirectory()) {
+ replyCode = FtpReply.REPLY_212_DIRECTORY_STATUS;
+ } else {
+ replyCode = FtpReply.REPLY_213_FILE_STATUS;
+ }
+
+ session.write(LocalizedFtpReply.translate(session, request, context,
+ replyCode, "STAT",
+ dirList));
+
+ } catch (FtpException e) {
+ session.write(LocalizedFtpReply
+ .translate(
+ session,
+ request,
+ context,
+ FtpReply.REPLY_450_REQUESTED_FILE_ACTION_NOT_TAKEN,
+ "STAT", null));
+ }
+
+ } else {
+ // write the status info
+ session.write(LocalizedFtpReply.translate(session, request, context,
+ FtpReply.REPLY_211_SYSTEM_STATUS_REPLY, "STAT", null));
+ }
}
}
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java b/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java
index f8a93f79..4a6a6051 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java
@@ -52,8 +52,7 @@
* shall be replaced by the data being transferred. A new file is created at the
* server site if the file specified in the pathname does not already exist.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class STOR extends AbstractCommand {
@@ -146,6 +145,12 @@ public void execute(final FtpIoSession session,
outStream = file.createOutputStream(skipLen);
long transSz = dataConnection.transferFromClient(session.getFtpletSession(), outStream);
+ // attempt to close the output stream so that errors in
+ // closing it will return an error to the client (FTPSERVER-119)
+ if(outStream != null) {
+ outStream.close();
+ }
+
LOG.info("File uploaded {}", fileName);
// notify the statistics component
@@ -153,11 +158,6 @@ public void execute(final FtpIoSession session,
.getFtpStatistics();
ftpStat.setUpload(session, file, transSz);
- // attempt to close the output stream so that errors in
- // closing it will return an error to the client (FTPSERVER-119)
- if(outStream != null) {
- outStream.close();
- }
} catch (SocketException ex) {
LOG.debug("Socket exception during data transfer", ex);
failure = true;
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java b/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java
index 97cd00b0..6b506f2e 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java
@@ -52,8 +52,7 @@
* 150 Transfer Started response must include the name generated, See RFC1123
* section 4.1.2.9
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class STOU extends AbstractCommand {
@@ -153,6 +152,12 @@ public void execute(final FtpIoSession session,
// transfer data
long transSz = dataConnection.transferFromClient(session.getFtpletSession(), os);
+ // attempt to close the output stream so that errors in
+ // closing it will return an error to the client (FTPSERVER-119)
+ if(os != null) {
+ os.close();
+ }
+
LOG.info("File uploaded {}", fileName);
// notify the statistics component
@@ -162,11 +167,6 @@ public void execute(final FtpIoSession session,
ftpStat.setUpload(session, file, transSz);
}
- // attempt to close the output stream so that errors in
- // closing it will return an error to the client (FTPSERVER-119)
- if(os != null) {
- os.close();
- }
} catch (SocketException ex) {
LOG.debug("Socket exception during data transfer", ex);
failure = true;
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/STRU.java b/core/src/main/java/org/apache/ftpserver/command/impl/STRU.java
index b363fbcd..d86d0d01 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/STRU.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/STRU.java
@@ -38,8 +38,7 @@
*
* The argument is a single Telnet character code specifying file structure.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class STRU extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/SYST.java b/core/src/main/java/org/apache/ftpserver/command/impl/SYST.java
index b6209a94..e2612de4 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/SYST.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/SYST.java
@@ -35,8 +35,7 @@
*
* This command is used to find out the type of operating system at the server.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SYST extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/TYPE.java b/core/src/main/java/org/apache/ftpserver/command/impl/TYPE.java
index bc394f85..48ee344e 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/TYPE.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/TYPE.java
@@ -38,8 +38,7 @@
*
* The argument specifies the representation type.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class TYPE extends AbstractCommand {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/USER.java b/core/src/main/java/org/apache/ftpserver/command/impl/USER.java
index 93e0a96e..8e98e362 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/USER.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/USER.java
@@ -34,6 +34,8 @@
import org.apache.ftpserver.impl.ServerFtpStatistics;
import org.apache.ftpserver.usermanager.impl.ConcurrentLoginRequest;
import org.apache.mina.filter.logging.MdcInjectionFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Internal class, do not use directly.
@@ -45,11 +47,12 @@
* system. This command will normally be the first command transmitted by the
* user after the control connections are made.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class USER extends AbstractCommand {
+ private final Logger LOG = LoggerFactory.getLogger(USER.class);
+
/**
* Execute command.
*/
@@ -112,7 +115,14 @@ public void execute(final FtpIoSession session,
int currAnonLogin = stat.getCurrentAnonymousLoginNumber();
int maxAnonLogin = context.getConnectionConfig()
.getMaxAnonymousLogins();
+ if(maxAnonLogin == 0) {
+ LOG.debug("Currently {} anonymous users logged in, unlimited allowed", currAnonLogin);
+ } else {
+ LOG.debug("Currently {} out of {} anonymous users logged in", currAnonLogin, maxAnonLogin);
+ }
if (anonymous && (currAnonLogin >= maxAnonLogin)) {
+ LOG.debug("Too many anonymous users logged in, user will be disconnected");
+
session
.write(LocalizedFtpReply
.translate(
@@ -127,7 +137,16 @@ public void execute(final FtpIoSession session,
// login limit check
int currLogin = stat.getCurrentLoginNumber();
int maxLogin = context.getConnectionConfig().getMaxLogins();
+
+ if(maxLogin == 0) {
+ LOG.debug("Currently {} users logged in, unlimited allowed", currLogin);
+ } else {
+ LOG.debug("Currently {} out of {} users logged in", currLogin, maxLogin);
+ }
+
if (maxLogin != 0 && currLogin >= maxLogin) {
+ LOG.debug("Too many users logged in, user will be disconnected");
+
session
.write(LocalizedFtpReply
.translate(
@@ -154,6 +173,7 @@ public void execute(final FtpIoSession session,
stat.getCurrentUserLoginNumber(configUser, address) + 1);
if (configUser.authorize(loginRequest) == null) {
+ LOG.debug("User logged in too many sessions, user will be disconnected");
session
.write(LocalizedFtpReply
.translate(
@@ -182,6 +202,7 @@ public void execute(final FtpIoSession session,
// if not ok - close connection
if (!success) {
+ LOG.debug("User failed to login, session will be closed");
session.close(false).awaitUninterruptibly(10000);
}
}
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/DirectoryLister.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/DirectoryLister.java
index 5efbbc9b..49782829 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/DirectoryLister.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/DirectoryLister.java
@@ -32,14 +32,13 @@
*
* This class prints file listing.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DirectoryLister {
private String traverseFiles(final List files,
final FileFilter filter, final FileFormater formater) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
sb.append(traverseFiles(files, filter, formater, true));
sb.append(traverseFiles(files, filter, formater, false));
@@ -50,7 +49,7 @@ private String traverseFiles(final List files,
private String traverseFiles(final List files,
final FileFilter filter, final FileFormater formater,
boolean matchDirs) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (FtpFile file : files) {
if (file == null) {
continue;
@@ -70,13 +69,13 @@ public String listFiles(final ListArgument argument,
final FileSystemView fileSystemView, final FileFormater formater)
throws IOException {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
// get all the file objects
List files = listFiles(fileSystemView, argument.getFile());
if (files != null) {
FileFilter filter = null;
- if ((argument.hasOption('a'))) {
+ if (!argument.hasOption('a')) {
filter = new VisibleFileFilter();
}
if (argument.getPattern() != null) {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/FileFilter.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/FileFilter.java
index 0054d9b6..0fed5fc4 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/FileFilter.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/FileFilter.java
@@ -27,8 +27,7 @@
*
* @see java.io.FileFilter
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public interface FileFilter {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/FileFormater.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/FileFormater.java
index 3b21a9a9..96eb4826 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/FileFormater.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/FileFormater.java
@@ -25,8 +25,7 @@
*
* Interface for formating output based on a {@link FtpFile}
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public interface FileFormater {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/LISTFileFormater.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/LISTFileFormater.java
index 8d856edf..148d63e0 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/LISTFileFormater.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/LISTFileFormater.java
@@ -28,8 +28,7 @@
*
* Formats files according to the LIST specification
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class LISTFileFormater implements FileFormater {
@@ -41,7 +40,7 @@ public class LISTFileFormater implements FileFormater {
* @see FileFormater#format(FtpFile)
*/
public String format(FtpFile file) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
sb.append(getPermission(file));
sb.append(DELIM);
sb.append(DELIM);
@@ -100,8 +99,8 @@ private char[] getPermission(FtpFile file) {
}
/*
- * public String format(FileObject[] files) { StringBuffer sb = new
- * StringBuffer();
+ * public String format(FileObject[] files) { StringBuilder sb = new
+ * StringBuilder();
*
* for (int i = 0; i < files.length; i++) { sb.append(format(files[i]));
* sb.append(NEWLINE); } return sb.toString(); }
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/ListArgument.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/ListArgument.java
index d61adb8c..b1002ed5 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/ListArgument.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/ListArgument.java
@@ -23,8 +23,7 @@
*
* Contains the parsed argument for a list command (e.g. LIST or NLST)
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class ListArgument {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/ListArgumentParser.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/ListArgumentParser.java
index 4128135a..82c54b92 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/ListArgumentParser.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/ListArgumentParser.java
@@ -25,8 +25,7 @@
*
* Parses a list argument (e.g. for LIST or NLST) into a {@link ListArgument}
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class ListArgumentParser {
@@ -47,8 +46,8 @@ public static ListArgument parse(String argument) {
// find options and file name (may have regular expression)
if (argument != null) {
argument = argument.trim();
- StringBuffer optionsSb = new StringBuffer(4);
- StringBuffer fileSb = new StringBuffer(16);
+ StringBuilder optionsSb = new StringBuilder(4);
+ StringBuilder fileSb = new StringBuilder(16);
StringTokenizer st = new StringTokenizer(argument, " ", true);
while (st.hasMoreTokens()) {
String token = st.nextToken();
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/MLSTFileFormater.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/MLSTFileFormater.java
index 22561470..b3cd9267 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/MLSTFileFormater.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/MLSTFileFormater.java
@@ -26,8 +26,7 @@
*
* Formats files according to the MLST specification
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class MLSTFileFormater implements FileFormater {
@@ -52,7 +51,7 @@ public MLSTFileFormater(String[] selectedTypes) {
* @see FileFormater#format(FtpFile)
*/
public String format(FtpFile file) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int i = 0; i < selectedTypes.length; ++i) {
String type = selectedTypes[i];
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/NLSTFileFormater.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/NLSTFileFormater.java
index a2147cbe..7ab683a3 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/NLSTFileFormater.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/NLSTFileFormater.java
@@ -25,8 +25,7 @@
*
* Formats files according to the NLST specification
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class NLSTFileFormater implements FileFormater {
@@ -36,7 +35,7 @@ public class NLSTFileFormater implements FileFormater {
* @see FileFormater#format(FtpFile)
*/
public String format(FtpFile file) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
sb.append(file.getName());
sb.append(NEWLINE);
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/RegexFileFilter.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/RegexFileFilter.java
index c4791bca..490653ef 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/RegexFileFilter.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/RegexFileFilter.java
@@ -26,8 +26,7 @@
*
* Selects files which short name matches a regular expression
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class RegexFileFilter implements FileFilter {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/VisibleFileFilter.java b/core/src/main/java/org/apache/ftpserver/command/impl/listing/VisibleFileFilter.java
index 14e1a2e6..e424983d 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/VisibleFileFilter.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/VisibleFileFilter.java
@@ -25,8 +25,7 @@
*
* Selects files that are visible
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class VisibleFileFilter implements FileFilter {
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/listing/package.html b/core/src/main/java/org/apache/ftpserver/command/impl/listing/package.html
index 87346453..4a250c22 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/listing/package.html
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/listing/package.html
@@ -14,12 +14,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
-
-
-
+
+
+
+
+
Internal classes, do not use directly!
-
File listing implementations used by various FTP commands
-
-
+
File listing implementations used by various FTP commands
+
+
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/package.html b/core/src/main/java/org/apache/ftpserver/command/impl/package.html
index dc9e0e90..399ab0fd 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/package.html
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/package.html
@@ -14,12 +14,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
-
-
-
+
+
+
+
+
Internal classes, do not use directly!
-
FTP command implementations
-
-
+
FTP command implementations
+
+
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/CommandFactoryBeanDefinitionParser.java b/core/src/main/java/org/apache/ftpserver/config/spring/CommandFactoryBeanDefinitionParser.java
index 17680822..6239cf03 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/CommandFactoryBeanDefinitionParser.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/CommandFactoryBeanDefinitionParser.java
@@ -35,8 +35,7 @@
/**
* Parses the FtpServer "commands" element into a Spring bean graph
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class CommandFactoryBeanDefinitionParser extends
AbstractSingleBeanDefinitionParser {
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/FileSystemBeanDefinitionParser.java b/core/src/main/java/org/apache/ftpserver/config/spring/FileSystemBeanDefinitionParser.java
index 1f7c7119..8aa1ff6b 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/FileSystemBeanDefinitionParser.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/FileSystemBeanDefinitionParser.java
@@ -30,8 +30,7 @@
/**
* Parses the FtpServer "native-filesystem" element into a Spring bean graph
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class FileSystemBeanDefinitionParser extends
AbstractSingleBeanDefinitionParser {
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/FtpServerNamespaceHandler.java b/core/src/main/java/org/apache/ftpserver/config/spring/FtpServerNamespaceHandler.java
index 721cc24a..ae0ddcc0 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/FtpServerNamespaceHandler.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/FtpServerNamespaceHandler.java
@@ -24,8 +24,7 @@
/**
* Registration point for FtpServer bean defintion parsers
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class FtpServerNamespaceHandler extends NamespaceHandlerSupport {
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java b/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
index a94e7a2c..5be20bd8 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
@@ -21,11 +21,12 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
import org.apache.ftpserver.DataConnectionConfiguration;
import org.apache.ftpserver.DataConnectionConfigurationFactory;
+import org.apache.ftpserver.FtpServerConfigurationException;
+import org.apache.ftpserver.ipfilter.DefaultIpFilter;
+import org.apache.ftpserver.ipfilter.IpFilterType;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.ssl.SslConfiguration;
import org.apache.ftpserver.ssl.SslConfigurationFactory;
@@ -43,8 +44,7 @@
/**
* Parses the FtpServer "nio-listener" element into a Spring bean graph
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class ListenerBeanDefinitionParser extends
AbstractSingleBeanDefinitionParser {
@@ -60,45 +60,6 @@ protected Class> getBeanClass(final Element element) {
return null;
}
- /**
- * Parse CIDR notations into MINA {@link Subnet}s. TODO: move to Mina
- */
- private Subnet parseSubnet(final String subnet) {
- if (subnet == null) {
- throw new NullPointerException("subnet can not be null");
- }
-
- String[] tokens = subnet.split("/");
-
- String ipString;
- String maskString;
- if (tokens.length == 2) {
- ipString = tokens[0];
- maskString = tokens[1];
- } else if (tokens.length == 1) {
- ipString = tokens[0];
- maskString = "32";
- } else {
- throw new IllegalArgumentException("Illegal subnet format: "
- + subnet);
- }
-
- InetAddress address;
- try {
- address = InetAddress.getByName(ipString);
- } catch (UnknownHostException e) {
- throw new IllegalArgumentException("Illegal IP address in subnet: "
- + subnet);
- }
-
- int mask = Integer.parseInt(maskString);
- if (mask < 0 || mask > 32) {
- throw new IllegalArgumentException("Mask must be in the range 0-32");
- }
-
- return new Subnet(address, mask);
- }
-
/**
* {@inheritDoc}
*/
@@ -139,16 +100,30 @@ protected void doParse(final Element element,
Element blacklistElm = SpringUtil.getChildElement(element,
FtpServerNamespaceHandler.FTPSERVER_NS, "blacklist");
- if (blacklistElm != null
- && StringUtils.hasText(blacklistElm.getTextContent())) {
- String[] blocks = blacklistElm.getTextContent().split("[\\s,]+");
- List subnets = new ArrayList();
-
- for (String block : blocks) {
- subnets.add(parseSubnet(block));
- }
-
- factoryBuilder.addPropertyValue("blockedSubnets", subnets);
+ if (blacklistElm != null) {
+ LOG.warn("Element 'blacklist' is deprecated, and may be removed in a future release. Please use 'ip-filter' instead. ");
+ try {
+ DefaultIpFilter ipFilter = new DefaultIpFilter(IpFilterType.DENY, blacklistElm.getTextContent());
+ factoryBuilder.addPropertyValue("ipFilter", ipFilter);
+ }
+ catch (UnknownHostException e) {
+ throw new IllegalArgumentException("Invalid IP address or subnet in the 'blacklist' element", e);
+ }
+ }
+
+ Element ipFilterElement = SpringUtil.getChildElement(element, FtpServerNamespaceHandler.FTPSERVER_NS, "ip-filter");
+ if(ipFilterElement != null) {
+ if(blacklistElm != null) {
+ throw new FtpServerConfigurationException("Element 'ipFilter' may not be used when 'blacklist' element is specified. ");
+ }
+ String filterType = ipFilterElement.getAttribute("type");
+ try {
+ DefaultIpFilter ipFilter = new DefaultIpFilter(IpFilterType.parse(filterType), ipFilterElement.getTextContent());
+ factoryBuilder.addPropertyValue("ipFilter", ipFilter);
+ }
+ catch (UnknownHostException e) {
+ throw new IllegalArgumentException("Invalid IP address or subnet in the 'ip-filter' element");
+ }
}
BeanDefinition factoryDefinition = factoryBuilder.getBeanDefinition();
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java b/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java
index c890dddf..ab6cab21 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java
@@ -42,8 +42,7 @@
/**
* Parses the FtpServer "server" element into a Spring bean graph
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class ServerBeanDefinitionParser extends
AbstractSingleBeanDefinitionParser {
@@ -119,6 +118,10 @@ protected void doParse(final Element element,
connectionConfig.setMaxLogins(SpringUtil.parseInt(element,
"max-logins"));
}
+ if (StringUtils.hasText(element.getAttribute("max-threads"))) {
+ connectionConfig.setMaxThreads(SpringUtil.parseInt(element,
+ "max-threads"));
+ }
if (StringUtils.hasText(element.getAttribute("max-anon-logins"))) {
connectionConfig.setMaxAnonymousLogins(SpringUtil.parseInt(element,
"max-anon-logins"));
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/SpringUtil.java b/core/src/main/java/org/apache/ftpserver/config/spring/SpringUtil.java
index 404cd7dc..dbd96b8e 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/SpringUtil.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/SpringUtil.java
@@ -37,8 +37,7 @@
/**
* Various util methods for the Spring config parsing and configuration
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class SpringUtil {
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/UserManagerBeanDefinitionParser.java b/core/src/main/java/org/apache/ftpserver/config/spring/UserManagerBeanDefinitionParser.java
index 99dab8cd..8e56d991 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/UserManagerBeanDefinitionParser.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/UserManagerBeanDefinitionParser.java
@@ -36,8 +36,7 @@
* Parses the FtpServer "file-user-manager" or "db-user-manager" elements into a
* Spring bean graph
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class UserManagerBeanDefinitionParser extends
AbstractSingleBeanDefinitionParser {
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/package.html b/core/src/main/java/org/apache/ftpserver/config/spring/package.html
index e31fac25..ca4f67dc 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/package.html
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/package.html
@@ -14,12 +14,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
-
-
-
+
+
+
+
+
Internal classes, do not use directly!
-
Support classes for Spring based XML configuration
-
-
+
Support classes for Spring based XML configuration
+
+
diff --git a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/NativeFileSystemFactory.java b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/NativeFileSystemFactory.java
index ad7103c6..f15a19de 100644
--- a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/NativeFileSystemFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/NativeFileSystemFactory.java
@@ -32,8 +32,7 @@
/**
* Native file system factory. It uses the OS file system.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class NativeFileSystemFactory implements FileSystemFactory {
diff --git a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NameEqualsFileFilter.java b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NameEqualsFileFilter.java
index 7e4fdaa3..3bacdac2 100644
--- a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NameEqualsFileFilter.java
+++ b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NameEqualsFileFilter.java
@@ -27,8 +27,7 @@
*
* FileFilter used for simple file name matching
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class NameEqualsFileFilter implements FileFilter {
diff --git a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFileSystemView.java b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFileSystemView.java
index 92665281..55da62da 100644
--- a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFileSystemView.java
+++ b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFileSystemView.java
@@ -26,7 +26,6 @@
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpFile;
import org.apache.ftpserver.ftplet.User;
-import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,8 +35,7 @@
* File system view based on native file system. Here the root directory will be
* user virtual root (/).
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class NativeFileSystemView implements FileSystemView {
diff --git a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFtpFile.java b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFtpFile.java
index 400188a4..1f8ddbe7 100644
--- a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFtpFile.java
+++ b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFtpFile.java
@@ -43,13 +43,12 @@
*
* This class wraps native file object.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class NativeFtpFile implements FtpFile {
private final Logger LOG = LoggerFactory.getLogger(NativeFtpFile.class);
-
+
// the file name with respect to the user root.
// The path separator character will be '/' and
// it will always begin with '/'.
@@ -192,7 +191,7 @@ public long getLastModified() {
public boolean setLastModified(long time) {
return file.setLastModified(time);
}
-
+
/**
* Check read permission.
*/
@@ -215,7 +214,7 @@ public boolean isWritable() {
LOG.debug("Checking can write: " + file.canWrite());
return file.canWrite();
}
-
+
LOG.debug("Authorized");
return true;
}
@@ -225,7 +224,6 @@ public boolean isWritable() {
*/
public boolean isRemovable() {
-
// root cannot be deleted
if ("/".equals(fileName)) {
return false;
@@ -235,25 +233,25 @@ public boolean isRemovable() {
* we will check if the parent file has write permission as most systems consider that a file can
* be deleted when their parent directory is writable.
*/
- String fullName=getAbsolutePath();
-
+ String fullName = getAbsolutePath();
+
// we check FTPServer's write permission for this file.
if (user.authorize(new WriteRequest(fullName)) == null) {
return false;
}
// In order to maintain consistency, when possible we delete the last '/' character in the String
- int indexOfSlash=fullName.lastIndexOf('/');
+ int indexOfSlash = fullName.lastIndexOf('/');
String parentFullName;
- if (indexOfSlash==0){
- parentFullName="/";
- }
- else{
- parentFullName=fullName.substring(0,indexOfSlash);
+ if (indexOfSlash == 0) {
+ parentFullName = "/";
+ } else {
+ parentFullName = fullName.substring(0, indexOfSlash);
}
-
+
// we check if the parent FileObject is writable.
- NativeFtpFile parentObject=new NativeFtpFile(parentFullName,file.getAbsoluteFile().getParentFile(),user);
- return parentObject.isWritable();
+ NativeFtpFile parentObject = new NativeFtpFile(parentFullName, file
+ .getAbsoluteFile().getParentFile(), user);
+ return parentObject.isWritable();
}
/**
@@ -364,6 +362,7 @@ public OutputStream createOutputStream(final long offset)
// The IBM jre needs to have both the stream and the random access file
// objects closed to actually close the file
return new FileOutputStream(raf.getFD()) {
+ @Override
public void close() throws IOException {
super.close();
raf.close();
@@ -388,6 +387,7 @@ public InputStream createInputStream(final long offset) throws IOException {
// The IBM jre needs to have both the stream and the random access file
// objects closed to actually close the file
return new FileInputStream(raf.getFD()) {
+ @Override
public void close() throws IOException {
super.close();
raf.close();
@@ -496,7 +496,7 @@ public final static String getPhysicalName(final String rootDir,
File[] matches = new File(resArg)
.listFiles(new NameEqualsFileFilter(tok, true));
- if (matches.length > 0) {
+ if (matches != null && matches.length > 0) {
tok = matches[0].getName();
}
}
@@ -517,12 +517,36 @@ public final static String getPhysicalName(final String rootDir,
return resArg;
}
-
+
+ /**
+ * Implements equals by comparing getCanonicalPath() for the underlying file instabnce.
+ * Ignores the fileName and User fields
+ */
@Override
public boolean equals(Object obj) {
- if(obj != null && obj instanceof NativeFtpFile) {
- return this.file.equals(((NativeFtpFile) obj).file);
- }
- return false;
+ if (obj instanceof NativeFtpFile) {
+ String thisCanonicalPath;
+ String otherCanonicalPath;
+ try {
+ thisCanonicalPath = this.file.getCanonicalPath();
+ otherCanonicalPath = ((NativeFtpFile) obj).file
+ .getCanonicalPath();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to get the canonical path", e);
+ }
+
+ return thisCanonicalPath.equals(otherCanonicalPath);
+ }
+ return false;
}
+
+
+ @Override
+ public int hashCode() {
+ try {
+ return file.getCanonicalPath().hashCode();
+ } catch (IOException e) {
+ return 0;
+ }
+ }
}
diff --git a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/package.html b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/package.html
index a9cc7085..e1d20c09 100644
--- a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/package.html
+++ b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/package.html
@@ -14,12 +14,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
-
-
-
+
+
+
+
+
Internal classes, do not use directly!
-
Native file system implementation
-
-
+
Native file system implementation
+
+
diff --git a/core/src/main/java/org/apache/ftpserver/ftpletcontainer/FtpletContainer.java b/core/src/main/java/org/apache/ftpserver/ftpletcontainer/FtpletContainer.java
index 14c3b049..fb84971f 100644
--- a/core/src/main/java/org/apache/ftpserver/ftpletcontainer/FtpletContainer.java
+++ b/core/src/main/java/org/apache/ftpserver/ftpletcontainer/FtpletContainer.java
@@ -28,8 +28,7 @@
* {@link Ftplet} interface and forward any events to the Ftplets hosted by the
* container.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public interface FtpletContainer extends Ftplet {
diff --git a/core/src/main/java/org/apache/ftpserver/ftpletcontainer/impl/DefaultFtpletContainer.java b/core/src/main/java/org/apache/ftpserver/ftpletcontainer/impl/DefaultFtpletContainer.java
index 1dcc38dc..7d85fa3d 100644
--- a/core/src/main/java/org/apache/ftpserver/ftpletcontainer/impl/DefaultFtpletContainer.java
+++ b/core/src/main/java/org/apache/ftpserver/ftpletcontainer/impl/DefaultFtpletContainer.java
@@ -42,8 +42,7 @@
*
* Internal class, do not use directly.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DefaultFtpletContainer implements FtpletContainer {
diff --git a/core/src/main/java/org/apache/ftpserver/ftpletcontainer/impl/package.html b/core/src/main/java/org/apache/ftpserver/ftpletcontainer/impl/package.html
index af5f8f7a..baac85c3 100644
--- a/core/src/main/java/org/apache/ftpserver/ftpletcontainer/impl/package.html
+++ b/core/src/main/java/org/apache/ftpserver/ftpletcontainer/impl/package.html
@@ -14,12 +14,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
-
-
-
+
+
+
+
+
Internal classes, do not use directly!
-
Ftplet container implementation
-
-
+
Ftplet container implementation
+
+
diff --git a/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java b/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java
index f29e92c2..a5650f6d 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java
@@ -25,9 +25,7 @@
/**
* Internal class, do not use directly.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
- *
+ * @author Apache MINA Project *
*/
public class DefaultConnectionConfig implements ConnectionConfig {
@@ -40,18 +38,21 @@ public class DefaultConnectionConfig implements ConnectionConfig {
private int maxLoginFailures = 3;
private int loginFailureDelay = 500;
+
+ private int maxThreads = 0;
/**
* Internal constructor, do not use directly. Use {@link ConnectionConfigFactory} instead
*/
public DefaultConnectionConfig(boolean anonymousLoginEnabled,
int loginFailureDelay, int maxLogins, int maxAnonymousLogins,
- int maxLoginFailures) {
+ int maxLoginFailures, int maxThreads) {
this.anonymousLoginEnabled = anonymousLoginEnabled;
this.loginFailureDelay = loginFailureDelay;
this.maxLogins = maxLogins;
this.maxAnonymousLogins = maxAnonymousLogins;
this.maxLoginFailures = maxLoginFailures;
+ this.maxThreads = maxThreads;
}
public int getLoginFailureDelay() {
@@ -73,5 +74,9 @@ public int getMaxLogins() {
public boolean isAnonymousLoginEnabled() {
return anonymousLoginEnabled;
}
-
+
+ public int getMaxThreads() {
+ return maxThreads;
+ }
+
}
diff --git a/core/src/main/java/org/apache/ftpserver/impl/DefaultDataConnectionConfiguration.java b/core/src/main/java/org/apache/ftpserver/impl/DefaultDataConnectionConfiguration.java
index 628665dc..ae1a94ec 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultDataConnectionConfiguration.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultDataConnectionConfiguration.java
@@ -28,8 +28,7 @@
*
* Data connection configuration.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DefaultDataConnectionConfiguration implements
DataConnectionConfiguration {
@@ -123,25 +122,7 @@ public String getPassiveExernalAddress() {
* port will be used.
*/
public synchronized int requestPassivePort() {
- int dataPort = -1;
- int loopTimes = 2;
- Thread currThread = Thread.currentThread();
-
- while ((dataPort == -1) && (--loopTimes >= 0)
- && (!currThread.isInterrupted())) {
-
- // search for a free port
- dataPort = passivePorts.reserveNextPort();
-
- // no available free port - wait for the release notification
- if (dataPort == -1) {
- try {
- wait();
- } catch (InterruptedException ex) {
- }
- }
- }
- return dataPort;
+ return passivePorts.reserveNextPort();
}
/**
@@ -158,8 +139,6 @@ public String getPassivePorts() {
*/
public synchronized void releasePassivePort(final int port) {
passivePorts.releasePort(port);
-
- notify();
}
/**
diff --git a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
index f5918574..bd66ab2d 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
@@ -20,9 +20,11 @@
package org.apache.ftpserver.impl;
import java.io.IOException;
+import java.nio.charset.MalformedInputException;
import org.apache.ftpserver.command.Command;
import org.apache.ftpserver.command.CommandFactory;
+import org.apache.ftpserver.ftplet.DefaultFtpReply;
import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpRequest;
@@ -31,15 +33,14 @@
import org.apache.ftpserver.listener.Listener;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.write.WriteToClosedSessionException;
+import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Internal class, do not use directly.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
- *
+ * @author Apache MINA Project *
*/
public class DefaultFtpHandler implements FtpHandler {
@@ -69,15 +70,28 @@ public void sessionCreated(final FtpIoSession session) throws Exception {
}
public void sessionOpened(final FtpIoSession session) throws Exception {
- context.getFtpletContainer().onConnect(session.getFtpletSession());
+ FtpletContainer ftplets = context.getFtpletContainer();
- session.updateLastAccessTime();
-
- session.write(LocalizedFtpReply.translate(session, null, context,
- FtpReply.REPLY_220_SERVICE_READY, null, null));
+ FtpletResult ftpletRet;
+ try {
+ ftpletRet = ftplets.onConnect(session.getFtpletSession());
+ } catch (Exception e) {
+ LOG.debug("Ftplet threw exception", e);
+ ftpletRet = FtpletResult.DISCONNECT;
+ }
+ if (ftpletRet == FtpletResult.DISCONNECT) {
+ LOG.debug("Ftplet returned DISCONNECT, session will be closed");
+ session.close(false).awaitUninterruptibly(10000);
+ } else {
+ session.updateLastAccessTime();
+
+ session.write(LocalizedFtpReply.translate(session, null, context,
+ FtpReply.REPLY_220_SERVICE_READY, null, null));
+ }
}
public void sessionClosed(final FtpIoSession session) throws Exception {
+ LOG.debug("Closing session");
try {
context.getFtpletContainer().onDisconnect(
session.getFtpletSession());
@@ -85,6 +99,17 @@ public void sessionClosed(final FtpIoSession session) throws Exception {
// swallow the exception, we're closing down the session anyways
LOG.warn("Ftplet threw an exception on disconnect", e);
}
+
+ // make sure we close the data connection if it happens to be open
+ try {
+ ServerDataConnectionFactory dc = session.getDataConnection();
+ if(dc != null) {
+ dc.closeDataConnection();
+ }
+ } catch (Exception e) {
+ // swallow the exception, we're closing down the session anyways
+ LOG.warn("Data connection threw an exception on disconnect", e);
+ }
FileSystemView fs = session.getFileSystemView();
if(fs != null) {
@@ -101,23 +126,38 @@ public void sessionClosed(final FtpIoSession session) throws Exception {
if (stats != null) {
stats.setLogout(session);
stats.setCloseConnection(session);
+ LOG.debug("Statistics login and connection count decreased due to session close");
+ } else {
+ LOG.warn("Statistics not available in session, can not decrease login and connection count");
}
+ LOG.debug("Session closed");
}
public void exceptionCaught(final FtpIoSession session,
final Throwable cause) throws Exception {
- if (cause instanceof WriteToClosedSessionException) {
+
+ if(cause instanceof ProtocolDecoderException &&
+ cause.getCause() instanceof MalformedInputException) {
+ // client probably sent something which is not UTF-8 and we failed to
+ // decode it
+
+ LOG.warn(
+ "Client sent command that could not be decoded: {}",
+ ((ProtocolDecoderException)cause).getHexdump());
+ session.write(new DefaultFtpReply(FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "Invalid character in command"));
+ } else if (cause instanceof WriteToClosedSessionException) {
WriteToClosedSessionException writeToClosedSessionException =
(WriteToClosedSessionException) cause;
LOG.warn(
"Client closed connection before all replies could be sent, last reply was {}",
writeToClosedSessionException.getRequest());
-
+ session.close(false).awaitUninterruptibly(10000);
} else {
LOG.error("Exception caught, closing session", cause);
+ session.close(false).awaitUninterruptibly(10000);
}
- session.close(false).awaitUninterruptibly(10000);
+
}
private boolean isCommandOkWithoutAuthentication(String command) {
@@ -160,6 +200,7 @@ public void messageReceived(final FtpIoSession session,
ftpletRet = FtpletResult.DISCONNECT;
}
if (ftpletRet == FtpletResult.DISCONNECT) {
+ LOG.debug("Ftplet returned DISCONNECT, session will be closed");
session.close(false).awaitUninterruptibly(10000);
return;
} else if (ftpletRet != FtpletResult.SKIP) {
@@ -184,6 +225,8 @@ public void messageReceived(final FtpIoSession session,
ftpletRet = FtpletResult.DISCONNECT;
}
if (ftpletRet == FtpletResult.DISCONNECT) {
+ LOG.debug("Ftplet returned DISCONNECT, session will be closed");
+
session.close(false).awaitUninterruptibly(10000);
return;
}
diff --git a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpRequest.java b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpRequest.java
index 10fbafc9..548e3ad2 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpRequest.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpRequest.java
@@ -26,8 +26,7 @@
*
* FTP request object.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DefaultFtpRequest implements FtpRequest {
diff --git a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java
index bf509c07..680bd19a 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java
@@ -43,8 +43,7 @@
* thread. Server implementation is used to create the server
* socket and handle client connection.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DefaultFtpServer implements FtpServer {
@@ -68,6 +67,10 @@ public DefaultFtpServer(final FtpServerContext serverContext) {
* @throws FtpException
*/
public void start() throws FtpException {
+ if (serverContext == null) {
+ // we have already been stopped, can not be restarted
+ throw new IllegalStateException("FtpServer has been stopped. Restart is not supported");
+ }
List startedListeners = new ArrayList();
@@ -100,7 +103,8 @@ public void start() throws FtpException {
}
/**
- * Stop the server. Stop the listener thread.
+ * Stop the server. Stopping the server will close completely and
+ * it not supported to restart using {@link #start()}.
*/
public void stop() {
if (serverContext == null) {
diff --git a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java
index 8417ea03..731b0f58 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java
@@ -21,9 +21,10 @@
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import org.apache.ftpserver.ConnectionConfig;
import org.apache.ftpserver.ConnectionConfigFactory;
@@ -46,6 +47,7 @@
import org.apache.ftpserver.usermanager.impl.ConcurrentLoginPermission;
import org.apache.ftpserver.usermanager.impl.TransferRatePermission;
import org.apache.ftpserver.usermanager.impl.WritePermission;
+import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,8 +56,7 @@
*
* FTP server configuration implementation. It holds all the components used.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DefaultFtpServerContext implements FtpServerContext {
@@ -80,6 +81,12 @@ public class DefaultFtpServerContext implements FtpServerContext {
private static final List ADMIN_AUTHORITIES = new ArrayList();
private static final List ANON_AUTHORITIES = new ArrayList();
+
+ /**
+ * The thread pool executor to be used by the server using this context
+ */
+ private ThreadPoolExecutor threadPoolExecutor = null;
+
static {
ADMIN_AUTHORITIES.add(new WritePermission());
@@ -191,6 +198,16 @@ public Ftplet getFtplet(String name) {
public void dispose() {
listeners.clear();
ftpletContainer.getFtplets().clear();
+ if (threadPoolExecutor != null) {
+ LOG.debug("Shutting down the thread pool executor");
+ threadPoolExecutor.shutdown();
+ try {
+ threadPoolExecutor.awaitTermination(5000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ } finally {
+ // TODO: how to handle?
+ }
+ }
}
public Listener getListener(String name) {
@@ -244,4 +261,22 @@ public ConnectionConfig getConnectionConfig() {
public void setConnectionConfig(ConnectionConfig connectionConfig) {
this.connectionConfig = connectionConfig;
}
+
+ public synchronized ThreadPoolExecutor getThreadPoolExecutor() {
+ if(threadPoolExecutor == null) {
+ int maxThreads = connectionConfig.getMaxThreads();
+ if(maxThreads < 1) {
+ int maxLogins = connectionConfig.getMaxLogins();
+ if(maxLogins > 0) {
+ maxThreads = maxLogins;
+ }
+ else {
+ maxThreads = 16;
+ }
+ }
+ LOG.debug("Intializing shared thread pool executor with max threads of {}", maxThreads);
+ threadPoolExecutor = new OrderedThreadPoolExecutor(maxThreads);
+ }
+ return threadPoolExecutor;
+ }
}
diff --git a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java
index 822486ec..cefad774 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java
@@ -39,8 +39,7 @@
*
* FTP session
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DefaultFtpSession implements FtpSession {
diff --git a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpStatistics.java b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpStatistics.java
index 4e41227c..e8228e5a 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpStatistics.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpStatistics.java
@@ -38,8 +38,7 @@
* TODO revisit concurrency, right now we're a bit over zealous with both Atomic*
* counters and synchronization
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public class DefaultFtpStatistics implements ServerFtpStatistics {
diff --git a/core/src/main/java/org/apache/ftpserver/impl/FileObserver.java b/core/src/main/java/org/apache/ftpserver/impl/FileObserver.java
index 178dcd44..9eba476b 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/FileObserver.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/FileObserver.java
@@ -26,8 +26,7 @@
*
* This is the file related activity observer.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
+ * @author Apache MINA Project
*/
public interface FileObserver {
diff --git a/core/src/main/java/org/apache/ftpserver/impl/FtpHandler.java b/core/src/main/java/org/apache/ftpserver/impl/FtpHandler.java
index ac1a731f..69e1c2e7 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/FtpHandler.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/FtpHandler.java
@@ -31,9 +31,7 @@
/**
* Internal class, do not use directly.
*
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
- *
+ * @author Apache MINA Project *
*/
public interface FtpHandler {
diff --git a/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java b/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java
index abe0d7bc..9f79c3ae 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java
@@ -51,801 +51,829 @@
import org.apache.mina.core.write.WriteRequest;
import org.apache.mina.core.write.WriteRequestQueue;
import org.apache.mina.filter.ssl.SslFilter;
+import org.slf4j.LoggerFactory;
/**
* Internal class, do not use directly.
- *
- * @author The Apache MINA Project (dev@mina.apache.org)
- * @version $Rev$, $Date$
- *
+ *
+ * @author Apache MINA Project *
*/
public class FtpIoSession implements IoSession {
- /**
- * Contains user name between USER and PASS commands
- */
- public static final String ATTRIBUTE_PREFIX = "org.apache.ftpserver.";
+ /**
+ * Contains user name between USER and PASS commands
+ */
+ public static final String ATTRIBUTE_PREFIX = "org.apache.ftpserver.";
+
+ private static final String ATTRIBUTE_USER_ARGUMENT = ATTRIBUTE_PREFIX
+ + "user-argument";
+
+ private static final String ATTRIBUTE_SESSION_ID = ATTRIBUTE_PREFIX
+ + "session-id";
+
+ private static final String ATTRIBUTE_USER = ATTRIBUTE_PREFIX + "user";
- private static final String ATTRIBUTE_USER_ARGUMENT = ATTRIBUTE_PREFIX
- + "user-argument";
+ private static final String ATTRIBUTE_LANGUAGE = ATTRIBUTE_PREFIX
+ + "language";
- private static final String ATTRIBUTE_SESSION_ID = ATTRIBUTE_PREFIX
- + "session-id";
-
- private static final String ATTRIBUTE_USER = ATTRIBUTE_PREFIX + "user";
+ private static final String ATTRIBUTE_LOGIN_TIME = ATTRIBUTE_PREFIX
+ + "login-time";
+
+ private static final String ATTRIBUTE_DATA_CONNECTION = ATTRIBUTE_PREFIX
+ + "data-connection";
- private static final String ATTRIBUTE_LANGUAGE = ATTRIBUTE_PREFIX
- + "language";
-
- private static final String ATTRIBUTE_LOGIN_TIME = ATTRIBUTE_PREFIX
- + "login-time";
-
- private static final String ATTRIBUTE_DATA_CONNECTION = ATTRIBUTE_PREFIX
- + "data-connection";
-
- private static final String ATTRIBUTE_FILE_SYSTEM = ATTRIBUTE_PREFIX
- + "file-system";
-
- private static final String ATTRIBUTE_RENAME_FROM = ATTRIBUTE_PREFIX
- + "rename-from";
-
- private static final String ATTRIBUTE_FILE_OFFSET = ATTRIBUTE_PREFIX
- + "file-offset";
-
- private static final String ATTRIBUTE_DATA_TYPE = ATTRIBUTE_PREFIX
- + "data-type";
-
- private static final String ATTRIBUTE_STRUCTURE = ATTRIBUTE_PREFIX
- + "structure";
-
- private static final String ATTRIBUTE_FAILED_LOGINS = ATTRIBUTE_PREFIX
- + "failed-logins";
-
- private static final String ATTRIBUTE_LISTENER = ATTRIBUTE_PREFIX
- + "listener";
-
- private static final String ATTRIBUTE_MAX_IDLE_TIME = ATTRIBUTE_PREFIX
- + "max-idle-time";
-
- private static final String ATTRIBUTE_LAST_ACCESS_TIME = ATTRIBUTE_PREFIX
- + "last-access-time";
-
- private static final String ATTRIBUTE_CACHED_REMOTE_ADDRESS = ATTRIBUTE_PREFIX
- + "cached-remote-address";
-
- private IoSession wrappedSession;
-
- private FtpServerContext context;
-
- /**
- * Last reply that was sent to the client, if any.
- */
- private FtpReply lastReply = null;
-
- /* Begin wrapped IoSession methods */
-
- /**
- * @see IoSession#close()
- */
- public CloseFuture close() {
- return wrappedSession.close();
- }
-
- /**
- * @see IoSession#close(boolean)
- */
- public CloseFuture close(boolean immediately) {
- return wrappedSession.close(immediately);
- }
-
- /**
- * @see IoSession#containsAttribute(Object)
- */
- public boolean containsAttribute(Object key) {
- return wrappedSession.containsAttribute(key);
- }
-
- /**
- * @see IoSession#getAttachment()
- */
- @SuppressWarnings("deprecation")
- public Object getAttachment() {
- return wrappedSession.getAttachment();
- }
-
- /**
- * @see IoSession#getAttribute(Object)
- */
- public Object getAttribute(Object key) {
- return wrappedSession.getAttribute(key);
- }
-
- /**
- * @see IoSession#getAttribute(Object, Object)
- */
- public Object getAttribute(Object key, Object defaultValue) {
- return wrappedSession.getAttribute(key, defaultValue);
- }
-
- /**
- * @see IoSession#getAttributeKeys()
- */
- public Set