-
-
Save hoogenm/de42e2ef85b38179297a0bba8d60778b to your computer and use it in GitHub Desktop.
| # Combines several solutions found on the internet | |
| class ImplicitFTP_TLS(ftplib.FTP_TLS): | |
| """FTP_TLS subclass to support implicit FTPS.""" | |
| """Constructor takes a boolean parameter ignore_PASV_host whether o ignore the hostname""" | |
| """in the PASV response, and use the hostname from the session instead""" | |
| def __init__(self, *args, **kwargs): | |
| self.ignore_PASV_host = kwargs.get('ignore_PASV_host') == True | |
| super().__init__(*args, {k: v for k, v in kwargs.items() if not k == 'ignore_PASV_host'}) | |
| self._sock = None | |
| @property | |
| def sock(self): | |
| """Return the socket.""" | |
| return self._sock | |
| @sock.setter | |
| def sock(self, value): | |
| """When modifying the socket, ensure that it is ssl wrapped.""" | |
| 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): | |
| """Override the ntransfercmd method""" | |
| conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest) | |
| conn = self.sock.context.wrap_socket( | |
| conn, server_hostname=self.host, session=self.sock.session | |
| ) | |
| return conn, size | |
| def makepasv(self): | |
| host, port = super().makepasv() | |
| return (self.host if self.ignore_PASV_host else host), port |
It works!!! I will cry, you have saved us, we are grateful
Worked for me. Thank you for saving me so much time, I was in a very deep rabbit hole without this. Thank you!
Thanks for the helpful post—our team encountered a similar issue and wanted to share how we resolved it.
We had no problems running this on Python 3.8 and 3.9. However, after upgrading to Python 3.11, we started seeing the following SSL error:
ssl.SSLEOFError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:2716)
After some investigation, we found it might be related to this issue:
https://bugs.python.org/issue43794
To address this, we updated our code with the following:
self.ftp = _ImplicitFTP_TLS()
self.ftp.context.options |= ssl.OP_IGNORE_UNEXPECTED_EOF
self.ftp.connect(self.host, self.port)This fixed the problem on Python 3.11.
I was facing the same errors for 3 hours before finding this thread. Thank you so much everyone.
Thank you so much buddy! It work like a charm from scratch...
@Niilavarnam Hi, this is just a class code that will replace the original one to enable implicit TLS. Connecting and other logic are up to you how you will manage it. For example:
ftps = ImplicitFTP_TLS()ftps.ssl_version = ssl.PROTOCOL_TLSv1_2ftps.connect(ftps_host, ftps_port, timeout=30)