Path: blob/master/test/jdk/sun/net/www/ftptest/FtpServer.java
41152 views
/*1* Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.net.*;24import java.io.*;25import java.util.ArrayList;2627/**28* This class implements a simple FTP server that can handle multiple29* connections concurrently. This is mostly meant as a test environment.30* You have to provide 2 handlers for it to be effective, one to simulate31* (or access) a filesystem and one to deal with authentication.32* See {@link FtpFileSystemHandler} and {@link FtpAuthHandler}.33*34* Since it is a subclass of Thread, you have to call <code>start()</code>35* To get it running.36*37* Usage example:<p>38*39* <code>40* FtpServer server = new FtpServer(0);41* int port = server.getLocalPort();42* server.setFileSystemHandler(myFSHandler);43* server.setAuthHandler(myAuthHandler);44* server.start();45* </code>46*47*/4849public class FtpServer extends Thread implements AutoCloseable {50private ServerSocket listener = null;51private FtpFileSystemHandler fsh = null;52private FtpAuthHandler auth = null;53private boolean done = false;54private ArrayList<FtpCommandHandler> clients = new ArrayList<FtpCommandHandler>();5556/**57* Creates an instance of an FTP server which will listen for incoming58* connections on the specified port. If the port is set to 0, it will59* automatically select an available ephemeral port.60*/61public FtpServer(InetAddress addr, int port) throws IOException {62listener = new ServerSocket();63listener.bind(new InetSocketAddress(addr, port));64}6566/**67* Creates an instance of an FTP server which will listen for incoming68* connections on the specified port. If the port is set to 0, it will69* automatically select an available ephemeral port.70*/71public FtpServer(int port) throws IOException {72listener = new ServerSocket(port);73}7475/**76* Creates an instance of an FTP server that will listen on the default77* FTP port, usually 21.78*/79public FtpServer() throws IOException {80this(21);81}8283public void setFileSystemHandler(FtpFileSystemHandler f) {84fsh = f;85}8687public void setAuthHandler(FtpAuthHandler a) {88auth = a;89}9091public void terminate() {92done = true;93interrupt();94}9596public void killClients() {97synchronized (clients) {98int c = clients.size();99while (c > 0) {100c--;101FtpCommandHandler cl = clients.get(c);102cl.terminate();103cl.interrupt();104}105}106}107108public int getLocalPort() {109return listener.getLocalPort();110}111112public InetAddress getInetAddress() {113return listener.getInetAddress();114}115116public String getAuthority() {117InetAddress address = getInetAddress();118String hostaddr = address.isAnyLocalAddress()119? "localhost" : address.getHostAddress();120if (hostaddr.indexOf(':') > -1) {121hostaddr = "[" + hostaddr + "]";122}123return hostaddr + ":" + getLocalPort();124}125126127void addClient(Socket client) {128FtpCommandHandler h = new FtpCommandHandler(client, this);129h.setHandlers(fsh, auth);130synchronized (clients) {131clients.add(h);132}133h.start();134}135136void removeClient(FtpCommandHandler cl) {137synchronized (clients) {138clients.remove(cl);139}140}141142public int activeClientsCount() {143synchronized (clients) {144return clients.size();145}146}147148public void run() {149Socket client;150151try {152while (!done) {153client = listener.accept();154addClient(client);155}156listener.close();157} catch (IOException e) {158159}160}161162@Override163public void close() throws Exception {164terminate();165listener.close();166if (activeClientsCount() > 0) {167killClients();168}169}170}171172173