有没有人设法在twisted的FTP服务器上实现REST命令?我目前的尝试:在twisted.protocols.ftp.FTP中实现REST?
from twisted.protocols import ftp
from twisted.internet import defer
class MyFTP(ftp.FTP):
def ftp_REST(self, pos):
try:
pos = int(pos)
except ValueError:
return defer.fail(CmdSyntaxError('Bad argument for REST'))
def all_ok(result):
return ftp.REQ_FILE_ACTN_PENDING_FURTHER_INFO # 350
return self.shell.restart(pos).addCallback(all_ok)
class MyShell(ftp.FTPShell):
def __init__(self, host, auth):
self.position = 0
...
def restart(self, pos):
self.position = pos
print "Restarting at %s"%pos
return defer.succeed(pos)
当一个客户端发送一个REST命令,它需要几秒钟我看到这个脚本输出之前:
Traceback (most recent call last):
Failure: twisted.protocols.ftp.PortConnectionError: DTPFactory timeout
Restarting at <pos>
我在做什么错?对我来说似乎是一个响应应该立即从REST命令后面,为什么套接字超时?
更新:
启用日志记录由让 - 保罗·Calderone的的建议后,它看起来像REST命令甚至没有做它到我的FTP类的DTP连接超时之前从没有连接(时间戳减少到MM:SS为了简洁):
09:53 [TrafficLoggingProtocol,1,127.0.0.1] cleanupDTP
09:53 [TrafficLoggingProtocol,1,127.0.0.1] <<class 'twisted.internet.tcp.Port'> of twisted.protocols.ftp.DTPFactory on 37298>
09:53 [TrafficLoggingProtocol,1,127.0.0.1] dtpFactory.stopFactory
09:53 [-] (Port 37298 Closed)
09:53 [-] Stopping factory <twisted.protocols.ftp.DTPFactory instance at 0x8a792ec>
09:53 [-] dtpFactory.stopFactory
10:31 [-] timed out waiting for DTP connection
10:31 [-] Unexpected FTP error
10:31 [-] Unhandled Error
Traceback (most recent call last):
Failure: twisted.protocols.ftp.PortConnectionError: DTPFactory timeout
10:31 [TrafficLoggingProtocol,2,127.0.0.1] Restarting at 1024
的ftp_PASV
命令返回DTPFactory.deferred
,其被描述为一个“延迟[即]实例连接时会触发”。 RETR命令通过罚款(ftp.FTP将是非常没有价值否则)。
这使我相信在这里有某种阻塞操作,除非进行DTP连接,否则不会让其他任何事情发生;那么只有这样我们才能接受更多的命令。不幸的是,它看起来像一些(所有?)客户端(特别是,我正在使用FileZilla进行测试)在尝试恢复下载时连接之前发送REST命令。
启用日志记录后,它看起来像是阻塞的DTP连接(来自PSV命令)。客户端发送PSV,然后发送REST(然后发送RETR,我想,尽管它从来没有那么远)。看起来问题是客户端在发送REST(并等待响应)之前未连接到DTP,并将它们发送到等待的循环中。他们正在等待对REST的响应,并且正在等待DTP连接。我想这就是为什么REST没有默认实现。人物。 – eternicode 2010-12-02 23:05:40
有些东西阻塞了更多命令的处理过程 - 尽管它并不阻塞,因为它阻止了任何其他代码在反应器线程中运行。 `FTP.lineReceived`首先调用`pauseProducing`。这使得反应器停止读取其连接,直到调用“resumeProducing”为止。而`FTP`只在确定已完全处理完该行后调用`resumeProducing`。在PASV的情况下,“完全处理”意味着客户端已*连接到DTP端口。所以你是对的,由于FTP协议目前正在实施,REST无法工作。 – 2010-12-03 02:29:19