If only a partial file was transfered, we consider that a fatal problem so

we won't try to QUIT the control connection and risk "hanging" waiting for
a response. Test case 161 verifies this. The quit-sending function was
also made static.
This commit is contained in:
Daniel Stenberg
2004-04-22 13:09:00 +00:00
parent 33cb93ad0b
commit 1d3f76df71
4 changed files with 73 additions and 22 deletions

View File

@@ -117,6 +117,7 @@ static CURLcode ftp_sendquote(struct connectdata *conn,
static CURLcode ftp_cwd(struct connectdata *conn, char *path); static CURLcode ftp_cwd(struct connectdata *conn, char *path);
static CURLcode ftp_mkd(struct connectdata *conn, char *path); static CURLcode ftp_mkd(struct connectdata *conn, char *path);
static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path); static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
static CURLcode ftp_quit(struct connectdata *conn);
/* easy-to-use macro: */ /* easy-to-use macro: */
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result #define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result
@@ -604,22 +605,22 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
infof(data, "We have successfully logged in\n"); infof(data, "We have successfully logged in\n");
if (conn->ssl[FIRSTSOCKET].use) { if (conn->ssl[FIRSTSOCKET].use) {
#ifdef HAVE_KRB4 #ifdef HAVE_KRB4
/* we are logged in (with Kerberos) /* We are logged in with Kerberos, now set the requested protection
* now set the requested protection level * level
*/ */
if(conn->sec_complete) if(conn->sec_complete)
Curl_sec_set_protection_level(conn); Curl_sec_set_protection_level(conn);
/* we may need to issue a KAUTH here to have access to the files /* We may need to issue a KAUTH here to have access to the files
* do it if user supplied a password * do it if user supplied a password
*/ */
if(conn->passwd && *conn->passwd) { if(conn->passwd && *conn->passwd) {
result = Curl_krb_kauth(conn); result = Curl_krb_kauth(conn);
if(result) if(result)
return result; return result;
} }
#endif #endif
} }
} }
else { else {
failf(data, "Odd return code after USER"); failf(data, "Odd return code after USER");
@@ -743,10 +744,13 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
ssize_t nread; ssize_t nread;
int ftpcode; int ftpcode;
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
bool was_ctl_valid = ftp->ctl_valid;
/* free the dir tree and file parts */ /* free the dir tree and file parts */
freedirs(ftp); freedirs(ftp);
ftp->ctl_valid = FALSE;
if(data->set.upload) { if(data->set.upload) {
if((-1 != data->set.infilesize) && if((-1 != data->set.infilesize) &&
(data->set.infilesize != *ftp->bytecountp) && (data->set.infilesize != *ftp->bytecountp) &&
@@ -779,6 +783,8 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
result = CURLE_FTP_COULDNT_RETR_FILE; result = CURLE_FTP_COULDNT_RETR_FILE;
} }
} }
ftp->ctl_valid = was_ctl_valid;
#ifdef HAVE_KRB4 #ifdef HAVE_KRB4
Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]); Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
@@ -2312,7 +2318,7 @@ CURLcode ftp_perform(struct connectdata *conn,
* The input argument is already checked for validity. * The input argument is already checked for validity.
* *
* ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
* end of the function. * Curl_ftp_done() function without finding any major problem.
*/ */
CURLcode Curl_ftp(struct connectdata *conn) CURLcode Curl_ftp(struct connectdata *conn)
{ {
@@ -2419,7 +2425,8 @@ CURLcode Curl_ftp(struct connectdata *conn)
else else
freedirs(ftp); freedirs(ftp);
ftp->ctl_valid = TRUE; ftp->ctl_valid = TRUE; /* seems good */
return retcode; return retcode;
} }
@@ -2474,7 +2481,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
/*********************************************************************** /***********************************************************************
* *
* Curl_ftp_quit() * ftp_quit()
* *
* This should be called before calling sclose() on an ftp control connection * This should be called before calling sclose() on an ftp control connection
* (not data connections). We should then wait for the response from the * (not data connections). We should then wait for the response from the
@@ -2482,7 +2489,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
* connection. * connection.
* *
*/ */
CURLcode Curl_ftp_quit(struct connectdata *conn) static CURLcode ftp_quit(struct connectdata *conn)
{ {
ssize_t nread; ssize_t nread;
int ftpcode; int ftpcode;
@@ -2512,13 +2519,13 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
bad in any way, sending quit and waiting around here will make the bad in any way, sending quit and waiting around here will make the
disconnect wait in vain and cause more problems than we need to. disconnect wait in vain and cause more problems than we need to.
Curl_ftp_quit() will check the state of ftp->ctl_valid. If it's ok it ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
will try to send the QUIT command, otherwise it will just return. will try to send the QUIT command, otherwise it will just return.
*/ */
/* The FTP session may or may not have been allocated/setup at this point! */ /* The FTP session may or may not have been allocated/setup at this point! */
if(ftp) { if(ftp) {
(void)Curl_ftp_quit(conn); /* ignore errors on the QUIT */ (void)ftp_quit(conn); /* ignore errors on the QUIT */
if(ftp->entrypath) if(ftp->entrypath)
free(ftp->entrypath); free(ftp->entrypath);

View File

@@ -22,7 +22,7 @@ test80 test81 test82 test83 test84 test85 test86 test87 test507 \
test149 test88 test89 test90 test508 test91 test92 test203 test93 \ test149 test88 test89 test90 test508 test91 test92 test203 test93 \
test94 test95 test509 test510 test97 test98 test99 test150 test151 \ test94 test95 test509 test510 test97 test98 test99 test150 test151 \
test152 test153 test154 test155 test156 test157 test158 test159 test511 \ test152 test153 test154 test155 test156 test157 test158 test159 test511 \
test160 test160 test161
# The following tests have been removed from the dist since they no longer # The following tests have been removed from the dist since they no longer
# work. We need to fix the test suite's FTPS server first, then bring them # work. We need to fix the test suite's FTPS server first, then bring them

39
tests/data/test161 Normal file
View File

@@ -0,0 +1,39 @@
# Server-side
<reply>
<data>
1oooooooooooooooooooooooooooooooooooooooooo2
</data>
<size>
10928
</size>
</reply>
# Client-side
<client>
<server>
ftp
</server>
<name>
FTP RETR PASV
</name>
<command>
ftp://%HOSTIP:%FTPPORT/161
</command>
</test>
# Verify data after the test has been "shot"
<verify>
<protocol>
USER anonymous
PASS curl_by_daniel@haxx.se
PWD
EPSV
TYPE I
SIZE 161
RETR 161
</protocol>
<errorcode>
18
</errrorcode>
</verify>

View File

@@ -258,6 +258,11 @@ while(<FILE>) {
} }
} }
} }
# GETNAME url.c:1901 getnameinfo()
elsif($_ =~ /^GETNAME ([^ ]*):(\d*) (.*)/) {
# not much to do
}
# ADDR url.c:1282 getaddrinfo() = 0x5ddd # ADDR url.c:1282 getaddrinfo() = 0x5ddd
elsif($_ =~ /^ADDR ([^ ]*):(\d*) (.*)/) { elsif($_ =~ /^ADDR ([^ ]*):(\d*) (.*)/) {
# generic match for the filename+linenumber # generic match for the filename+linenumber