mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 15:48:49 -05:00
- Ingmar Runge enhanced libcurl's FTP engine to support the PRET command. This
command is a special "hack" used by the drftpd server, but even though it is a custom extension I've deemed it fine to add to libcurl since this server seems to survive and people keep using it and want libcurl to support it. The new libcurl option is named CURLOPT_FTP_USE_PRET, and it is also usable from the curl tool with --ftp-pret. Using this option on a server that doesn't support this command will make libcurl fail.
This commit is contained in:
parent
42d365f199
commit
605bbfc4c0
14
CHANGES
14
CHANGES
@ -6,6 +6,20 @@
|
||||
|
||||
Changelog
|
||||
|
||||
Daniel Stenberg (1 Jan 2010)
|
||||
- Ingmar Runge enhanced libcurl's FTP engine to support the PRET command. This
|
||||
command is a special "hack" used by the drftpd server, but even though it is
|
||||
a custom extension I've deemed it fine to add to libcurl since this server
|
||||
seems to survive and people keep using it and want libcurl to support
|
||||
it. The new libcurl option is named CURLOPT_FTP_USE_PRET, and it is also
|
||||
usable from the curl tool with --ftp-pret. Using this option on a server
|
||||
that doesn't support this command will make libcurl fail.
|
||||
|
||||
I added test cases 1107 and 1108 to verify the functionality.
|
||||
|
||||
The PRET command is documented at
|
||||
http://www.drftpd.org/index.php/Distributed_PASV
|
||||
|
||||
Yang Tse (30 Dec 2009)
|
||||
- Steven M. Schweda improved VMS build system, and Craig A. Berry helped
|
||||
with the patch and testing.
|
||||
|
@ -1,8 +1,8 @@
|
||||
Curl and libcurl 7.20.0
|
||||
|
||||
Public curl releases: 114
|
||||
Command line options: 134
|
||||
curl_easy_setopt() options: 165
|
||||
Command line options: 135
|
||||
curl_easy_setopt() options: 166
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 761
|
||||
@ -16,6 +16,7 @@ This release includes the following changes:
|
||||
o added support for IMAP, POP3 and SMTP transfers
|
||||
o added --mail-from and --mail-rcpt for SMTP
|
||||
o VMS build system enhancements
|
||||
o added support for the PRET ftp command
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
@ -50,6 +51,6 @@ advice from friends like these:
|
||||
Marco Maggi, Camille Moncelier, Claes Jakobsson, Kevin Baughman,
|
||||
Marc Kleine-Budde, Jad Chamcham, Bjorn Augustsson, David Byron,
|
||||
Markus Koetter, Chad Monroe, Martin Storsjo, Siegfried Gyuricsko,
|
||||
Jon Nelson, Julien Chaffraix, Renato Botelho, Peter Pentchev
|
||||
Jon Nelson, Julien Chaffraix, Renato Botelho, Peter Pentchev, Ingmar Runge
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
@ -461,6 +461,11 @@ will re-use the same IP address it already uses for the control
|
||||
connection. (Added in 7.14.2)
|
||||
|
||||
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
|
||||
.IP "--ftp-pret"
|
||||
(FTP) Tell curl to send a PRET command before PASV (and EPSV). Certain
|
||||
FTP servers, mainly drftpd, require this non-standard command for
|
||||
directory listings as well as up and downloads in PASV mode.
|
||||
(Added in 7.20.x)
|
||||
.IP "--ftp-ssl"
|
||||
(FTP) Try to use SSL/TLS for the FTP connection. Reverts to a non-secure
|
||||
connection if the server doesn't support SSL/TLS. See also
|
||||
|
@ -1160,6 +1160,12 @@ means that it will first attempt to use EPSV before using PASV, but if you
|
||||
pass zero to this option, it will not try using EPSV, only plain PASV.
|
||||
|
||||
If the server is an IPv6 host, this option will have no effect as of 7.12.3.
|
||||
.IP CURLOPT_FTP_USE_PRET
|
||||
Pass a long. If the value is 1, it tells curl to send a PRET command
|
||||
before PASV (and EPSV). Certain FTP servers, mainly drftpd, require this
|
||||
non-standard command for directory listings as well as up and downloads in
|
||||
PASV mode. Has no effect when using the active FTP transfers mode.
|
||||
(Added in 7.20.x)
|
||||
.IP CURLOPT_FTP_CREATE_MISSING_DIRS
|
||||
Pass a long. If the value is 1, curl will attempt to create any remote
|
||||
directory that it fails to CWD into. CWD is the command that changes working
|
||||
|
@ -70,6 +70,10 @@ either a PASV or a EPSV command. The server is flawed.
|
||||
.IP "CURLE_FTP_WEIRD_227_FORMAT (14)"
|
||||
FTP servers return a 227-line as a response to a PASV command. If libcurl
|
||||
fails to parse that line, this return code is passed back.
|
||||
.IP "CURLE_FTP_PRET_FAILED (84)"
|
||||
The FTP server does not understand the PRET command at all or does not
|
||||
support the given argument. Be careful when using \fICURLOPT_CUSTOMREQUEST\fP,
|
||||
a custom LIST command will be sent with PRET CMD before PASV as well.
|
||||
.IP "CURLE_FTP_CANT_GET_HOST (15)"
|
||||
An internal failure to lookup the host used for the new connection.
|
||||
.IP "CURLE_FTP_COULDNT_SET_TYPE (17)"
|
||||
|
@ -413,6 +413,7 @@ typedef enum {
|
||||
wrong format (Added in 7.19.0) */
|
||||
CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in
|
||||
7.19.0) */
|
||||
CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
|
||||
@ -1291,6 +1292,9 @@ typedef enum {
|
||||
/* set the SMTP mail receiver(s) */
|
||||
CINIT(MAIL_RCPT, OBJECTPOINT, 187),
|
||||
|
||||
/* FTP: send PRET before PASV */
|
||||
CINIT(FTP_USE_PRET, LONG, 188),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
|
30
lib/ftp.c
30
lib/ftp.c
@ -565,6 +565,7 @@ static void state(struct connectdata *conn,
|
||||
"REST",
|
||||
"RETR_REST",
|
||||
"PORT",
|
||||
"PRET",
|
||||
"PASV",
|
||||
"LIST",
|
||||
"RETR",
|
||||
@ -1090,7 +1091,25 @@ static CURLcode ftp_state_post_rest(struct connectdata *conn)
|
||||
}
|
||||
else {
|
||||
/* We have chosen (this is default) to use the PASV (or similar) command */
|
||||
result = ftp_state_use_pasv(conn);
|
||||
if(data->set.ftp_use_pret) {
|
||||
/* The user has requested that we send a PRET command
|
||||
to prepare the server for the upcoming PASV */
|
||||
if(!conn->proto.ftpc.file) {
|
||||
PPSENDF(&conn->proto.ftpc.pp, "PRET %s", data->set.str[STRING_CUSTOMREQUEST]?
|
||||
data->set.str[STRING_CUSTOMREQUEST]:
|
||||
(data->set.ftp_list_only?"NLST":"LIST"));
|
||||
}
|
||||
else if(data->set.upload) {
|
||||
PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
|
||||
}
|
||||
else {
|
||||
PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file);
|
||||
}
|
||||
state(conn, FTP_PRET);
|
||||
}
|
||||
else {
|
||||
result = ftp_state_use_pasv(conn);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2710,6 +2729,15 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
result = ftp_state_rest_resp(conn, ftpcode, ftpc->state);
|
||||
break;
|
||||
|
||||
case FTP_PRET:
|
||||
if(ftpcode != 200) {
|
||||
/* there only is this one standard OK return code. */
|
||||
failf(data, "PRET command not accepted: %03d", ftpcode);
|
||||
return CURLE_FTP_PRET_FAILED;
|
||||
}
|
||||
result = ftp_state_use_pasv(conn);
|
||||
break;
|
||||
|
||||
case FTP_PASV:
|
||||
result = ftp_state_pasv_resp(conn, ftpcode);
|
||||
break;
|
||||
|
@ -79,6 +79,7 @@ typedef enum {
|
||||
FTP_REST, /* when used to check if the server supports it in head-like */
|
||||
FTP_RETR_REST, /* when asking for "resume" in for RETR */
|
||||
FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
|
||||
FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */
|
||||
FTP_PASV, /* generic state for PASV and EPSV, check count1 */
|
||||
FTP_LIST, /* generic state for LIST, NLST or a custom list command */
|
||||
FTP_RETR,
|
||||
|
@ -81,6 +81,9 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_REMOTE_ACCESS_DENIED:
|
||||
return "Access denied to remote resource";
|
||||
|
||||
case CURLE_FTP_PRET_FAILED:
|
||||
return "FTP: The server did not accept the PRET command.";
|
||||
|
||||
case CURLE_FTP_WEIRD_PASS_REPLY:
|
||||
return "FTP: unknown PASS reply";
|
||||
|
||||
|
@ -701,6 +701,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
|
||||
set->httpreq = HTTPREQ_GET; /* Default HTTP request */
|
||||
set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
|
||||
set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
|
||||
set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
|
||||
set->ftp_filemethod = FTPFILE_MULTICWD;
|
||||
|
||||
set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
|
||||
@ -1563,6 +1564,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long));
|
||||
break;
|
||||
|
||||
case CURLOPT_FTP_USE_PRET:
|
||||
data->set.ftp_use_pret = (bool)(0 != va_arg(param, long));
|
||||
break;
|
||||
|
||||
case CURLOPT_FTP_SSL_CCC:
|
||||
data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
|
||||
break;
|
||||
|
@ -1308,6 +1308,7 @@ struct UserDefined {
|
||||
bool reuse_fresh; /* do not re-use an existing connection */
|
||||
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
|
||||
bool ftp_use_eprt; /* if EPRT is to be attempted or not */
|
||||
bool ftp_use_pret; /* if PRET is to be used before PASV or not */
|
||||
|
||||
curl_usessl ftp_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
|
||||
IMAP or POP3 or others! */
|
||||
|
10
src/main.c
10
src/main.c
@ -477,6 +477,7 @@ struct Configurable {
|
||||
bool resume_from_current;
|
||||
bool disable_epsv;
|
||||
bool disable_eprt;
|
||||
bool ftp_pret;
|
||||
curl_off_t resume_from;
|
||||
char *postfields;
|
||||
curl_off_t postfieldsize;
|
||||
@ -794,6 +795,7 @@ static void help(void)
|
||||
" --ftp-pasv Use PASV/EPSV instead of PORT (F)",
|
||||
" -P/--ftp-port <address> Use PORT with address instead of PASV (F)",
|
||||
" --ftp-skip-pasv-ip Skip the IP address for PASV (F)\n"
|
||||
" --ftp-pret Send PRET before PASV (for drftpd) (F)",
|
||||
" --ftp-ssl Try SSL/TLS for ftp transfer (F)",
|
||||
" --ftp-ssl-ccc Send CCC after authenticating (F)",
|
||||
" --ftp-ssl-ccc-mode [active/passive] Set CCC mode (F)",
|
||||
@ -1746,6 +1748,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
{"$9", "tftp-blksize", TRUE},
|
||||
{"$A", "mail-from", TRUE},
|
||||
{"$B", "mail-rcpt", TRUE},
|
||||
{"$C", "ftp-pret", FALSE},
|
||||
{"0", "http1.0", FALSE},
|
||||
{"1", "tlsv1", FALSE},
|
||||
{"2", "sslv2", FALSE},
|
||||
@ -2284,6 +2287,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
if(err)
|
||||
return err;
|
||||
break;
|
||||
case 'C': /* --ftp-pret */
|
||||
config->ftp_pret = toggle;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '#': /* --progress-bar */
|
||||
@ -5032,6 +5038,10 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
|
||||
if(config->mail_rcpt)
|
||||
my_setopt_str(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt);
|
||||
|
||||
/* curl 7.20.x */
|
||||
if(config->ftp_pret)
|
||||
my_setopt(curl, CURLOPT_FTP_USE_PRET, TRUE);
|
||||
|
||||
retry_numretries = config->req_retry;
|
||||
|
||||
retrystart = cutil_tvnow();
|
||||
|
@ -63,7 +63,8 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
|
||||
test1089 test1090 test1091 test1092 test1093 test1094 test1095 test1096 \
|
||||
test1097 test560 test561 test1098 test1099 test562 test563 test1100 \
|
||||
test564 test1101 test1102 test1103 test1104 test299 test310 test311 \
|
||||
test312 test1105 test565 test800 test1106 test801 test566 test802 test803
|
||||
test312 test1105 test565 test800 test1106 test801 test566 test802 test803 \
|
||||
test1107 test1108
|
||||
|
||||
filecheck:
|
||||
@mkdir test-place; \
|
||||
|
53
tests/data/test1107
Normal file
53
tests/data/test1107
Normal file
@ -0,0 +1,53 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
FTP
|
||||
PASV
|
||||
RETR
|
||||
PRET
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
data
|
||||
to
|
||||
see
|
||||
that FTP
|
||||
works
|
||||
so does it?
|
||||
</data>
|
||||
<servercmd>
|
||||
REPLY PRET 200 fine
|
||||
</servercmd>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
ftp
|
||||
</server>
|
||||
<name>
|
||||
FTP RETR PASV with PRET
|
||||
</name>
|
||||
<command>
|
||||
ftp://%HOSTIP:%FTPPORT/1107 --ftp-pret
|
||||
</command>
|
||||
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
USER anonymous
|
||||
PASS ftp@example.com
|
||||
PWD
|
||||
PRET RETR 1107
|
||||
EPSV
|
||||
TYPE I
|
||||
SIZE 1107
|
||||
RETR 1107
|
||||
QUIT
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
45
tests/data/test1108
Normal file
45
tests/data/test1108
Normal file
@ -0,0 +1,45 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
FTP
|
||||
PASV
|
||||
RETR
|
||||
PRET
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
|
||||
<servercmd>
|
||||
REPLY PRET 550 unkown command
|
||||
</servercmd>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
ftp
|
||||
</server>
|
||||
<name>
|
||||
FTP RETR PASV with PRET not supported
|
||||
</name>
|
||||
<command>
|
||||
ftp://%HOSTIP:%FTPPORT/1108 --ftp-pret
|
||||
</command>
|
||||
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
USER anonymous
|
||||
PASS ftp@example.com
|
||||
PWD
|
||||
PRET RETR 1108
|
||||
</protocol>
|
||||
# we expect that the server doesn't understand PRET
|
||||
<errorcode>
|
||||
84
|
||||
</errorcode>
|
||||
</verify>
|
||||
</testcase>
|
Loading…
Reference in New Issue
Block a user