From: serassio <> Date: Sun, 30 Jan 2005 02:14:08 +0000 (+0000) Subject: Bug #1194: FTP data connection fails on some FTP servers when requesting X-Git-Tag: SQUID_3_0_PRE4~888 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=18ed7c61d2012122353c64dd058e7207c7d23e26;p=thirdparty%2Fsquid.git Bug #1194: FTP data connection fails on some FTP servers when requesting directory without a trailing slash This patch simplifies FTP data connection management to always reopen a new connection after a failed FTP request. Forward port of 2.5 patch. --- diff --git a/src/ftp.cc b/src/ftp.cc index a2c324f997..b3ac65d5d8 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.358 2004/05/31 23:17:51 hno Exp $ + * $Id: ftp.cc,v 1.359 2005/01/29 19:14:08 serassio Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -125,9 +125,6 @@ unsigned int put_mkdir: unsigned int listformat_unknown: 1; - -unsigned int datachannel_hack: - 1; }; class FtpStateData @@ -1184,8 +1181,11 @@ ftpDataRead(int fd, char *buf, size_t len, comm_err_t errflag, int xerrno, void IOStats.Ftp.read_hist[bin]++; } - if (ftpState->flags.isdir && !ftpState->flags.html_header_sent && len >= 0) { - ftpListingStart(ftpState); + if (!ftpState->flags.http_header_sent && len >= 0) { + ftpAppendSuccessHeader(ftpState); + + if (ftpState->flags.isdir) + ftpListingStart(ftpState); } if (errflag != COMM_OK || len < 0) { @@ -1201,6 +1201,11 @@ ftpDataRead(int fd, char *buf, size_t len, comm_err_t errflag, int xerrno, void comm_read(fd, ftpState->data.buf + ftpState->data.offset, read_sz, ftpDataRead, data); } else { + if (!ftpState->flags.http_header_sent && !ftpState->fwd->flags.ftp_pasv_failed && ftpState->flags.pasv_supported) { + ftpState->fwd->flags.dont_retry = 0; /* this is a retryable error */ + ftpState->fwd->flags.ftp_pasv_failed = 1; + } + ftpFailed(ftpState, ERR_READ_ERROR, 0); /* ftpFailed closes ctrl.fd and frees ftpState */ return; @@ -1371,11 +1376,7 @@ ftpStart(FwdState * fwd) ftpState->size = -1; ftpState->mdtm = -1; - if (!Config.Ftp.passive) - ftpState->flags.rest_supported = 0; - else if (fwd->flags.ftp_pasv_failed) - ftpState->flags.pasv_supported = 0; - else + if (Config.Ftp.passive && !fwd->flags.ftp_pasv_failed) ftpState->flags.pasv_supported = 1; ftpState->flags.rest_supported = 1; @@ -2123,15 +2124,9 @@ ftpSendPasv(FtpStateData * ftpState) } if (ftpState->data.fd >= 0) { - if (!ftpState->flags.datachannel_hack) { - /* We are already connected, reuse this connection. */ - ftpRestOrList(ftpState); - return; - } else { - /* Close old connection */ - comm_close(ftpState->data.fd); - ftpState->data.fd = -1; - } + /* Close old connection */ + comm_close(ftpState->data.fd); + ftpState->data.fd = -1; } if (!ftpState->flags.pasv_supported) { @@ -2617,7 +2612,6 @@ ftpReadList(FtpStateData * ftpState) if (code == 125 || (code == 150 && ftpState->data.host)) { /* Begin data transfer */ - ftpAppendSuccessHeader(ftpState); /* XXX what about Config.Timeout.read? */ assert(ftpState->data.offset == 0); ftpState->entry->delayAwareRead(ftpState->data.fd, ftpState->data.buf, ftpState->data.size, ftpDataRead, ftpState); @@ -2665,7 +2659,6 @@ ftpReadRetr(FtpStateData * ftpState) if (code == 125 || (code == 150 && ftpState->data.host)) { /* Begin data transfer */ debug(9, 3) ("ftpReadRetr: reading data channel\n"); - ftpAppendSuccessHeader(ftpState); /* XXX what about Config.Timeout.read? */ size_t read_sz = ftpState->data.size - ftpState->data.offset; @@ -2830,31 +2823,6 @@ ftpTrySlashHack(FtpStateData * ftpState) ftpGetFile(ftpState); } -static void -ftpTryDatachannelHack(FtpStateData * ftpState) -{ - ftpState->flags.datachannel_hack = 1; - /* we have to undo some of the slash hack... */ - - if (ftpState->old_filepath != NULL) { - ftpState->flags.try_slash_hack = 0; - safe_free(ftpState->filepath); - ftpState->filepath = ftpState->old_filepath; - ftpState->old_filepath = NULL; - } - - ftpState->flags.tried_nlst = 0; - /* And off we go */ - - if (ftpState->flags.isdir) { - ftpListDir(ftpState); - } else { - ftpGetFile(ftpState); - } - - return; -} - /* Forget hack status. Next error is shown to the user */ static void ftpUnhack(FtpStateData * ftpState) @@ -2912,25 +2880,6 @@ ftpFail(FtpStateData * ftpState) } } - /* Try to reopen datachannel */ - if (!ftpState->flags.datachannel_hack && - ftpState->pathcomps == NULL) { - switch (ftpState->state) { - - case SENT_RETR: - - case SENT_LIST: - - case SENT_NLST: - /* Try to reopen datachannel */ - ftpHackShortcut(ftpState, ftpTryDatachannelHack); - return; - - default: - break; - } - } - ftpFailed(ftpState, ERR_NONE, 0); /* ftpFailed closes ctrl.fd and frees ftpState */ }