📄 requesthandler.java
字号:
// $Id: RequestHandler.java 366160 2006-01-05 11:09:00Z rana_b $
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import org.apache.commons.logging.Log;
import org.apache.ftpserver.ftplet.DataType;
import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.FtpletEnum;
import org.apache.ftpserver.ftplet.Structure;
import org.apache.ftpserver.interfaces.ConnectionObserver;
import org.apache.ftpserver.interfaces.IConnection;
import org.apache.ftpserver.interfaces.IConnectionManager;
import org.apache.ftpserver.interfaces.IFtpConfig;
import org.apache.ftpserver.interfaces.IFtpStatistics;
import org.apache.ftpserver.interfaces.IIpRestrictor;
import org.apache.ftpserver.interfaces.ISsl;
import org.apache.ftpserver.util.IoUtils;
/**
* This is a generic request handler. It delegates
* the request to appropriate method in subclass.
*
* @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
*/
public
class RequestHandler implements IConnection {
private static final HashMap COMMAND_MAP = new HashMap(64);
private IFtpConfig m_fconfig;
private Log m_log;
private Socket m_controlSocket;
private FtpRequestImpl m_request;
private FtpWriter m_writer;
private BufferedReader m_reader;
private boolean m_isConnectionClosed;
private DirectoryLister m_directoryLister;
private DataType m_dataType = DataType.ASCII;
private Structure m_structure = Structure.FILE;
/**
* Constructor - set the control socket.
*/
public RequestHandler(IFtpConfig fconfig, Socket controlSocket) throws IOException {
m_fconfig = fconfig;
m_controlSocket = controlSocket;
m_log = m_fconfig.getLogFactory().getInstance(getClass());
// data connection object
FtpDataConnection dataCon = new FtpDataConnection();
dataCon.setFtpConfig(m_fconfig);
// reader object
m_request = new FtpRequestImpl();
m_request.setClientAddress(m_controlSocket.getInetAddress());
m_request.setFtpDataConnection(dataCon);
// writer object
m_writer = new FtpWriter();
m_writer.setControlSocket(m_controlSocket);
m_writer.setFtpConfig(m_fconfig);
m_writer.setFtpRequest(m_request);
}
/**
* Set observer.
*/
public void setObserver(ConnectionObserver observer) {
// set writer observer
FtpWriter writer = m_writer;
if(writer != null) {
writer.setObserver(observer);
}
// set request observer
FtpRequestImpl request = m_request;
if(request != null) {
request.setObserver(observer);
}
}
/**
* Get the configuration object.
*/
public IFtpConfig getConfig() {
return m_fconfig;
}
/**
* Get directory lister.
*/
public DirectoryLister getDirectoryLister() {
return m_directoryLister;
}
/**
* Set directory lister.
*/
public void setDirectoryLister(DirectoryLister lister) {
m_directoryLister = lister;
}
/**
* Get the data type.
*/
public DataType getDataType() {
return m_dataType;
}
/**
* Set the data type.
*/
public void setDataType(DataType type) {
m_dataType = type;
}
/**
* Get structure.
*/
public Structure getStructure() {
return m_structure;
}
/**
* Set structure
*/
public void setStructure(Structure stru) {
m_structure = stru;
}
/**
* Get request.
*/
public FtpRequest getRequest() {
return m_request;
}
/**
* Server one FTP client connection.
*/
public void run() {
InetAddress clientAddr = m_request.getRemoteAddress();
IConnectionManager conManager = m_fconfig.getConnectionManager();
try {
// write log message
String hostAddress = clientAddr.getHostAddress();
m_log.info("Open connection - " + hostAddress);
// notify ftp statistics
IFtpStatistics ftpStat = (IFtpStatistics)m_fconfig.getFtpStatistics();
ftpStat.setOpenConnection(this);
// call Ftplet.onConnect() method
boolean isSkipped = false;
Ftplet ftpletContainer = m_fconfig.getFtpletContainer();
FtpletEnum ftpletRet = ftpletContainer.onConnect(m_request, m_writer);
if(ftpletRet == FtpletEnum.RET_SKIP) {
isSkipped = true;
}
else if(ftpletRet == FtpletEnum.RET_DISCONNECT) {
conManager.closeConnection(this);
return;
}
if(!isSkipped) {
// IP permission check
IIpRestrictor ipRestrictor = m_fconfig.getIpRestrictor();
if( !ipRestrictor.hasPermission(clientAddr) ) {
m_log.warn("No permission to access from " + hostAddress);
m_writer.send(530, "ip.restricted", null);
return;
}
// connection limit check
int maxConnections = conManager.getMaxConnections();
if(ftpStat.getCurrentConnectionNumber() > maxConnections) {
m_log.warn("Maximum connection limit reached.");
m_writer.send(530, "connection.limit", null);
return;
}
// everything is fine - go ahead
m_writer.send(220, null, null);
}
m_reader = new BufferedReader(new InputStreamReader(m_controlSocket.getInputStream(), "GB2312"));//GB2312 UTF-8
do {
notifyObserver();
String commandLine = m_reader.readLine();
this.m_log.debug("client command:" + commandLine);
// test command line
if(commandLine == null) {
break;
}
commandLine = commandLine.trim();
if(commandLine.equals("")) {
continue;
}
// parse and check permission
m_request.parse(commandLine);
if(!hasPermission()) {
m_writer.send(530, "permission", null);
continue;
}
// execute command
service(m_request, m_writer);
}
while(!m_isConnectionClosed);
}
catch(SocketException ex) {
// socket closed - no need to do anything
}
catch(Exception ex) {
m_log.warn("RequestHandler.run()", ex);
}
finally {
// close all resources if not done already
if(!m_isConnectionClosed) {
conManager.closeConnection(this);
}
}
}
/**
* Notify connection manager observer.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -