/*
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.ftp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.StringTokenizer;
/**
* @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
public abstract class BaseFtpTest extends BaseStandaloneTest
{
protected Socket commandConn;
protected String user = "root";
protected String password = "exo";
protected String host = "localhost";
protected int port = 2122;
protected BufferedReader inputCommand;
protected BufferedWriter outputCommand;
public void setUp() throws Exception
{
super.setUp();
root.addNode("ftp-root", "nt:folder");
session.save();
}
protected void connect() throws IOException
{
commandConn = new Socket(host, port);
inputCommand = new BufferedReader(new InputStreamReader(commandConn.getInputStream()));
outputCommand = new BufferedWriter(new OutputStreamWriter(commandConn.getOutputStream()));
String response = readResponse();
assertTrue(response.startsWith(FtpConst.EXO_LOGO[0]));
sendCommand(FtpConst.Commands.CMD_USER + ' ' + user);
response = readResponse();
assertTrue(response.startsWith("331 "));
sendCommand(FtpConst.Commands.CMD_PASS + ' ' + password);
response = readResponse();
assertTrue(response.startsWith("230 "));
}
protected void disconnect() throws IOException
{
try
{
sendCommand(FtpConst.Commands.CMD_QUIT);
}
finally
{
inputCommand.close();
outputCommand.close();
commandConn.close();
}
}
protected String pwd() throws IOException
{
sendCommand(FtpConst.Commands.CMD_PWD);
String response = readResponse();
assertTrue(response.startsWith("257 "));
int q1 = response.indexOf('"');
int q2 = response.indexOf('"', q1 + 1);
return response.substring(q1 + 1, q2);
}
protected void cwd(String dir) throws IOException
{
sendCommand(FtpConst.Commands.CMD_CWD + ' ' + dir);
String response = readResponse();
assertTrue(response.startsWith("250 "));
}
protected void stor(byte[] data, String filename) throws IOException
{
String response = pasv();
int begin = response.indexOf('(');
int end = response.indexOf(')', begin + 1);
String address = response.substring(begin + 1, end);
StringTokenizer tokens = new StringTokenizer(address, ",");
String _host =
tokens.nextToken() + "." + tokens.nextToken() + "." + tokens.nextToken() + "." + tokens.nextToken();
int _port = Integer.parseInt(tokens.nextToken()) * 256 + Integer.parseInt(tokens.nextToken());
sendCommand(FtpConst.Commands.CMD_STOR + ' ' + filename);
Socket dataConn = new Socket(_host, _port);
response = readResponse();
assertTrue(response.startsWith("125 "));
OutputStream output = null;
try
{
output = dataConn.getOutputStream();
output.write(data);
output.flush();
}
finally
{
if (outputCommand != null)
{
output.close();
}
}
response = readResponse();
dataConn.close();
assertTrue(response.startsWith("226 "));
}
protected void bin() throws IOException
{
type('I');
}
protected void ascii() throws IOException
{
type('A');
}
protected void type(char type) throws IOException
{
// I - bin, A - ASCII
sendCommand(FtpConst.Commands.CMD_TYPE + ' ' + type);
String response = readResponse();
assertTrue(response.startsWith("200 "));
}
protected String pasv() throws IOException
{
sendCommand(FtpConst.Commands.CMD_PASV);
String response = readResponse();
assertTrue(response.startsWith("227 "));
return response;
}
protected byte[] retr(String filename) throws IOException
{
String response = pasv();
int begin = response.indexOf('(');
int end = response.indexOf(')', begin + 1);
String address = response.substring(begin + 1, end);
StringTokenizer tokens = new StringTokenizer(address, ",");
String _host =
tokens.nextToken() + "." + tokens.nextToken() + "." + tokens.nextToken() + "." + tokens.nextToken();
int _port = Integer.parseInt(tokens.nextToken()) * 256 + Integer.parseInt(tokens.nextToken());
sendCommand(FtpConst.Commands.CMD_RETR + ' ' + filename);
Socket dataConn = new Socket(_host, _port);
response = readResponse();
assertTrue(response.startsWith("125 "));
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
InputStream input = null;;
try
{
input = dataConn.getInputStream();
int bytes = -1;
while ((bytes = input.read(buff)) != -1)
output.write(buff, 0, bytes);
}
finally
{
if (input != null)
{
input.close();
}
}
response = readResponse();
dataConn.close();
assertTrue(response.startsWith("226 "));
return output.toByteArray();
}
protected void sendCommand(String command) throws IOException
{
try
{
outputCommand.write(command + "\r\n");
outputCommand.flush();
}
catch (IOException e)
{
disconnect();
throw e;
}
}
protected String readResponse() throws IOException
{
StringBuffer buff = new StringBuffer();
String line = inputCommand.readLine();
assertTrue(line.length() >= 3);
buff.append(line);
if (line.length() > 3 && line.charAt(3) == '-')
{
do
{
buff.append('\n');
buff.append(line);
}
while (!isLastLine(line = inputCommand.readLine()));
}
String response = buff.toString();
return response;
}
private static boolean isLastLine(String line)
{
return Character.isDigit(line.charAt(0)) && Character.isDigit(line.charAt(1))
&& Character.isDigit(line.charAt(2)) && line.charAt(3) == ' ';
}
}