[issue25458] ftplib: command response shift - mismatch

2016-03-09 Thread Peter Pan

Peter Pan added the comment:

Here is a small test for the new version.

(To see the original ftplib.py version failing copy+paste the code from my 
initial post into a python file and run)

--
Added file: http://bugs.python.org/file42100/test_ftp.py

___
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue25458>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue25458] ftplib: command response shift - mismatch

2016-03-09 Thread Peter Pan

Peter Pan added the comment:

I've updated "ftplib.py" from the 3.5.1 source code release.
This should fix issues:
 http://bugs.python.org/issue25458
 http://bugs.python.org/issue25491

--
Added file: http://bugs.python.org/file42099/ftplib.py

___
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue25458>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue25458] ftplib: command response shift - mismatch

2016-03-08 Thread Peter Pan

Peter Pan added the comment:

The problem in my example is ftplib reports a "226" response to command "NOOP" 
which is nonsense. ftplib received "226" before "ftp.sendcmd('NOOP')" was 
called.

Since "transfercmd()" returns a socket, ftplib was planned to allow for manual 
transfer socket handling, but it is currently unable to handle the asynchronous 
responses from the server when the transfer is done. This is a bug or design 
error.


Multiple changes are needed to support manual transfer socket handling. I 
suggest the following:

Since asynchronous responses from the server are possible on the command 
socket, "set_debuglevel(1)" must report them at once, but this would require 
multithreading. A good compromise is to debug print and clear any buffered 
status right before sending the next command.
We also need a method to check the last status code, in order to know the 
result of the last manual transfer. ftplib has to store it separately as an 
attribute.


New attribute
-

this.last_status_code = None #has no effect to any command or debug output
this.last_status_message

New internal method
---

#loop: look for buffered status response; if present, print debug and assign 
this.last_status = buffer.pop()
.unbuffer():
 ...


New user methods


#Set last status to None so we can use "get_last_status" to check/poll for the 
next one.
.clear_last_status():
 this.last_status_code = None
 this.last_status_message = ""
 return

#Return the last status received from the server; if there is one on the 
buffer, unbuffer and return that.
.get_last_status():
 this.unbuffer()
 return [this.last_status_code, this.last_status_message]

--

___
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue25458>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue25458] ftplib: command response shift - mismatch

2015-10-22 Thread Peter Pan

New submission from Peter Pan:

When handling the transfer socket manually the asynchronous status message "226 
transfer complete" on the control socket is falsely taken as response for the 
last sent command.
ftplib reads the response too late and the command/response order becomes 
invalid.

I can avoid that by using the undocumented ftplib internal method FTP.getline() 
after the transfer socket is closed and not sending more commands while the 
transfer socket is open.

It would be useful, if ftplib empties the response socket buffer before sending 
the next command. But maybe the best solution is an optional function callback 
when the "226" response appears, while it is ignored when not matching the last 
sent command.

Example code that triggers the problem:

import ftplib
import socket
import re


ftp = ftplib.FTP()
ftp.set_debuglevel(1)
ftp.connect('ftp.debian.org', timeout=10)
ftp.login('anonymous','u...@example.com')
ftp.sendcmd('TYPE A')

s = ftp.transfercmd('LIST')

'''
#manual transfer socket - should result in same behaviour
r = ftp.sendcmd('EPSV')
r = re.search('\|([0-9]+)\|', r)
port = int( r.group(1) )
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('ftp.debian.org', port))
ftp.sendcmd('LIST')
'''

fp = s.makefile('r')
fp.read()
fp.close()
s.close()

#ftplib falsely sees "226 transfer complete" as response to next command
ftp.sendcmd('NOOP')

--
components: Library (Lib)
messages: 253326
nosy: peterpan
priority: normal
severity: normal
status: open
title: ftplib: command response shift - mismatch
type: behavior
versions: Python 3.4

___
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue25458>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com