pythonftpftplibeoferrorftputil

Getting EOFError along with exceptions when using ftplib


I'm looking into using ftplib (and possibly ftputil) for doing some automated FTP file syncing. I have a couple of servers to test this against at the moment, but, whilst I'm having a successful conversation with both servers, I get EOFError-s with each error reply. For example: if I try to log in with an incorrect user/pass, I will get the 530 response with everything... but I also get an EOFError; if I login with a correct user/pass or try to dir() after doing so etc., I get no EOFError.

It seems to only appear with error messages. I strongly suspect this may be caused by the servers rather than python: I've not found any mention of this issue elsewhere. I, however, have very little control over the server setup.

I'm asking for ideas:

Thanks!


Solution

  • The servers are sending EOF to tell you that they've terminated the connection.

    You should treat this no differently than any other disconnection event, except that obviously you need to handle it with except EOFError.

    See the source, from http://svn.python.org/view/python/trunk/Lib/ftplib.py?view=markup

    # Internal: return one line from the server, stripping CRLF.
    # Raise EOFError if the connection is closed
    182     def getline(self):
    183         line = self.file.readline()
    184         if self.debugging > 1:
    185             print '*get*', self.sanitize(line)
    186         if not line: raise EOFError
    187         if line[-2:] == CRLF: line = line[:-2]
    188         elif line[-1:] in CRLF: line = line[:-1]
    189         return line
    

    EOFError is only raised when readline() on the connection returns a blank line, which the comment indicates is a disconnection event.

    Edit in re your comment:

    The server doesn't send an empty line. readline() returns everything up to the next \n or \r or \r\n or all of the abouve depending on how it's configured. In this case, there is nothing to read because the end of the file has been reached. This causes readline() to return a blank line, it doesn't mean a blank line has been read. If a blank line had been read, readline() would return the character that ended the line (\n or \r or \n\r).

    If you don't get the exception when using FTPUtil, that is because it handles it internally.