Python FTPS 上传错误:425 无法建立数据连接:不允许操作

问题描述 投票:0回答:2

我正在尝试使用 ftps 将文件发送到 FTP 服务器。登录和更改目录工作:

import ftplib
ftps = ftplib.FTP_TLS('host','user','pwd')
ftps.set_pasv(True)
ftps.prot_p()
ftps.cwd('/target_directory')

但是当我尝试上传文件时:

file = open(file, 'rb')
send_cmd = 'STOR file_name.txt'
ftps.storbinary(send_cmd, file)
file.close()
ftps.quit()

我收到以下错误:

File "/script/location/script.py", line 161, in <module>
ftps.storbinary(send_cmd,file)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ftplib.py", line 772, in storbinary
return self.voidresp()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ftplib.py", line 229, in voidresp
resp = self.getresp()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ftplib.py", line 222, in getresp
raise error_temp, resp
ftplib.error_temp: 425 Unable to build data connection: Operation not permitted

我读到,425 响应代码通常是处于活动模式的结果,这就是我添加

ftps.set_pasv(True)
的原因(尽管默认情况下这是 True)。

我也尝试过使用

ftps.retrlines('LIST')
列出目录内容,但得到了基本相同的错误。我正在使用Python 2.7.10。任何帮助将不胜感激。

python ftplib tls1.2
2个回答
2
投票

这是 python 中报告的错误:https://bugs.python.org/issue19500

您可以在新课程中应用补丁

class Explicit_FTP_TLS(ftplib.FTP_TLS):
    """Explicit FTPS, with shared TLS session"""
    def ntransfercmd(self, cmd, rest=None):
        conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
        if self._prot_p:
            conn = self.context.wrap_socket(conn,
                                            server_hostname=self.host,
                                            session=self.sock.session)
        return conn, size

0
投票

谢谢@pin3da,终于修复了这个bug,需要一段时间才能找到你的答案。但对我来说,它需要稍微修改一下,如下所示,希望它可以帮助其他像我一样在这个问题(十年前的问题)上苦苦挣扎的人。

import ftplib
import ssl

class ImplicitFTP_TLS(ftplib.FTP_TLS):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._sock = None

    @property
    def sock(self):
        return self._sock

    @sock.setter
    def sock(self, value):
        if value is not None and not isinstance(value, ssl.SSLSocket):
            value = self.context.wrap_socket(value)
        self._sock = value

    def ntransfercmd(self, cmd, rest=None):
        conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
        if self._prot_p:
            conn = self.context.wrap_socket(conn,
                                            server_hostname=self.host,
                                            session=self.sock.session)
        return conn, size

演示代码

ftps = ImplicitFTP_TLS()
ftps.connect(host={your_ftp_host}, port=990, timeout=300)
ftps.login({your_ftp_account},{your_ftp_password})
ftps.prot_p()
# do something
print(ftps.getwelcome())
ftps.close()
© www.soinside.com 2019 - 2024. All rights reserved.