[issue25458] ftplib: command response shift - mismatch

Ivan Pozdeev report at bugs.python.org
Mon Dec 12 23:42:38 EST 2016


Ivan Pozdeev added the comment:

I tried to fix `urllib' and ultimately failed. In a nutshell, handling of the aftermath of an `ntransfercmd' is broken.

Since `ntransfercmd'/`transfercmd' returns a socket, handling of an end-of-transmission response is done in independently invoked code - upon the socket's close. So, if any other operation on the command connection is attempted before that, `ftplib's handling of the session breaks.

The plan to fix follows, but first, some background:

According to http://stackoverflow.com/questions/2549829/using-ftplib-for-multithread-uploads , FTP actually doesn't, and is not designed to, handle transfers in "background". In that you surely can send a further command on the socket, but the server won't actually read it until it's done with the transfer.

According to http://stackoverflow.com/questions/31560701/ftp-data-connections-reuse , data connections cannot be reused.

(RFC959 is vague on both points)

Now, the proposed fix design:

* upon starting a transfer, an FTP object sets a flag, `transfer_in_progress'.
* any public subroutine that would send a further command checks the flag. Then, there are a few options:
    a) refuse any further commands outright until the user explicitly closes the socket (whose close handler would also handle the end-of-transfer response)
    b) check the wire for an end-of-transfer response and if it's there, handle it and allow the command. Closing the socket may or may not handle the response in its own right.
    c) allow the command even if there's no end-of-transfer response. Then handling of the transfer response is done with the function parsing the response for the new command - which will hang until the transfer is complete.
* the code handling the end-of-transfer response clears the flag.

Each option has drawbacks, so I'm not sure which one is the most pythonic.
I would go with b) because it would allow syntax like urllib.urlopen(<...>).read() which it does allow for HTTP.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue25458>
_______________________________________


More information about the Python-bugs-list mailing list