?? baseftpconnection.java
字號:
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package server.ftp;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.InetAddress;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import util.Message;
import io.IoUtils;
import io.StreamConnectorObserver;
/**
* This is a generic ftp connection handler. It delegates
* the request to appropriate methods in subclasses.
*
* @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
*/
public
class BaseFtpConnection implements Runnable, StreamConnectorObserver {
protected final static Class[] METHOD_INPUT_SIG = new Class[] {FtpRequest.class, FtpWriter.class};
protected FtpConfig mConfig = null;
protected FtpStatus mFtpStatus = null;
protected FtpDataConnection mDataConnection = null;
protected FtpUser mUser = null;
protected SpyConnectionInterface mSpy = null;
protected FtpConnectionObserver mObserver = null;
protected Socket mControlSocket = null;
protected FtpWriter mWriter = null;
protected boolean mbStopRequest = false;
/**
* Set configuration file and the control socket.
*/
public BaseFtpConnection(FtpConfig ftpConfig, Socket soc) {
mConfig = ftpConfig;
mFtpStatus = mConfig.getStatus();
mControlSocket = soc;
mUser = new FtpUser();
}
/**
* Server one FTP connection.
*/
public void run() {
InetAddress clientAddress = mControlSocket.getInetAddress();
mConfig.getLogger().info("Handling new request from " + clientAddress.getHostAddress());
mDataConnection = new FtpDataConnection(mConfig);
mUser.setClientAddress(clientAddress);
mConfig.getConnectionService().newConnection(this);
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(mControlSocket.getInputStream()));
mWriter = new FtpWriter(mControlSocket, mConfig);
// permission check
if( !mConfig.getIpRestrictor().hasPermission(mControlSocket.getInetAddress()) ) {
mWriter.write(mFtpStatus.getResponse(530, null, mUser, null));
return;
}
mWriter.write(mFtpStatus.getResponse(220, null, mUser, null));
do {
notifyObserver();
String commandLine = in.readLine();
// test command line
if(commandLine == null) {
break;
}
spyRequest(commandLine);
if(commandLine.equals("")) {
continue;
}
FtpRequest request = new FtpRequest(commandLine);
if(!hasPermission(request)) {
mWriter.write(mFtpStatus.getResponse(530, request, mUser, null));
break;
}
// execute command
service(request, mWriter);
}
while(!mbStopRequest);
}
catch(Exception ex) {
}
finally {
IoUtils.close(in);
IoUtils.close(mWriter);
ConnectionService conService = mConfig.getConnectionService();
if (conService != null) {
conService.closeConnection(mUser.getSessionId());
}
}
}
/**
* Execute the ftp command.
*/
public void service(FtpRequest request, FtpWriter writer) throws IOException {
try {
String metName = "do" + request.getCommand();
Method actionMet = getClass().getDeclaredMethod(metName, METHOD_INPUT_SIG);
actionMet.invoke(this, new Object[] {request, writer});
}
catch(NoSuchMethodException ex) {
writer.write(mFtpStatus.getResponse(502, request, mUser, null));
}
catch(InvocationTargetException ex) {
writer.write(mFtpStatus.getResponse(500, request, mUser, null));
Throwable th = ex.getTargetException();
if (th instanceof java.io.IOException) {
throw (IOException)th;
}
else {
mConfig.getLogger().warn(th);
}
}
catch(Exception ex) {
writer.write(mFtpStatus.getResponse(500, request, mUser, null));
if (ex instanceof java.io.IOException) {
throw (IOException)ex;
}
else {
mConfig.getLogger().warn(ex);
}
}
}
/**
* Check permission - default implementation - does nothing.
*/
protected boolean hasPermission(FtpRequest request) {
return true;
}
/**
* User logout and stop this thread.
*/
public void stop() {
mbStopRequest = true;
if (mDataConnection != null) {
mDataConnection.dispose();
mDataConnection = null;
}
if (mControlSocket != null) {
try {
mControlSocket.close();
}
catch(Exception ex) {
mConfig.getLogger().warn(ex);
}
mControlSocket = null;
}
if (mUser.hasLoggedIn()) {
mUser.logout();
}
mObserver = null;
}
/**
* Is the connection closed?
*/
public boolean isClosed() {
return mbStopRequest;
}
/**
* Monitor the user request.
*/
protected void spyRequest(final String str) {
final SpyConnectionInterface spy = mSpy;
if (spy != null) {
Message msg = new Message() {
public void execute() {
try {
spy.request(str + '\n');
}
catch(Exception ex) {
mSpy = null;
mConfig.getLogger().error(ex);
}
}
};
mConfig.getMessageQueue().add(msg);
}
}
/**
* Get user object
*/
public FtpUser getUser() {
return mUser;
}
/**
* Get connection spy object
*/
public SpyConnectionInterface getSpyObject() {
return mSpy;
}
/**
* Set spy object
*/
public void setSpyObject(SpyConnectionInterface spy) {
mWriter.setSpyObject(spy);
mSpy = spy;
}
/**
* Get observer
*/
public FtpConnectionObserver getObserver() {
return mObserver;
}
/**
* Set observer
*/
public void setObserver(FtpConnectionObserver obsr) {
mObserver = obsr;
}
/**
* Notify observer.
*/
public void notifyObserver() {
mUser.hitUser();
final FtpUser thisUser = mUser;
final FtpConnectionObserver obsr = mObserver;
if (obsr != null) {
Message msg = new Message() {
public void execute() {
obsr.updateConnection(thisUser);
}
};
mConfig.getMessageQueue().add(msg);
}
}
/**
* This method tracks data transfer.
*/
public void dataTransferred(int sz) {
notifyObserver();
}
/**
* Get config object
*/
public FtpConfig getConfig() {
return mConfig;
}
/**
* Get status object
*/
public FtpStatus getStatus() {
return mFtpStatus;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -