ShareFile的隐式FTPS失败,"操作超时"在Python中

时间:2017-01-11 18:54:52

标签: python ftplib ftps sharefile

当使用Python通过隐式FTPS建立与ShareFile的连接时,我得到以下结果:

Traceback (most recent call last):
    ftps.storbinary("STOR /file, open(file, "rb"), 1024)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ftplib.py", line 769, in storbinary
conn.unwrap()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 791, in unwrap
    s = self._sslobj.shutdown()
SSLError: ('The read operation timed out',)

我的tyFTP(因为ftplib不直接支持隐式FTPS所必需的)类来自:Python FTP implicit TLS connection issue。这是代码:

ftps = tyFTP()
try:
  ftps.connect(‘ftps.host.domain’, 990)
except:
  traceback.print_exc()
  traceback.print_stack()
ftps.login(‘uid', ‘pwd')
ftps.prot_p()

try:
  ftps.storbinary("STOR /file", open(file, "rb"), 1024)
  # i also tried non-binary, but that didn't work either
  # ftps.storlines("STOR /file", open(file, "r"))
except:
  traceback.print_exc()
  traceback.print_stack()

之前已经问过这个问题,但提供的唯一解决方案是破解python代码。这是最好/唯一的选择吗?

ShareFile upload with Python 2.7.5 code timesout on FTPS STOR

ftplib - file creation very slow: SSLError: The read operation timed out

ftps.storlines socket.timeout despite file upload completing

在python.org上还有一个关于这个问题的旧讨论:http://bugs.python.org/issue8108。有人认为这是一个难以解决的模糊情况(也许从来没有?)

请注意:我会在现有问题上添加评论,但我的声誉不足以发表评论(新的堆栈交换用户)。

1 个答案:

答案 0 :(得分:1)

有时您需要的帮助是您自己的。

为了解决这个问题而不直接修改ftplib代码(这需要在Mac上跳过箍,因为你无法在/ System / Library中轻松编写/修改文件)我在ftplib.FTP_TLS中覆盖了storbinary方法。这主要是使用此修复程序来支持隐式FTPS:

Python FTP implicit TLS connection issue

然后将这些行添加到类tyFTP中,并注释掉conn.unwrap()调用,并将其替换为'传递':

  def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None):
    self.voidcmd('TYPE I')
    conn = self.transfercmd(cmd, rest)
    try:
      while 1:
        buf = fp.read(blocksize)
        if not buf: break
        conn.sendall(buf)
        if callback: callback(buf)
      if isinstance(conn, ssl.SSLSocket):
        pass
#         conn.unwrap()
    finally:
      conn.close()
    return self.voidresp()