mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
Added EPSV which is now unconditionally always tried before PASV, which
makes it work reaaaaly nicely on IPv6-enabled hosts! Added SIZE before RETR is made, always done on downloads. It makes us know the size prior to download much more frequently. Unfortunately, this breaks all the FTP test cases. *fixfixfix*
This commit is contained in:
parent
aff19f64b5
commit
f0d3fccd4b
46
lib/ftp.c
46
lib/ftp.c
@ -1269,20 +1269,23 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
|||||||
|
|
||||||
LPSV is RFC1639, expect:
|
LPSV is RFC1639, expect:
|
||||||
228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)
|
228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)
|
||||||
(Is this actually supported *anywhere*?)
|
|
||||||
|
|
||||||
EPSV is RFC2428, expect:
|
EPSV is RFC2428, expect:
|
||||||
229 Entering Extended Passive Mode (|||port|)
|
229 Entering Extended Passive Mode (|||port|)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
const char *mode[] = { "EPSV", "PASV", NULL };
|
||||||
|
int results[] = { 229, 227, 0 };
|
||||||
|
#else
|
||||||
#if 0
|
#if 0
|
||||||
/* no support for IPv6 passive mode yet */
|
|
||||||
char *mode[] = { "EPSV", "LPSV", "PASV", NULL };
|
char *mode[] = { "EPSV", "LPSV", "PASV", NULL };
|
||||||
int results[] = { 229, 228, 227, 0 };
|
int results[] = { 229, 228, 227, 0 };
|
||||||
#else
|
#else
|
||||||
const char *mode[] = { "PASV", NULL };
|
const char *mode[] = { "PASV", NULL };
|
||||||
int results[] = { 227, 0 };
|
int results[] = { 227, 0 };
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
int modeoff;
|
int modeoff;
|
||||||
unsigned short connectport; /* the local port connect() should use! */
|
unsigned short connectport; /* the local port connect() should use! */
|
||||||
@ -1292,13 +1295,15 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
|||||||
/* newhost must be able to hold a full IP-style address in ASCII, which
|
/* newhost must be able to hold a full IP-style address in ASCII, which
|
||||||
in the IPv6 case means 5*8-1 = 39 letters */
|
in the IPv6 case means 5*8-1 = 39 letters */
|
||||||
char newhost[48];
|
char newhost[48];
|
||||||
|
char *newhostp=NULL;
|
||||||
|
|
||||||
for (modeoff = 0; mode[modeoff]; modeoff++) {
|
for (modeoff = 0; mode[modeoff]; modeoff++) {
|
||||||
FTPSENDF(conn, mode[modeoff], "");
|
result = Curl_ftpsendf(conn, mode[modeoff]);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
|
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
|
||||||
if(nread < 0)
|
if(nread < 0)
|
||||||
return CURLE_OPERATION_TIMEOUTED;
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
|
|
||||||
if (ftpcode == results[modeoff])
|
if (ftpcode == results[modeoff])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1337,13 +1342,10 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||||
|
newhostp = newhost;
|
||||||
newport = (port[0]<<8) + port[1];
|
newport = (port[0]<<8) + port[1];
|
||||||
|
|
||||||
/* we should compare to see if this is the same IP like the one
|
|
||||||
we're already connected to, as then we can skip the name function
|
|
||||||
call below, in similar style that we do for the EPSV reply */
|
|
||||||
}
|
}
|
||||||
#if 0
|
#if 1
|
||||||
else if (229 == results[modeoff]) {
|
else if (229 == results[modeoff]) {
|
||||||
char *ptr = strchr(buf, '(');
|
char *ptr = strchr(buf, '(');
|
||||||
if(ptr) {
|
if(ptr) {
|
||||||
@ -1360,7 +1362,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
|||||||
newport = num;
|
newport = num;
|
||||||
|
|
||||||
/* we should use the same host we already are connected to */
|
/* we should use the same host we already are connected to */
|
||||||
addr = conn->hostaddr;
|
newhostp = conn->name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ptr=NULL;
|
ptr=NULL;
|
||||||
@ -1384,9 +1386,9 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
|||||||
connectport =
|
connectport =
|
||||||
(unsigned short)conn->port; /* we connect to the proxy's port */
|
(unsigned short)conn->port; /* we connect to the proxy's port */
|
||||||
}
|
}
|
||||||
else if(!addr) {
|
else {
|
||||||
/* normal, direct, ftp connection */
|
/* normal, direct, ftp connection */
|
||||||
addr = Curl_getaddrinfo(data, newhost, newport, &hostdataptr);
|
addr = Curl_getaddrinfo(data, newhostp, newport, &hostdataptr);
|
||||||
if(!addr) {
|
if(!addr) {
|
||||||
failf(data, "Can't resolve new host %s", newhost);
|
failf(data, "Can't resolve new host %s", newhost);
|
||||||
return CURLE_FTP_CANT_GET_HOST;
|
return CURLE_FTP_CANT_GET_HOST;
|
||||||
@ -1719,22 +1721,32 @@ CURLcode ftp_perform(struct connectdata *conn)
|
|||||||
(data->set.ftp_list_only?"NLST":"LIST"));
|
(data->set.ftp_list_only?"NLST":"LIST"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
ssize_t foundsize;
|
||||||
|
|
||||||
/* Set type to binary (unless specified ASCII) */
|
/* Set type to binary (unless specified ASCII) */
|
||||||
result = ftp_transfertype(conn, data->set.ftp_ascii);
|
result = ftp_transfertype(conn, data->set.ftp_ascii);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
/* Attempt to get the size, it'll be useful in some cases: for resumed
|
||||||
|
downloads and when talking to servers that don't give away the size
|
||||||
|
in the RETR response line. */
|
||||||
|
result = ftp_getsize(conn, ftp->file, &foundsize);
|
||||||
|
if(CURLE_OK == result)
|
||||||
|
downloadsize = foundsize;
|
||||||
|
|
||||||
if(conn->resume_from) {
|
if(conn->resume_from) {
|
||||||
|
|
||||||
/* Daniel: (August 4, 1999)
|
/* Daniel: (August 4, 1999)
|
||||||
*
|
*
|
||||||
* We start with trying to use the SIZE command to figure out the size
|
* We start with trying to use the SIZE command to figure out the size
|
||||||
* of the file we're gonna get. If we can get the size, this is by far
|
* of the file we're gonna get. If we can get the size, this is by far
|
||||||
* the best way to know if we're trying to resume beyond the EOF. */
|
* the best way to know if we're trying to resume beyond the EOF.
|
||||||
ssize_t foundsize;
|
*
|
||||||
|
* Daniel, November 28, 2001. We *always* get the size on downloads
|
||||||
result = ftp_getsize(conn, ftp->file, &foundsize);
|
* now, so it is done before this even when not doing resumes. I saved
|
||||||
|
* the comment above for nostalgical reasons! ;-)
|
||||||
|
*/
|
||||||
if(CURLE_OK != result) {
|
if(CURLE_OK != result) {
|
||||||
infof(data, "ftp server doesn't support SIZE\n");
|
infof(data, "ftp server doesn't support SIZE\n");
|
||||||
/* We couldn't get the size and therefore we can't know if there
|
/* We couldn't get the size and therefore we can't know if there
|
||||||
|
Loading…
Reference in New Issue
Block a user