[issue10202] ftplib doesn't check close status after sending file
report at bugs.python.org
Wed Oct 27 19:04:16 CEST 2010
John Nagle <nagle at users.sourceforge.net> added the comment:
Re: "Such a requirement should be respected by both peers and AFAICR there's no FTP-related RFC which explicitly states that shutdown() should be used.".
That's because the FTP spec (RFC 959) talks about TCP in reference to the TCP specification, not the Berkeley Sockets implementation. "shutdown" is a Berkeley Sockets interface feature, and isn't formally standardized. Which is why it isn't mentioned in RFCs.
The issue here is that an FTP data connection send is one of the few places where 1) the sender is indicating an EOF by closing the connection, and 2) the sender cares about complete delivery to the receiver. (HTTP servers don't care if the client disconnects before transfer is complete.)
The TCP spec (the original RFC 793) says "A TCP will reliably deliver all buffers SENT before the connection was CLOSED so a user who expects no data in return need only wait to hear the connection was CLOSED successfully to know that all his data was received at the destination TCP." That's the way it was supposed to work when the FTP spec was written. In other words, "close" is supposed to wait for completion of the TCP close handshake.
Today, it's common to close connections to abandon them, in which case there's no need to wait for the close handshake to complete. This resulted in a split at the socket level - there's "close", "SO_LINGER" to affect the wait for the close handshake, and an optional timeout. Then there's "shutdown" for when you explicitly care about what's happening during close.
Python's socket implementation is written with "close" as a "don't care" operation. Since many Python closes happen implicitly, when a reference count goes to 0, this is appropriate; raising an exception during deallocation generally surprises the user. So it's implicit in the Python interface that, if you're using connection close to signal EOF and care about delivery, you should use "shutdown".
So I'd put a shutdown call in "ftplib" at the end of each data connection send. That will block at the end of the transfer and raise an exception (I think that's the way the socket library is coded) if the close handshake doesn't finish cleanly.
Python tracker <report at bugs.python.org>
More information about the Python-bugs-list