使用apache ftpserver为FTP协议适配对象存储

背景:

部分老旧系统使用ftp进行文件传输,在当前技术趋势下及安全要求下,推荐使用对象存储进行文件传输。如何在不改造老旧系统前提下,无缝更换为对象存储?

解决办法:

apache ftpserver提供了纯java的ftp服务器解决方案。

提供了Ftplet来扩展相应ftp操作。

public interface Ftplet {
    void init(FtpletContext var1) throws FtpException;

    void destroy();

    FtpletResult beforeCommand(FtpSession var1, FtpRequest var2) throws FtpException, IOException;

    FtpletResult afterCommand(FtpSession var1, FtpRequest var2, FtpReply var3) throws FtpException, IOException;

    FtpletResult onConnect(FtpSession var1) throws FtpException, IOException;

    FtpletResult onDisconnect(FtpSession var1) throws FtpException, IOException;
}

应用开发者可以继承DefaultFtplet,重载其中的方法来处理上传和下载操作。

但使用此方法,只对下载有效。

下载时:先将对象存储上的文件下载在ftpserver,然后由具体RETR命令执行将文件下载至客户端。如果对象存储下载出现问题,客户端也会下载失败。

上传时:在STOR命令执行前,是无法获取至客户端的文件的,如在STOR命令后,相应的226文件传输完成报文已经发给客户端,在这时再向对象存储上传,不管是否成功,客户端都以为是成功的。问题出现了!

对于上传,如何进行控制呢,在不侵入ftpserver源码的前提下,可对NioListener进行继承,并增加新的IoFilterAdapter,对226报文进行拦截,即在完给客户端之前完成报文的上传,如果上传失败,则将返回消息改成551失败报文。

 public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
        if (writeRequest.getMessage() instanceof LocalizedDataTransferFtpReply) {
            log.info("in file upload filter");
            LocalizedDataTransferFtpReply reply = (LocalizedDataTransferFtpReply) writeRequest.getMessage();
            if (LocalizedFtpReply.REPLY_226_CLOSING_DATA_CONNECTION == reply.getCode()) {
                upload(writeRequest, reply);
            }
        }
        nextFilter.filterWrite(session, writeRequest);
    }

private void upload(WriteRequest writeRequest, LocalizedDataTransferFtpReply reply) throws Exception {
        FtpFile file = reply.getFile();
        String filepath = file.getAbsolutePath();
        //      
        int code = 0;
        try {
            code = upload(filepath);
            if (code != 200) {
                throw new Exception("upload code " + code);
            }
        } catch (Exception e) {
            (new File(tempDir + "/" + filepath)).delete();
            log.error("error on uploading! file {} ", filepath, e);
            DefaultFtpReply newReply = new DefaultFtpReply(LocalizedFtpReply.REPLY_551_REQUESTED_ACTION_ABORTED_PAGE_TYPE_UNKNOWN, "upload to fts failed, " + e.getMessage());
            writeRequest.setMessage(newReply);
        }
    }

这里还有个小问题,就是226报文,在上传和下载时都会用到,卖个关子,请各位自行脑补。

源代码请看附件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值