On Fri, Aug 17, 2007 at 09:56:49AM -0400, Sanford Walke IV wrote:
> How do you explain section 12.7 of 4217, then?  The timing diagrams
> clearly show that data transfer is not expected before the 150is passed.

It is just an example.

> I've traced this with the vendor, and it's very clear that lftp is sending
> data too early.  The data connection is NOT available until after the 150
> has been sent.

I cannot imagine ftp server failing because of early data on data socket,
except if it was specially coded for that. However, here is a patch to test -
please try.

--
   Alexander.
Index: ftpclass.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/ftpclass.cc,v
retrieving revision 1.416
diff -u -p -r1.416 ftpclass.cc
--- ftpclass.cc 14 Aug 2007 13:04:17 -0000      1.416
+++ ftpclass.cc 17 Aug 2007 14:43:06 -0000
@@ -1686,6 +1686,7 @@ int   Ftp::Do()
 
       flags&=~IO_FLAG;
       last_priority=priority;
+      conn->received_150=false;
 
       switch((enum open_mode)mode)
       {
@@ -2046,7 +2047,7 @@ int   Ftp::Do()
         return MOVED;
       }
 
-      goto pre_data_open;
+      goto pre_waiting_150;
 
    case(DATASOCKET_CONNECTING_STATE):
    datasocket_connecting_state:
@@ -2122,7 +2123,7 @@ int   Ftp::Do()
            goto usual_return;
         DebugPrint("---- ",_("Data connection established"),9);
         if(!conn->proxy_is_http)
-           goto pre_data_open;
+           goto pre_waiting_150;
 
         pasv_state=PASV_HTTP_PROXY_CONNECTED;
         m=MOVED;
@@ -2133,11 +2134,22 @@ int   Ftp::Do()
         conn->data_iobuf=new IOBufferFDStream(new 
FDStream(conn->data_sock,"data-socket"),IOBuffer::GET);
       case PASV_HTTP_PROXY_CONNECTED:
         if(HttpProxyReplyCheck(conn->data_iobuf))
-           goto pre_data_open;
+           goto pre_waiting_150;
         goto usual_return;
       }
 
-   pre_data_open:
+   pre_waiting_150:
+      state=WAITING_150_STATE;
+      m=MOVED;
+   case WAITING_150_STATE:
+      m|=FlushSendQueue();
+      m|=ReceiveResp();
+      if(state!=WAITING_150_STATE || Error())
+         return MOVED;
+      if(!conn->received_150)
+        return m;
+
+      // now init data connection properly and start data exchange
       assert(rate_limit==0);
       rate_limit=new RateLimit(hostname);
       state=DATA_OPEN_STATE;
@@ -3226,6 +3238,7 @@ void  Ftp::Close()
       case(CWD_CWD_WAITING_STATE):
       case(WAITING_STATE):
       case(DATA_OPEN_STATE):
+      case(WAITING_150_STATE):
         state=EOF_STATE;
         break;
       case(INITIAL_STATE):
@@ -3675,6 +3688,9 @@ void Ftp::CheckFEAT(char *reply)
 
 void Ftp::CheckResp(int act)
 {
+   if(act==150)
+      conn->received_150=true;
+
    if(act==150 && (flags&PASSIVE_MODE) && conn->aborted_data_sock!=-1)
       conn->CloseAbortedDataConnection();
 
@@ -4076,6 +4092,7 @@ const char *Ftp::CurrentStatus()
         return _("Waiting for other copy peer...");
       if(mode==STORE)
         return(_("Waiting for transfer to complete"));
+   case(WAITING_150_STATE):
       return(_("Waiting for response..."));
    case(ACCEPTING_STATE):
       return(_("Waiting for data connection..."));
Index: ftpclass.h
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/ftpclass.h,v
retrieving revision 1.148
diff -u -p -r1.148 ftpclass.h
--- ftpclass.h  10 Aug 2007 16:18:11 -0000      1.148
+++ ftpclass.h  17 Aug 2007 14:39:48 -0000
@@ -63,7 +63,8 @@ class Ftp : public NetAccess
       DATA_OPEN_STATE,    // data connection is open, for read or write
       CWD_CWD_WAITING_STATE,  // waiting until 'CWD $cwd' finishes
       USER_RESP_WAITING_STATE,// waiting until 'USER $user' finishes
-      DATASOCKET_CONNECTING_STATE  // waiting for data_sock to connect
+      DATASOCKET_CONNECTING_STATE, // waiting for data_sock to connect
+      WAITING_150_STATE           // waiting for 150 message
    };
 
 
@@ -93,6 +94,7 @@ class Ftp : public NetAccess
       bool try_feat_after_login;
       bool tune_after_login;
       bool utf8_activated; // server is switched to UTF8 mode.
+      bool received_150;
 
       char type;  // type of transfer: 'A'scii or 'I'mage
 

Reply via email to