You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ng...@apache.org on 2008/10/18 22:37:55 UTC
svn commit: r705921 - in /mina/ftpserver/trunk/core/src:
main/java/org/apache/ftpserver/impl/DefaultFtpServer.java
main/java/org/apache/ftpserver/listener/nio/NioListener.java
test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java
Author: ngn
Date: Sat Oct 18 13:37:55 2008
New Revision: 705921
URL: http://svn.apache.org/viewvc?rev=705921&view=rev
Log:
Fix for bug where already started listeners would not be stopped if FtpServer.start() fails later (FTPSERVER-197)
Added:
mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java
Modified:
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java?rev=705921&r1=705920&r2=705921&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServer.java Sat Oct 18 13:37:55 2008
@@ -19,6 +19,8 @@
package org.apache.ftpserver.impl;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import org.apache.ftpserver.ConnectionConfig;
@@ -26,6 +28,7 @@
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.command.CommandFactory;
import org.apache.ftpserver.ftplet.FileSystemFactory;
+import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.Listener;
@@ -60,28 +63,45 @@
/**
* Start the server. Open a new listener thread.
+ * @throws FtpException
*/
- public void start() throws Exception {
+ public void start() throws FtpException {
- Map<String, Listener> listeners = serverContext.getListeners();
- for (Listener listener : listeners.values()) {
- listener.start(serverContext);
- }
-
- // init the Ftplet container
- serverContext.getFtpletContainer().init(serverContext);
+ List<Listener> startedListeners = new ArrayList<Listener>();
- started = true;
-
- LOG.info("FTP server started");
+ try {
+ Map<String, Listener> listeners = serverContext.getListeners();
+ for (Listener listener : listeners.values()) {
+ listener.start(serverContext);
+ startedListeners.add(listener);
+ }
+
+ // init the Ftplet container
+ serverContext.getFtpletContainer().init(serverContext);
+
+ started = true;
+ LOG.info("FTP server started");
+ } catch(Exception e) {
+ // must close listeners that we were able to start
+ for(Listener listener : startedListeners) {
+ listener.stop();
+ }
+
+ if(e instanceof FtpException) {
+ throw (FtpException)e;
+ } else {
+ throw (RuntimeException)e;
+ }
+
+ }
}
/**
* Stop the server. Stop the listener thread.
*/
public void stop() {
- if (!started || serverContext == null) {
+ if (serverContext == null) {
// we have already been stopped, ignore
return;
}
Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java?rev=705921&r1=705920&r2=705921&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java Sat Oct 18 13:37:55 2008
@@ -22,6 +22,7 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -31,6 +32,7 @@
import java.util.concurrent.TimeUnit;
import org.apache.ftpserver.DataConnectionConfiguration;
+import org.apache.ftpserver.FtpServerConfigurationException;
import org.apache.ftpserver.impl.DefaultFtpHandler;
import org.apache.ftpserver.impl.FtpHandler;
import org.apache.ftpserver.impl.FtpIoSession;
@@ -112,65 +114,82 @@
/**
* @see Listener#start(FtpServerContext)
*/
- public synchronized void start(FtpServerContext context) throws Exception {
- this.context = context;
-
- acceptor = new NioSocketAcceptor(Runtime.getRuntime()
- .availableProcessors());
-
- if (getServerAddress() != null) {
- address = new InetSocketAddress(getServerAddress(), getPort());
- } else {
- address = new InetSocketAddress(getPort());
- }
-
- acceptor.setReuseAddress(true);
- acceptor.getSessionConfig().setReadBufferSize(2048);
- acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
- getIdleTimeout());
- // Decrease the default receiver buffer size
- ((SocketSessionConfig) acceptor.getSessionConfig())
- .setReceiveBufferSize(512);
-
- MdcInjectionFilter mdcFilter = new MdcInjectionFilter();
-
- acceptor.getFilterChain().addLast("mdcFilter", mdcFilter);
-
- // add and update the blacklist filter
- acceptor.getFilterChain().addLast("ipFilter", new BlacklistFilter());
- updateBlacklistFilter();
-
- acceptor.getFilterChain().addLast("threadPool",
- new ExecutorFilter(filterExecutor));
- acceptor.getFilterChain().addLast("codec",
- new ProtocolCodecFilter(new FtpServerProtocolCodecFactory()));
- acceptor.getFilterChain().addLast("mdcFilter2", mdcFilter);
- acceptor.getFilterChain().addLast("logger", new FtpLoggingFilter());
-
- if (isImplicitSsl()) {
- SslConfiguration ssl = getSslConfiguration();
- SslFilter sslFilter = new SslFilter(ssl.getSSLContext());
-
- if (ssl.getClientAuth() == ClientAuth.NEED) {
- sslFilter.setNeedClientAuth(true);
- } else if (ssl.getClientAuth() == ClientAuth.WANT) {
- sslFilter.setWantClientAuth(true);
+ public synchronized void start(FtpServerContext context) {
+ try {
+
+ this.context = context;
+
+ acceptor = new NioSocketAcceptor(Runtime.getRuntime()
+ .availableProcessors());
+
+ if (getServerAddress() != null) {
+ address = new InetSocketAddress(getServerAddress(), getPort());
+ } else {
+ address = new InetSocketAddress(getPort());
}
-
- if (ssl.getEnabledCipherSuites() != null) {
- sslFilter.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+
+ acceptor.setReuseAddress(true);
+ acceptor.getSessionConfig().setReadBufferSize(2048);
+ acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
+ getIdleTimeout());
+ // Decrease the default receiver buffer size
+ ((SocketSessionConfig) acceptor.getSessionConfig())
+ .setReceiveBufferSize(512);
+
+ MdcInjectionFilter mdcFilter = new MdcInjectionFilter();
+
+ acceptor.getFilterChain().addLast("mdcFilter", mdcFilter);
+
+ // add and update the blacklist filter
+ acceptor.getFilterChain().addLast("ipFilter", new BlacklistFilter());
+ updateBlacklistFilter();
+
+ acceptor.getFilterChain().addLast("threadPool",
+ new ExecutorFilter(filterExecutor));
+ acceptor.getFilterChain().addLast("codec",
+ new ProtocolCodecFilter(new FtpServerProtocolCodecFactory()));
+ acceptor.getFilterChain().addLast("mdcFilter2", mdcFilter);
+ acceptor.getFilterChain().addLast("logger", new FtpLoggingFilter());
+
+ if (isImplicitSsl()) {
+ SslConfiguration ssl = getSslConfiguration();
+ SslFilter sslFilter;
+ try {
+ sslFilter = new SslFilter(ssl.getSSLContext());
+ } catch (GeneralSecurityException e) {
+ throw new FtpServerConfigurationException("SSL could not be initialized, check configuration");
+ }
+
+ if (ssl.getClientAuth() == ClientAuth.NEED) {
+ sslFilter.setNeedClientAuth(true);
+ } else if (ssl.getClientAuth() == ClientAuth.WANT) {
+ sslFilter.setWantClientAuth(true);
+ }
+
+ if (ssl.getEnabledCipherSuites() != null) {
+ sslFilter.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+ }
+
+ acceptor.getFilterChain().addFirst("sslFilter", sslFilter);
}
-
- acceptor.getFilterChain().addFirst("sslFilter", sslFilter);
+
+ handler.init(context, this);
+ acceptor.setHandler(new FtpHandlerAdapter(context, handler));
+
+ try {
+ acceptor.bind(address);
+ } catch (IOException e) {
+ throw new FtpServerConfigurationException("Failed to bind to address " + address + ", check configuration", e);
+ }
+
+ // update the port to the real port bound by the listener
+ setPort(acceptor.getLocalAddress().getPort());
+ } catch(RuntimeException e) {
+ // clean up if we fail to start
+ stop();
+
+ throw e;
}
-
- handler.init(context, this);
- acceptor.setHandler(new FtpHandlerAdapter(context, handler));
-
- acceptor.bind(address);
-
- // update the port to the real port bound by the listener
- setPort(acceptor.getLocalAddress().getPort());
}
/**
@@ -193,6 +212,8 @@
// TODO: how to handle?
}
}
+
+ context = null;
}
/**
Added: mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java?rev=705921&view=auto
==============================================================================
--- mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java (added)
+++ mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java Sat Oct 18 13:37:55 2008
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ftpserver.impl;
+
+import java.io.IOException;
+import java.net.BindException;
+
+import org.apache.ftpserver.FtpServer;
+import org.apache.ftpserver.FtpServerConfigurationException;
+import org.apache.ftpserver.FtpServerFactory;
+import org.apache.ftpserver.listener.Listener;
+import org.apache.ftpserver.listener.ListenerFactory;
+import org.apache.ftpserver.test.TestUtil;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ *
+ */
+public class DefaultFtpServerTest extends TestCase {
+
+ public void testFailStartingSecondListener() throws Exception {
+ // FTPSERVER-197
+
+ FtpServerFactory serverFactory = new FtpServerFactory();
+
+ ListenerFactory listenerFactory = new ListenerFactory();
+ listenerFactory.setPort(TestUtil.findFreePort());
+
+ // let's create two listeners on the same port, second should not start
+
+ Listener defaultListener = listenerFactory.createListener();
+ Listener secondListener = listenerFactory.createListener();
+
+
+ serverFactory.addListener("default", defaultListener);
+ serverFactory.addListener("second", secondListener);
+
+ FtpServer server = serverFactory.createServer();
+
+ try {
+ server.start();
+ fail("Must throw FtpServerConfigurationException");
+ } catch(FtpServerConfigurationException e) {
+ if(e.getCause() instanceof BindException) {
+ // OK!
+ } else {
+ throw e;
+ }
+ }
+
+ assertTrue(defaultListener.isStopped());
+ assertTrue(secondListener.isStopped());
+ assertTrue(server.isStopped());
+
+
+ }
+
+}