From a319aa6d415e85f3260066c5cc3ab5bfef7dcb11 Mon Sep 17 00:00:00 2001 From: Vitaly Lavrov Date: Tue, 13 Oct 2015 23:44:45 -0700 Subject: [PATCH] Bug 4279: No response from proxy for FTP-download of non-existing file --- src/clients/FtpClient.cc | 25 ++++++++++++++++------- src/clients/FtpClient.h | 3 ++- src/clients/FtpGateway.cc | 43 +++++++++++++++------------------------ 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/clients/FtpClient.cc b/src/clients/FtpClient.cc index a262eea3ac..65b864d2af 100644 --- a/src/clients/FtpClient.cc +++ b/src/clients/FtpClient.cc @@ -243,13 +243,23 @@ Ftp::Client::doneWithServer() const } void -Ftp::Client::failed(err_type error, int xerrno) +Ftp::Client::failed(err_type error, int xerrno, ErrorState *err) { debugs(9, 3, "entry-null=" << (entry?entry->isEmpty():0) << ", entry=" << entry); const char *command, *reply; - const Http::StatusCode httpStatus = failedHttpStatus(error); - ErrorState *const ftperr = new ErrorState(error, httpStatus, fwd->request); + ErrorState *ftperr; + + if (err) { + debugs(9, 6, "error=" << err->type << ", code=" << xerrno << + ", status=" << err->httpStatus); + error = err->type; + ftperr = err; + } else { + Http::StatusCode httpStatus = failedHttpStatus(error); + ftperr = new ErrorState(error, httpStatus, fwd->request); + } + ftperr->xerrno = xerrno; ftperr->ftp.server_msg = ctrl.message; @@ -274,10 +284,11 @@ Ftp::Client::failed(err_type error, int xerrno) if (reply) ftperr->ftp.reply = xstrdup(reply); - fwd->request->detailError(error, xerrno); - fwd->fail(ftperr); - - closeServer(); // we failed, so no serverComplete() + if (!err) { + fwd->request->detailError(error, xerrno); + fwd->fail(ftperr); + closeServer(); // we failed, so no serverComplete() + } } Http::StatusCode diff --git a/src/clients/FtpClient.h b/src/clients/FtpClient.h index ef2aa9859b..ab110fe2c5 100644 --- a/src/clients/FtpClient.h +++ b/src/clients/FtpClient.h @@ -96,7 +96,8 @@ public: virtual ~Client(); /// handle a fatal transaction error, closing the control connection - virtual void failed(err_type error = ERR_NONE, int xerrno = 0); + virtual void failed(err_type error = ERR_NONE, int xerrno = 0, + ErrorState *ftperr = NULL); /// read timeout handler virtual void timeout(const CommTimeoutCbParams &io); diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc index 524eebbf07..d2cc6217c5 100644 --- a/src/clients/FtpGateway.cc +++ b/src/clients/FtpGateway.cc @@ -1246,7 +1246,6 @@ void Ftp::Gateway::loginFailed() { ErrorState *err = NULL; - const char *command, *reply; if ((state == SENT_USER || state == SENT_PASS) && ctrl.replycode >= 400) { if (ctrl.replycode == 421 || ctrl.replycode == 426) { @@ -1264,34 +1263,13 @@ Ftp::Gateway::loginFailed() } } - // any other problems are general falures. if (!err) { ftpFail(this); return; } - err->ftp.server_msg = ctrl.message; - - ctrl.message = NULL; - - if (old_request) - command = old_request; - else - command = ctrl.last_command; - - if (command && strncmp(command, "PASS", 4) == 0) - command = "PASS "; - - if (old_reply) - reply = old_reply; - else - reply = ctrl.last_reply; - - if (command) - err->ftp.request = xstrdup(command); - - if (reply) - err->ftp.reply = xstrdup(reply); + failed(ERR_NONE, ctrl.replycode, err); + // any other problems are general falures. HttpReply *newrep = err->BuildHttpReply(); delete err; @@ -2438,7 +2416,11 @@ Ftp::Gateway::hackShortcut(FTPSM * nextState) static void ftpFail(Ftp::Gateway *ftpState) { - debugs(9, 6, HERE << "flags(" << + int code = ftpState->ctrl.replycode; + err_type error_code = ERR_NONE; + + debugs(9, 6, "state " << ftpState->state << + " reply code " << code << "flags(" << (ftpState->flags.isdir?"IS_DIR,":"") << (ftpState->flags.try_slash_hack?"TRY_SLASH_HACK":"") << "), " << "mdtm=" << ftpState->mdtm << ", size=" << ftpState->theSize << @@ -2464,8 +2446,15 @@ ftpFail(Ftp::Gateway *ftpState) } } - ftpState->failed(ERR_NONE, 0); - /* failed() closes ctrl.conn and frees this */ + Http::StatusCode sc = ftpState->failedHttpStatus(error_code); + ErrorState *ftperr = new ErrorState(error_code, sc, ftpState->fwd->request); + ftpState->failed(error_code, code, ftperr); + ftperr->detailError(code); + HttpReply *newrep = ftperr->BuildHttpReply(); + delete ftperr; + + ftpState->entry->replaceHttpReply(newrep); + ftpSendQuit(ftpState); } Http::StatusCode -- 2.47.2