From: Vitaly Lavrov Date: Tue, 13 Oct 2015 12:53:10 +0000 (-0700) Subject: Bug 4279: No response from proxy for FTP-download of non-existing file X-Git-Tag: SQUID_4_0_1~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cd4d5d45ab6f388b367542042c14028681cec9ea;p=thirdparty%2Fsquid.git Bug 4279: No response from proxy for FTP-download of non-existing file --- diff --git a/src/clients/FtpClient.cc b/src/clients/FtpClient.cc index 7720ae1b1f..43dfad0117 100644 --- a/src/clients/FtpClient.cc +++ b/src/clients/FtpClient.cc @@ -242,13 +242,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; @@ -273,10 +283,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 3de1ccad8a..44544ee464 100644 --- a/src/clients/FtpClient.h +++ b/src/clients/FtpClient.h @@ -98,7 +98,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 = nullptr); /// read timeout handler virtual void timeout(const CommTimeoutCbParams &io); diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc index 526223f021..443ef79bbe 100644 --- a/src/clients/FtpGateway.cc +++ b/src/clients/FtpGateway.cc @@ -1227,7 +1227,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) { @@ -1245,34 +1244,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; @@ -2413,7 +2391,11 @@ static void ftpFail(Ftp::Gateway *ftpState) { const bool slashHack = ftpState->request->url.path().caseCmp("/%2f", 4)==0; - debugs(9, 6, "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 << @@ -2438,8 +2420,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