Search code examples
python-3.xftpftps

FTP doesn't connect ends up with "EOFError"


I am trying to connect to connect to a FTP site to download some files:

from ftplib import FTP_TLS
from ftplib import FTP
import ssl
import ftplib


FTP_TLS.ssl_version = ssl.PROTOCOL_TLSv1_2
ftps = FTP_TLS(timeout=100)    
ftps.set_debuglevel(2)     
ftps.connect('IP', port)
ftps.auth()
ftps.prot_p()
ftps.login('username', 'password')

The program tries for sometime before it fails with the following error:

get '' Traceback (most recent call last): File "FTP.py", line 12, in ftps.connect('IP', port) File "C:_data\learn\Miniconda\lib\ftplib.py", line 155, in connect self.welcome = self.getresp() File "C:_data\learn\Miniconda\lib\ftplib.py", line 236, in getresp resp = self.getmultiline() File "C:_data\learn\Miniconda\lib\ftplib.py", line 222, in getmultiline line = self.getline() File "C:_data\learn\Miniconda\lib\ftplib.py", line 210, in getline raise EOFError EOFError

I am not sure what the cause of this error is . I can connect to the ftp server using the same details with a FTP client (FileZilla). Can anyone point out if there is issue with my code and possible options to fix this.

Edit 1

As suggested below posting FileZilla logs :

Status:   Connecting to IP:Port...
Status:   Connection established, initializing TLS...
Status:   Verifying certificate...
Status:   TLS connection established, waiting for welcome message...
Status:   Logged in
Status:   Retrieving directory listing...
Status:   Directory listing of "/" successful

FIleZilla explicitly pops up a certificate which I press OK on my desktop after which the connection is established. I am assuming the failure here is because my code doesn't accept the certificate. Any help is appreciated.


Solution

  • For anyone looking for an answer, the issue was that implicit FTPS connections need the socket to be ssl wrapped automatically.I used the below piece of code written by George Leslie-Waksman

    import ftplib
    import ssl
    
    class ImplicitFTP_TLS(ftplib.FTP_TLS):
        """FTP_TLS subclass that automatically wraps sockets in SSL to support implicit FTPS."""
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            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
    

    If this resolves your issue, kindly upvote the original answer -->https://stackoverflow.com/a/36049814/392233