Robson Braga Araujo provided a patch that makes libcurl less eager to close
authorDaniel Stenberg <daniel@haxx.se>
Tue, 18 Apr 2006 23:14:30 +0000 (23:14 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 18 Apr 2006 23:14:30 +0000 (23:14 +0000)
the control connection when using FTP, for example when you remove an easy
handle from a multi stack.

CHANGES
RELEASE-NOTES
lib/ftp.c

diff --git a/CHANGES b/CHANGES
index f04f821..c7ac2e2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,14 @@
 
                                   Changelog
 
+Daniel (19 April 2006)
+- Robson Braga Araujo provided a patch that makes libcurl less eager to close
+  the control connection when using FTP, for example when you remove an easy
+  handle from a multi stack.
+
+- Applied a patch by Ates Goral and Katie Wang that corrected my bad fix
+  attempt from April 10.
+
 Daniel (11 April 2006)
 - #1468330 (http://curl.haxx.se/bug/view.cgi?id=1468330) pointed out a bad
   typecast in the curl tool leading to a crash with (64bit?) VS2005 (at least)
@@ -14,7 +22,7 @@ Daniel (11 April 2006)
 Daniel (10 April 2006)
 - Ates Goral found out that if you specified both CURLOPT_CONNECTTIMEOUT and
   CURLOPT_TIMEOUT, the _longer_ time would wrongly be used for the SSL
-  connection time-out! Katie Wang provided a fine patch.
+  connection time-out!
 
 - I merged my hiper patch (http://curl.haxx.se/libcurl/hiper/) into the main
   sources. See the lib/README.multi_socket for implementation story with
index 4879c36..7b2cede 100644 (file)
@@ -18,6 +18,7 @@ This release includes the following changes:
 
 This release includes the following bugfixes:
 
+ o closed control connection with FTP when easy handle was removed from multi
  o curl --trace crash when built with VS2005
  o SSL connect time-out
  o Improved NTLM functionality
@@ -31,12 +32,13 @@ This release includes the following bugfixes:
 
 Other curl-related news since the previous public release:
 
- o 
+ o tclcurl 0.15.3 was released:
+   http://personal1.iddeo.es/andresgarci/tclcurl/english/
 
 This release would not have looked like this without help, code, reports and
 advice from friends like these:
 
  Dan Fandrich, Ilja van Sprundel, David McCreedy, Tor Arntsen, Xavier Bouchoux,
- David Byron, Michele Bini, Ates Goral, Katie Wang
+ David Byron, Michele Bini, Ates Goral, Katie Wang, Robson Braga Araujo
 
         Thanks! (and sorry if I forgot to mention someone)
index 6e94437..31921e6 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2912,42 +2912,6 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
   /* free the dir tree and file parts */
   freedirs(ftp);
 
-  ftp->ctl_valid = FALSE;
-
-  if(data->set.upload) {
-    if((-1 != data->set.infilesize) &&
-       (data->set.infilesize != *ftp->bytecountp) &&
-       !data->set.crlf &&
-       !ftp->no_transfer) {
-      failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
-            " out of %" FORMAT_OFF_T " bytes)",
-            *ftp->bytecountp, data->set.infilesize);
-      conn->bits.close = TRUE; /* close this connection since we don't
-                                  know what state this error leaves us in */
-      return CURLE_PARTIAL_FILE;
-    }
-  }
-  else {
-    if((-1 != conn->size) && (conn->size != *ftp->bytecountp) &&
-       (conn->maxdownload != *ftp->bytecountp)) {
-      failf(data, "Received only partial file: %" FORMAT_OFF_T " bytes",
-            *ftp->bytecountp);
-      conn->bits.close = TRUE; /* close this connection since we don't
-                                  know what state this error leaves us in */
-      return CURLE_PARTIAL_FILE;
-    }
-    else if(!ftp->dont_check &&
-            !*ftp->bytecountp &&
-            (conn->size>0)) {
-      /* We consider this an error, but there's no true FTP error received
-         why we need to continue to "read out" the server response too.
-         We don't want to leave a "waiting" server reply if we'll get told
-         to make a second request on this same connection! */
-      failf(data, "No data was received!");
-      result = CURLE_FTP_COULDNT_RETR_FILE;
-    }
-  }
-
   switch(status) {
   case CURLE_BAD_DOWNLOAD_RESUME:
   case CURLE_FTP_WEIRD_PASV_REPLY:
@@ -2981,19 +2945,23 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
   conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
 
   if(!ftp->no_transfer && !status) {
-    /* Let's see what the server says about the transfer we just performed,
+    /*
+     * Let's see what the server says about the transfer we just performed,
      * but lower the timeout as sometimes this connection has died while the
      * data has been transfered. This happens when doing through NATs etc that
      * abandon old silent connections.
      */
+    long old_time = ftp->response_time;
+
     ftp->response_time = 60; /* give it only a minute for now */
 
     result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
 
-    ftp->response_time = 3600; /* set this back to one hour waits */
+    ftp->response_time = old_time; /* set this back to previous value */
 
     if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
       failf(data, "control connection looks dead");
+      ftp->ctl_valid = FALSE; /* mark control connection as bad */
       return result;
     }
 
@@ -3004,11 +2972,41 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
       /* 226 Transfer complete, 250 Requested file action okay, completed. */
       if((ftpcode != 226) && (ftpcode != 250)) {
         failf(data, "server did not report OK, got %d", ftpcode);
-        return CURLE_FTP_WRITE_ERROR;
+        result = CURLE_PARTIAL_FILE;
       }
     }
   }
 
+  if(result)
+    /* the response code from the transfer showed an error already so no
+       use checking further */
+    ;
+  else if(data->set.upload) {
+    if((-1 != data->set.infilesize) &&
+       (data->set.infilesize != *ftp->bytecountp) &&
+       !data->set.crlf &&
+       !ftp->no_transfer) {
+      failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
+            " out of %" FORMAT_OFF_T " bytes)",
+            *ftp->bytecountp, data->set.infilesize);
+      result = CURLE_PARTIAL_FILE;
+    }
+  }
+  else {
+    if((-1 != conn->size) && (conn->size != *ftp->bytecountp) &&
+       (conn->maxdownload != *ftp->bytecountp)) {
+      failf(data, "Received only partial file: %" FORMAT_OFF_T " bytes",
+            *ftp->bytecountp);
+      result = CURLE_PARTIAL_FILE;
+    }
+    else if(!ftp->dont_check &&
+            !*ftp->bytecountp &&
+            (conn->size>0)) {
+      failf(data, "No data was received!");
+      result = CURLE_FTP_COULDNT_RETR_FILE;
+    }
+  }
+
   /* clear these for next connection */
   ftp->no_transfer = FALSE;
   ftp->dont_check = FALSE;