]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 4279: No response from proxy for FTP-download of non-existing file
authorVitaly Lavrov <vel21ripn@gmail.com>
Tue, 13 Oct 2015 12:53:10 +0000 (05:53 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Tue, 13 Oct 2015 12:53:10 +0000 (05:53 -0700)
src/clients/FtpClient.cc
src/clients/FtpClient.h
src/clients/FtpGateway.cc

index 7720ae1b1f35bb3174ffab0a58e46d0cfe1531a4..43dfad01172b43a959902fefbb48f1dd456586af 100644 (file)
@@ -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
index 3de1ccad8abe19a7d00fea694b695fcae25ad763..44544ee464ecfc2d14a0922b95321f070c0d74f4 100644 (file)
@@ -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);
index 526223f0217722f97092268b7659c5bf6b9cd334..443ef79bbeaa0f6d8ad75dc702dcd5fc0e4144aa 100644 (file)
@@ -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 <yourpassword>";
-
-    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