package com.abiquo.appliancemanager.filesystems; import java.io.IOException; import java.io.InputStream; import java.net.URL; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.abiquo.appliancemanager.exceptions.DownloadException; /** * @see http://commons.apache.org/net/apidocs/org/apache/commons/net/ftp/FTPClient.html */ public class FileFTP implements IFileSystem { private final static Logger log = LoggerFactory.getLogger(FileFTP.class); @Override public InputStream open(URL target) throws DownloadException { FTPClient client = new FTPClient(); InputStream isFile; String host = target.getHost(); int port = target.getPort(); if (port == -1) { port = 21; } // log.debug("Open to host "+host+":"+port); // log.debug("Using file "+target.getFile()); try { log.debug("connecting"); client.connect(host, port); log.debug("logining"); // TODO parse user and password from the URL client.login("anonymous", ""); checkConnection(client); client.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);// COMPRESSED_TRANSFER_MODE); client.setFileType(FTP.BINARY_FILE_TYPE); // FTP.ASCII_FILE_TYPE isFile = client.retrieveFileStream(target.getFile()); } catch (IOException e) { if (client.isConnected()) { try { client.disconnect(); } catch (IOException ioe) { // do nothing log.error(" failed to disconect ", e); } } final String msg = "Can not transfer file form " + target.toString(); throw new DownloadException(msg, e); } return new FtpInputStream(client, isFile); } /** * After connection attempt, you should check the reply code to verify success. * * @throws DownloadException if the client reply code is not PositiveCompletion (starting with * 2) */ private void checkConnection(FTPClient client) throws DownloadException { if (!FTPReply.isPositiveCompletion(client.getReplyCode())) { log .debug("Refused connection " + client.getReplyCode() + " " + client.getReplyString()); try { client.disconnect(); log.debug("Disconnected"); } catch (IOException e) { log.error("Error disconnecting a bad FTP connection ", e); } final String msg = "FTP server refused connection, caused by : " + client.getReplyString(); throw new DownloadException(msg); } } /** * Wrap the HTTP response InputStream with its request HttpMethod, to release the connection * when finish stream read. */ class FtpInputStream extends InputStream { FTPClient client; InputStream source; public FtpInputStream(FTPClient c, InputStream s) { client = c; source = s; } public int read() throws IOException { return source.read(); } public void close() throws IOException { if (!client.completePendingCommand()) { log.error("Some pending commands ...."); // TODO check sucess } client.logout(); if (client.isConnected()) { client.disconnect(); System.err.println("FTP CONNECTION RELEASED"); // TODO remove } source.close(); } } }