ftplib - uploading files using transfercmd?

Eddie Corns eddie at holyrood.ed.ac.uk
Fri Mar 19 07:22:06 EST 2004


Kevin Ollivier <kevino at tulane.edu> writes:

>Hi all,

>I've come across a problem that has me stumped, and I thought I'd send
>a message to the gurus to see if this makes sense to anyone else. =) 

>Basically, I'm trying to upload a series of files via FTP. I'm using
>ftplib to do it, and for each file I'm using transfercmd("STOR " +
>myfile) to get the socket, then uploading 4096 bytes at a time and
>providing status updates via a GUI interface. Finally, I close the
>socket, set it to None, then move on to the next file. I'm using
>active FTP to upload.

>The first file uploads just fine, but on the second file I'm
>consistently seeing a weird problem where the response to the PORT
>command (sent by self.makeport()) comes *after* the STOR command is
>sent. The order in which the commands are sent doesn't seem to differ,
>only the order in which the FTP server responds differs. This causes
>the transfercmd() call to see an 'error' because the repsonse to the
>PORT command is a 200, but it expects a response in the 100s. I've
>posted the actual FTP debug calls below. 

>I can resolve the problem by continually re-logging into the server,
>but I'd like to avoid doing that if possible. I've tried setting the
>file mode to binary as well as ASCII with the same results.

>Any clues on what I may be going wrong? Has anyone seen anything like
>this before? I couldn't find anything while googling... TIA for any
>help!

>Kevin

  >#uploading first file...
  >*cmd* u'CWD /newlook/tutorial/'
  >*put* u'CWD /newlook/tutorial/\r\n'
  >*get* '250 CWD command successful.\r\n'
  >*resp* '250 CWD command successful.'
  >*cmd* 'TYPE I'
  >*put* 'TYPE I\r\n'
  >*get* '200 Type set to I.\r\n'
  >*resp* '200 Type set to I.'
  >item = /newlook/tutorial/pub/working_with_themes.htm
  >*cmd* 'PORT 192,168,1,103,13,230'
  >*put* 'PORT 192,168,1,103,13,230\r\n'
  >*get* '200 PORT command successful.\r\n'
  >*resp* '200 PORT command successful.'
  >*cmd* u'STOR /newlook/tutorial/pub/working_with_themes.htm'
  >*put* u'STOR /newlook/tutorial/pub/working_with_themes.htm\r\n'
  >*get* '150 Opening BINARY mode data connection for
  >/newlook/tutorial/pub/working_with_themes.htm.\r\n'
  >*resp* '150 Opening BINARY mode data connection for
  >/newlook/tutorial/pub/working_with_themes.htm.'
* >*cmd* 'TYPE I'
* >*put* 'TYPE I\r\n'
* >*get* '226 Transfer complete.\r\n'
* >*resp* '226 Transfer complete.'

  >#uploading second file...
  >item = /newlook/tutorial/pub/Changing_Page_Properties_1.htm
  >*cmd* 'PORT 192,168,1,103,13,231'
  >*put* 'PORT 192,168,1,103,13,231\r\n'
  >*get* '200 Type set to I.\r\n'
  >*resp* '200 Type set to I.'
  >*cmd* u'STOR /newlook/tutorial/pub/Changing_Page_Properties_1.htm'
  >*put* u'STOR /newlook/tutorial/pub/Changing_Page_Properties_1.htm\r\n'
  >*get* '200 PORT command successful.\r\n'
  >*resp* '200 PORT command successful.'
  >Traceback (most recent call last):
  >  File "F:\oss\eclass\eclass_builder\editor.py", line 1083, in
  >UploadPage
  >    self.UploadFiles(ftpfiles)
  >  File "F:\oss\eclass\eclass_builder\editor.py", line 921, in
  >UploadFiles
  >    ftp.UploadFiles()
  >  File "F:\oss\eclass\eclass_builder\editor.py", line 1908, in
  >UploadFiles
  >    self.mysocket = self.host.transfercmd('STOR ' + dir + myitem)
  >  File "C:\PYTHON23\lib\ftplib.py", line 345, in transfercmd
  >    return self.ntransfercmd(cmd, rest)[0]
  >  File "C:\PYTHON23\lib\ftplib.py", line 336, in ntransfercmd
  >    raise error_reply, resp
  >ftplib.error_reply: 200 PORT command successful.

I suspect the problem is in the bit marked with *.  You are somehow sending
out a new FTP command before the previous was finished.  The 226 belonged to
the transfer command but was eaten by the TYPE command, leaving a dangling
response to the TYPE command.  Are you perhaps not waiting for the retrbinary
method to finish before sending another?  Remember, there is more for
retrbinary to read after it has called the callback for the last time so you
must wait for it to finish.

Eddie



More information about the Python-list mailing list