From e532b196ccc671a14b9ab9bc18860b2656e5ea42 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 18 Apr 2006 23:14:30 +0000 Subject: [PATCH] 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. --- CHANGES | 10 ++++++- RELEASE-NOTES | 6 ++-- lib/ftp.c | 76 +++++++++++++++++++++++++-------------------------- 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/CHANGES b/CHANGES index f04f8219a..c7ac2e2da 100644 --- 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 diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 4879c36f7..7b2cedeea 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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) diff --git a/lib/ftp.c b/lib/ftp.c index 6e9443721..31921e657 100644 --- 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;