Issue 12002: ftplib.FTP.abort fails with TypeError on Python 3.x (original) (raw)

On Python 3.2, calling abort() on an ftplib.FTP object will cause an exception:

ftp = ftplib.FTP('localhost') ftp.abort() Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.2/ftplib.py", line 246, in abort self.sock.sendall(line, MSG_OOB) TypeError: 'str' does not support the buffer interface

The offending line, ftplib.py:246, should be replaced by self.sock.sendall(line.encode(self.encoding), MSG_OOB)

This is a nasty one and mainly it's the reason why there are no tests for abort() method. In FTP, ABOR command is supposed to be sent as OOB (out-of-band) "urgent" data and the dummy FTP server we're using for the funcional tests must handle this appopriately.

In practical terms this means that when the client calls self.sock.sendall(line, MSG_OOB) the server is supposed to call socket.recv(1024, MSG_OOB). Since our server uses asyncore this becomes quite twisted to handle. This can be avoided by setting SO_OOBINLINE which tells the server to handle the urgent data inline meaning that both plain and urgent data can be received with a normal sock.recv(1024) call.

The patch in attachment does this and also fixes FTP_TLS.abort() which is not able to accept the extra MSG_OOB flag argument.

There's a side note: on certain platforms SO_OOBINLINE has no effect, resulting in asyncore's handle_expt method being called, see: http://code.google.com/p/pyftpdlib/source/browse/trunk/pyftpdlib/ftpserver.py#2064 I haven't handled this case in my patch because I'm not sure what platforms are broken. I'd say we can commit this patch as-is, wait for the buildbots to turn red and then disable the test for those platforms afterwards.