Robson Braga Araujo filed bug report #1776235

(http://curl.haxx.se/bug/view.cgi?id=1776235) about ftp requests with NOBODY
on a directory would do a "SIZE (null)" request. This is now fixed and test
case 1000 was added to verify.
This commit is contained in:
Daniel Stenberg 2007-08-17 22:22:43 +00:00
parent f3c7adcb54
commit 3217809294
5 changed files with 76 additions and 7 deletions

View File

@ -6,6 +6,12 @@
Changelog Changelog
Daniel S (18 August 2007)
- Robson Braga Araujo filed bug report #1776235
(http://curl.haxx.se/bug/view.cgi?id=1776235) about ftp requests with NOBODY
on a directory would do a "SIZE (null)" request. This is now fixed and test
case 1000 was added to verify.
Daniel S (17 August 2007) Daniel S (17 August 2007)
- Song Ma provided a patch that cures a problem libcurl has when doing resume - Song Ma provided a patch that cures a problem libcurl has when doing resume
HTTP PUT using Digest authentication. Test case 5320 and 5322 were also HTTP PUT using Digest authentication. Test case 5320 and 5322 were also

View File

@ -41,6 +41,7 @@ This release includes the following bugfixes:
o memory leak when handling compressed data streams from broken servers o memory leak when handling compressed data streams from broken servers
o no NTLM unicode response o no NTLM unicode response
o resume HTTP PUT using Digest authentication o resume HTTP PUT using Digest authentication
o FTP NOBODY requests on directories sent "SIZE (null)"
This release includes the following known bugs: This release includes the following known bugs:
@ -64,6 +65,6 @@ advice from friends like these:
Daniel Cater, Colin Hogben, Jofell Gallardo, Daniel Johnson, Daniel Cater, Colin Hogben, Jofell Gallardo, Daniel Johnson,
Ralf S. Engelschall, James Housley, Chris Flerackers, Patrick Monnerat, Ralf S. Engelschall, James Housley, Chris Flerackers, Patrick Monnerat,
Jayesh A Shah, Greg Zavertnik, Peter O'Gorman, Greg Morse, Dmitriy Sergeyev, Jayesh A Shah, Greg Zavertnik, Peter O'Gorman, Greg Morse, Dmitriy Sergeyev,
Scott Cantor, Allen Pulsifer, Andrew Wansink Scott Cantor, Allen Pulsifer, Andrew Wansink, Robson Braga Araujo
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@ -140,6 +140,19 @@ static int ftp_need_type(struct connectdata *conn,
#define NBFTPSENDF(x,y,z) if ((result = Curl_nbftpsendf(x,y,z)) != CURLE_OK) \ #define NBFTPSENDF(x,y,z) if ((result = Curl_nbftpsendf(x,y,z)) != CURLE_OK) \
return result return result
/*
* NOTE: back in the old days, we added code in the FTP code that made NOBODY
* requests on files respond with headers passed to the client/stdout that
* looked like HTTP ones.
*
* This approach is not very elegant, it causes confusion and is error-prone.
* It is subject for removal at the next (or at least a future) soname bump.
* Until then you can test the effects of the removal by undefining the
* following define named CURL_FTP_HTTPSTYLE_HEAD.
*/
#define CURL_FTP_HTTPSTYLE_HEAD 1
static void freedirs(struct connectdata *conn) static void freedirs(struct connectdata *conn)
{ {
struct ftp_conn *ftpc = &conn->proto.ftpc; struct ftp_conn *ftpc = &conn->proto.ftpc;
@ -1303,8 +1316,8 @@ static CURLcode ftp_state_post_size(struct connectdata *conn)
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->reqdata.proto.ftp; struct FTP *ftp = conn->data->reqdata.proto.ftp;
if(ftp->no_transfer) { if(ftp->no_transfer && ftp->file) {
/* if a "head"-like request is being made */ /* if a "head"-like request is being made (on a file) */
/* Determine if server can respond to REST command and therefore /* Determine if server can respond to REST command and therefore
whether it supports range */ whether it supports range */
@ -1323,8 +1336,8 @@ static CURLcode ftp_state_post_type(struct connectdata *conn)
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->reqdata.proto.ftp; struct FTP *ftp = conn->data->reqdata.proto.ftp;
if(ftp->no_transfer) { if(ftp->no_transfer && ftp->file) {
/* if a "head"-like request is being made */ /* if a "head"-like request is being made (on a file) */
/* we know ftp->file is a valid pointer to a file name */ /* we know ftp->file is a valid pointer to a file name */
NBFTPSENDF(conn, "SIZE %s", ftp->file); NBFTPSENDF(conn, "SIZE %s", ftp->file);
@ -1898,6 +1911,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
data->info.filetime = (long)curl_getdate(buf, &secs); data->info.filetime = (long)curl_getdate(buf, &secs);
} }
#ifdef CURL_FTP_HTTPSTYLE_HEAD
/* If we asked for a time of the file and we actually got one as well, /* If we asked for a time of the file and we actually got one as well,
we "emulate" a HTTP-style header in our output. */ we "emulate" a HTTP-style header in our output. */
@ -1928,6 +1942,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
if(result) if(result)
return result; return result;
} /* end of a ridiculous amount of conditionals */ } /* end of a ridiculous amount of conditionals */
#endif
} }
break; break;
default: default:
@ -2096,6 +2111,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1; filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1;
if(instate == FTP_SIZE) { if(instate == FTP_SIZE) {
#ifdef CURL_FTP_HTTPSTYLE_HEAD
if(-1 != filesize) { if(-1 != filesize) {
snprintf(buf, sizeof(data->state.buffer), snprintf(buf, sizeof(data->state.buffer),
"Content-Length: %" FORMAT_OFF_T "\r\n", filesize); "Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
@ -2103,6 +2119,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
if(result) if(result)
return result; return result;
} }
#endif
result = ftp_state_post_size(conn); result = ftp_state_post_size(conn);
} }
else if(instate == FTP_RETR_SIZE) else if(instate == FTP_RETR_SIZE)
@ -2125,13 +2142,14 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn,
switch(instate) { switch(instate) {
case FTP_REST: case FTP_REST:
default: default:
#ifdef CURL_FTP_HTTPSTYLE_HEAD
if (ftpcode == 350) { if (ftpcode == 350) {
result = Curl_client_write(conn, CLIENTWRITE_BOTH, result = Curl_client_write(conn, CLIENTWRITE_BOTH,
(char *)"Accept-ranges: bytes\r\n", 0); (char *)"Accept-ranges: bytes\r\n", 0);
if(result) if(result)
return result; return result;
} }
#endif
result = ftp_state_post_rest(conn); result = ftp_state_post_rest(conn);
break; break;

View File

@ -43,4 +43,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test296 test297 test298 test610 test611 test612 test406 test407 test408 \ test296 test297 test298 test610 test611 test612 test406 test407 test408 \
test409 test613 test614 test700 test701 test702 test704 test705 test703 \ test409 test613 test614 test700 test701 test702 test704 test705 test703 \
test706 test707 test350 test351 test352 test353 test289 test540 test354 \ test706 test707 test350 test351 test352 test353 test289 test540 test354 \
test231 test1001 test1002 test231 test1000 test1001 test1002

44
tests/data/test1000 Normal file
View File

@ -0,0 +1,44 @@
<testcase>
<info>
<keywords>
FTP
PASV
LIST
NOBODY
</keywords>
</info>
#
# Server-side
<reply>
# When doing LIST, we get the default list output hard-coded in the test
# FTP server
<datacheck>
</datacheck>
</reply>
#
# Client-side
<client>
<server>
ftp
</server>
<name>
FTP dir list PASV with -I
</name>
<command>
ftp://%HOSTIP:%FTPPORT/1000/ -I
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
USER anonymous
PASS ftp@example.com
PWD
CWD 1000
QUIT
</protocol>
</verify>
</testcase>