Загрузка ShareFile с тайм-аутом кода Python 2.7.5 в FTPS STOR

Я пытаюсь загрузить zip-файлы в ShareFile с помощью кода Python, но обнаруживаю, что код зависает в переопределенной версии ftplib.FTP_TLS.storebinary() в классе, наследующемся от FTP_TL, и не возвращается, пока не возникнет исключение 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, но я нашел удобный код здесь, в Stack Overflow (Неявная проблема с TLS-подключением Python FTP.) при исследовании проблемы. После тестирования я вернулся к этому вопросу Stackoverflow, но не смог найти ответ на проблему тайм-аута. Моя область знаний связана с географическими информационными системами (ГИС), поэтому я не в своей зоне комфорта с сокетами и 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://stackoverflow.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

Спасибо, что потратили время, чтобы прочитать это и, надеюсь, ответить.


person Phil_J    schedule 11.06.2015    source источник