Загрузка ShareFile с тайм-аутом кода Python 2.7.5 на FTPS STOR
Я пытаюсь загрузить ZIP-файлы в ShareFile с помощью кода Python, но обнаружил, что код зависает в переопределенной версии ftplib.FTP_TLS.storebinary() в классе, унаследованном от FTP_TLs, и не возвращается до тех пор, пока не возникнет исключение ssl.SSLError. Файл загружен и остается неповрежденным до возникновения исключения.
Runtime error
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Python27\ArcGIS10.2\Lib\ftplib.py", line 741, in storbinary
conn.unwrap()
File "C:\Python27\ArcGIS10.2\Lib\ssl.py", line 284, in unwrap
s = self._sslobj.shutdown()
SSLError: The read operation timed out
Почему это происходит, и есть ли способ, как я могу это исправить, чтобы получить сообщение FTP-сервера вместо тайм-аута?
ShareFile требует неявного FTP (порт 990, зашифрованные каналы управления и передачи данных), и это не реализовано в ftplib Python, но я нашел некоторый полезный код здесь, посвященный переполнению стека ( проблема неявного соединения TLS с Python FTP) при исследовании проблемы. После тестирования я вернулся к этому вопросу Stackru, но не смог найти ответ на проблему тайм-аута. Я занимаюсь геоинформационными системами (ГИС), поэтому я вне зоны комфорта с сокетами и протоколом FTP.
В настоящее время я использую тестовый код с Python 2.7.5, встроенным в программное обеспечение под названием ArcMap, но намереваюсь использовать окончательный код с Python, встроенным в альтернативное программное обеспечение под названием FME 2014, также использующее Python 2.7.5. FME сгенерирует zip-файлы пространственных данных, а скрипт завершения работы Python загрузит данные. Обновление до Python 2.7.10 не является возможным из-за рабочих нагрузок и приоритетов ИКТ.
Код, который я использую, указан ниже:
#---------------------------------
# Code by Juan Moreno, answer 3 in https://stackru.com/questions/12164470/python-ftp-tls-connection-issue#
#---------------------------------
from ftplib import FTP_TLS, FTP
import socket
import ssl
class IMPLICIT_FTP_TLS(FTP_TLS):
def __init__(self, host='', user='', passwd='', acct='', keyfile=None, certfile=None, timeout=60):
FTP_TLS.__init__(self, host, user, passwd, acct, keyfile, certfile, timeout)
def connect(self, host='', port=0, timeout=-999): ### FTP.connect(host[, port[, timeout]])
if host != '':
self.host = host
if port > 0:
self.port = port
if timeout != -999:
self.timeout = timeout
try:
self.sock = socket.create_connection((self.host, self.port), self.timeout)
self.af = self.sock.family
self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile)
self.file = self.sock.makefile('rb')
self.welcome = self.getresp()
except Exception as e:
print e
return self.welcome
def ntransfercmd(self, cmd, rest=None):
conn, size = FTP.ntransfercmd(self, cmd, rest)
if self._prot_p:
conn = ssl.wrap_socket(conn, self.keyfile, self.certfile)
return conn, size
Мой тестовый код
import os
#----------------------------------
# test Code using IMPLICIT_FTP_TLS
#----------------------------------
ftps = IMPLICIT_FTP_TLS()
try:
print "conn: {}".format( ftps.connect(host="myorg.sharefileftp.com", port=990, timeout=5) )
print "login: {}".format( ftps.login(user="myorg/me@myorgdomain", passwd="****") )
print "prot_p: {}".format( ftps.prot_p() )
print "cwd: {}".format( ftps.cwd("me@myorgdomain") )
print "cwd: {}".format( ftps.cwd("myfolder") )
filename = r"C:\project\datafile.zip"
print "attempting to upload data..."
with open(filename, "rb") as myzipfile:
print "storB: {}".format( ftps.storbinary("STOR {}".format(os.path.basename(filename)), myzipfile) )
except ssl.SSLError as sslerr:
print sslerr
print "args: {}".format(sslerr.args)
except StandardError as se:
print se
finally:
print "quit: {}".format( ftps.quit() )
del ftps
Спасибо, что потратили время, чтобы прочитать это и, надеюсь, ответить.