mirror of
https://github.com/curl/curl.git
synced 2026-04-14 00:51:42 +08:00
ftp: fix prequotes for a directory in URL
Allow prequotes to be sent after curl has changed the working directory, just before the listing command if the URL is a directory. FTP state machine is updated with the new FTP_LIST_PREQUOTE state and FTP_RETR_LIST_TYPE type. Test 754 verifies Fixes #8602 Closes #17616
This commit is contained in:
parent
149d436457
commit
fdf50d64b8
32
lib/ftp.c
32
lib/ftp.c
@ -114,12 +114,14 @@ static const char * const ftp_state_names[]={
|
||||
"QUOTE",
|
||||
"RETR_PREQUOTE",
|
||||
"STOR_PREQUOTE",
|
||||
"LIST_PREQUOTE",
|
||||
"POSTQUOTE",
|
||||
"CWD",
|
||||
"MKD",
|
||||
"MDTM",
|
||||
"TYPE",
|
||||
"LIST_TYPE",
|
||||
"RETR_LIST_TYPE",
|
||||
"RETR_TYPE",
|
||||
"STOR_TYPE",
|
||||
"SIZE",
|
||||
@ -1459,6 +1461,14 @@ static CURLcode ftp_state_list(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode ftp_state_list_prequote(struct Curl_easy *data,
|
||||
struct ftp_conn *ftpc,
|
||||
struct FTP *ftp)
|
||||
{
|
||||
/* We have sent the TYPE, now we must send the list of prequote strings */
|
||||
return ftp_state_quote(data, ftpc, ftp, TRUE, FTP_LIST_PREQUOTE);
|
||||
}
|
||||
|
||||
static CURLcode ftp_state_retr_prequote(struct Curl_easy *data,
|
||||
struct ftp_conn *ftpc,
|
||||
struct FTP *ftp)
|
||||
@ -1647,6 +1657,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
|
||||
break;
|
||||
case FTP_RETR_PREQUOTE:
|
||||
case FTP_STOR_PREQUOTE:
|
||||
case FTP_LIST_PREQUOTE:
|
||||
item = data->set.prequote;
|
||||
break;
|
||||
case FTP_POSTQUOTE:
|
||||
@ -1736,6 +1747,10 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
|
||||
break;
|
||||
case FTP_POSTQUOTE:
|
||||
break;
|
||||
case FTP_LIST_PREQUOTE:
|
||||
ftp_state(data, ftpc, FTP_LIST_TYPE);
|
||||
result = ftp_state_list(data, ftpc, ftp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2209,6 +2224,8 @@ static CURLcode ftp_state_type_resp(struct Curl_easy *data,
|
||||
result = ftp_state_retr_prequote(data, ftpc, ftp);
|
||||
else if(instate == FTP_STOR_TYPE)
|
||||
result = ftp_state_stor_prequote(data, ftpc, ftp);
|
||||
else if(instate == FTP_RETR_LIST_TYPE)
|
||||
result = ftp_state_list_prequote(data, ftpc, ftp);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -3013,6 +3030,7 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data,
|
||||
case FTP_POSTQUOTE:
|
||||
case FTP_RETR_PREQUOTE:
|
||||
case FTP_STOR_PREQUOTE:
|
||||
case FTP_LIST_PREQUOTE:
|
||||
if((ftpcode >= 400) && !ftpc->count2) {
|
||||
/* failure response code, and not allowed to fail */
|
||||
failf(data, "QUOT command failed with %03d", ftpcode);
|
||||
@ -3082,6 +3100,7 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data,
|
||||
case FTP_LIST_TYPE:
|
||||
case FTP_RETR_TYPE:
|
||||
case FTP_STOR_TYPE:
|
||||
case FTP_RETR_LIST_TYPE:
|
||||
result = ftp_state_type_resp(data, ftpc, ftp, ftpcode, ftpc->state);
|
||||
break;
|
||||
|
||||
@ -3686,7 +3705,8 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
|
||||
if(result)
|
||||
;
|
||||
else if(data->state.list_only || !ftpc->file) {
|
||||
else if((data->state.list_only || !ftpc->file) &&
|
||||
!(data->set.prequote)) {
|
||||
/* The specified path ends with a slash, and therefore we think this
|
||||
is a directory that is requested, use LIST. But before that we
|
||||
need to set ASCII transfer mode. */
|
||||
@ -3700,8 +3720,14 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
/* otherwise just fall through */
|
||||
}
|
||||
else {
|
||||
result = ftp_nb_type(data, ftpc, ftp, data->state.prefer_ascii,
|
||||
FTP_RETR_TYPE);
|
||||
if(data->set.prequote && !ftpc->file) {
|
||||
result = ftp_nb_type(data, ftpc, ftp, TRUE,
|
||||
FTP_RETR_LIST_TYPE);
|
||||
}
|
||||
else {
|
||||
result = ftp_nb_type(data, ftpc, ftp, data->state.prefer_ascii,
|
||||
FTP_RETR_TYPE);
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -62,12 +62,14 @@ enum {
|
||||
FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
|
||||
FTP_RETR_PREQUOTE,
|
||||
FTP_STOR_PREQUOTE,
|
||||
FTP_LIST_PREQUOTE,
|
||||
FTP_POSTQUOTE,
|
||||
FTP_CWD, /* change dir */
|
||||
FTP_MKD, /* if the dir did not exist */
|
||||
FTP_MDTM, /* to figure out the datestamp */
|
||||
FTP_TYPE, /* to set type when doing a head-like request */
|
||||
FTP_LIST_TYPE, /* set type when about to do a dir list */
|
||||
FTP_RETR_LIST_TYPE,
|
||||
FTP_RETR_TYPE, /* set type when about to RETR a file */
|
||||
FTP_STOR_TYPE, /* set type when about to STOR a file */
|
||||
FTP_SIZE, /* get the remote file's size for head-like request */
|
||||
|
||||
@ -108,7 +108,7 @@ test718 test719 test720 test721 test722 test723 test724 test725 test726 \
|
||||
test727 test728 test729 test730 test731 test732 test733 test734 test735 \
|
||||
test736 test737 test738 test739 test740 test741 test742 test743 test744 \
|
||||
test745 test746 test747 test748 test749 test750 test751 test752 test753 \
|
||||
\
|
||||
test754 \
|
||||
test780 test781 test782 test783 test784 test785 test786 test787 test788 \
|
||||
test789 test790 test791 \
|
||||
\
|
||||
|
||||
64
tests/data/test754
Normal file
64
tests/data/test754
Normal file
@ -0,0 +1,64 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
FTP
|
||||
list
|
||||
post-quote
|
||||
pre-quote
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<data mode="text">
|
||||
total 20
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
|
||||
drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
|
||||
-r--r--r-- 1 0 1 35 Jul 16 1996 README
|
||||
lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
|
||||
dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
|
||||
drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
|
||||
dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
|
||||
drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
|
||||
dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
|
||||
</data>
|
||||
<servercmd>
|
||||
REPLY FAIL 500 this might not be a failure!
|
||||
</servercmd>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
ftp
|
||||
</server>
|
||||
<name>
|
||||
FTP list with quote ops
|
||||
</name>
|
||||
<command>
|
||||
ftp://%HOSTIP:%FTPPORT/path/ -Q "NOOP 1" -Q "+NOOP 2" -Q "-NOOP 3" -Q "*FAIL" -Q "+*FAIL HARD"
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<strip>
|
||||
QUIT
|
||||
</strip>
|
||||
<protocol>
|
||||
USER anonymous
|
||||
PASS ftp@example.com
|
||||
PWD
|
||||
NOOP 1
|
||||
FAIL
|
||||
CWD path
|
||||
EPSV
|
||||
TYPE A
|
||||
NOOP 2
|
||||
FAIL HARD
|
||||
LIST
|
||||
NOOP 3
|
||||
QUIT
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
||||
Loading…
Reference in New Issue
Block a user