This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Ivan.Pozdeev
Recipients Ivan.Pozdeev, giampaolo.rodola, peterpan
Date 2016-12-13.04:42:37
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1481604158.32.0.0301798814159.issue25458@psf.upfronthosting.co.za>
In-reply-to
Content
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.
History
Date User Action Args
2016-12-13 04:42:38Ivan.Pozdeevsetrecipients: + Ivan.Pozdeev, giampaolo.rodola, peterpan
2016-12-13 04:42:38Ivan.Pozdeevsetmessageid: <1481604158.32.0.0301798814159.issue25458@psf.upfronthosting.co.za>
2016-12-13 04:42:38Ivan.Pozdeevlinkissue25458 messages
2016-12-13 04:42:37Ivan.Pozdeevcreate