]> granicus.if.org Git - apache/commitdiff
mod_proxy: Ensure network errors detected by the proxy are returned as
authorGraham Leggett <minfrin@apache.org>
Tue, 7 May 2013 20:27:37 +0000 (20:27 +0000)
committerGraham Leggett <minfrin@apache.org>
Tue, 7 May 2013 20:27:37 +0000 (20:27 +0000)
504 Gateway Timout as opposed to 502 Bad Gateway, in order to be
compliant with RFC2616 14.9.4 Cache Revalidation and Reload Controls.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1480058 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/proxy/mod_proxy_ftp.c
modules/proxy/mod_proxy_http.c
modules/proxy/proxy_util.c

diff --git a/CHANGES b/CHANGES
index 66a33756211b729236a8f5bbe05d715a2b839789..c0f607d73b1b1e2392297cb704bd700e0d06b33f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_proxy: Ensure network errors detected by the proxy are returned as
+     504 Gateway Timout as opposed to 502 Bad Gateway, in order to be
+     compliant with RFC2616 14.9.4 Cache Revalidation and Reload Controls.
+     [Graham Leggett, Co-Advisor <coad measurement-factory.com>]
+
   *) mod_cache: Ensure that we don't attempt to replace a cached response
      with an older response as per RFC2616 13.12. [Graham Leggett, Co-Advisor
      <coad measurement-factory.com>]
index b93f58768cc84a1c8f85d82cdb738f11762affc9..6be17c0d9a11c5ad42df1f7d59bf5c4e1e401aa6 100644 (file)
@@ -859,7 +859,11 @@ static int ftp_set_TYPE(char xfer_type, request_rec *r, conn_rec *ftp_ctrl,
     /* 501 Syntax error in parameters or arguments. */
     /* 504 Command not implemented for that parameter. */
     /* 530 Not logged in. */
-    if (rc == -1 || rc == 421) {
+    if (rc == -1) {
+        ret = ap_proxyerror(r, HTTP_GATEWAY_TIME_OUT,
+                             "Error reading from remote server");
+    }
+    else if (rc == 421) {
         ret = ap_proxyerror(r, HTTP_BAD_GATEWAY,
                              "Error reading from remote server");
     }
@@ -891,6 +895,10 @@ static char *ftp_get_PWD(request_rec *r, conn_rec *ftp_ctrl, apr_bucket_brigade
     /* 550 Requested action not taken. */
     switch (proxy_ftp_command("PWD" CRLF, r, ftp_ctrl, bb, &ftpmessage)) {
         case -1:
+            ap_proxyerror(r, HTTP_GATEWAY_TIME_OUT,
+                             "Failed to read PWD on ftp server");
+            break;
+
         case 421:
         case 550:
             ap_proxyerror(r, HTTP_BAD_GATEWAY,
@@ -1140,7 +1148,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
      * them until we get a successful connection
      */
     if (APR_SUCCESS != err) {
-        return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p,
+        return ap_proxyerror(r, HTTP_GATEWAY_TIME_OUT, apr_pstrcat(p,
                                                  "DNS lookup failure for: ",
                                                         connectname, NULL));
     }
@@ -1212,10 +1220,15 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
     /* 220 Service ready for new user. */
     /* 421 Service not available, closing control connection. */
     rc = proxy_ftp_command(NULL, r, origin, bb, &ftpmessage);
-    if (rc == -1 || rc == 421) {
-        return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, "Error reading from remote server");
+    if (rc == -1) {
+        return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                "Error reading from remote server");
+    }
+    else if (rc == 421) {
+        return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
+                "Error reading from remote server");
     }
-    if (rc == 120) {
+    else if (rc == 120) {
         /*
          * RFC2616 states: 14.37 Retry-After
          *
@@ -1241,7 +1254,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
         }
         return ftp_proxyerror(r, backend, HTTP_SERVICE_UNAVAILABLE, ftpmessage);
     }
-    if (rc != 220) {
+    else if (rc != 220) {
         return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
     }
 
@@ -1257,15 +1270,20 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
     /* (This may include errors such as command line too long.) */
     /* 501 Syntax error in parameters or arguments. */
     /* 530 Not logged in. */
-    if (rc == -1 || rc == 421) {
-        return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, "Error reading from remote server");
+    if (rc == -1) {
+        return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                "Error reading from remote server");
+    }
+    else if (rc == 421) {
+        return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
+                "Error reading from remote server");
     }
-    if (rc == 530) {
+    else if (rc == 530) {
         proxy_ftp_cleanup(r, backend);
         return ftp_unauthorized(r, 1);  /* log it: user name guessing
                                          * attempt? */
     }
-    if (rc != 230 && rc != 331) {
+    else if (rc != 230 && rc != 331) {
         return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
     }
 
@@ -1285,21 +1303,25 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
         /* 501 Syntax error in parameters or arguments. */
         /* 503 Bad sequence of commands. */
         /* 530 Not logged in. */
-        if (rc == -1 || rc == 421) {
+        if (rc == -1) {
+            return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                                  "Error reading from remote server");
+        }
+        else if (rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
                                   "Error reading from remote server");
         }
-        if (rc == 332) {
+        else if (rc == 332) {
             return ftp_proxyerror(r, backend, HTTP_UNAUTHORIZED,
                   apr_pstrcat(p, "Need account for login: ", ftpmessage, NULL));
         }
         /* @@@ questionable -- we might as well return a 403 Forbidden here */
-        if (rc == 530) {
+        else if (rc == 530) {
             proxy_ftp_cleanup(r, backend);
             return ftp_unauthorized(r, 1);      /* log it: passwd guessing
                                                  * attempt? */
         }
-        if (rc != 230 && rc != 202) {
+        else if (rc != 230 && rc != 202) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
         }
     }
@@ -1315,9 +1337,14 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
             ++path;
 
         rc = proxy_ftp_command("CWD /" CRLF, r, origin, bb, &ftpmessage);
-        if (rc == -1 || rc == 421)
+        if (rc == -1) {
+            return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                    "Error reading from remote server");
+        }
+        else if (rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                  "Error reading from remote server");
+                    "Error reading from remote server");
+        }
     }
 
     /*
@@ -1354,14 +1381,18 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
         /* 502 Command not implemented. */
         /* 530 Not logged in. */
         /* 550 Requested action not taken. */
-        if (rc == -1 || rc == 421) {
+        if (rc == -1) {
+            return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                    "Error reading from remote server");
+        }
+        else if (rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                  "Error reading from remote server");
+                    "Error reading from remote server");
         }
-        if (rc == 550) {
+        else if (rc == 550) {
             return ftp_proxyerror(r, backend, HTTP_NOT_FOUND, ftpmessage);
         }
-        if (rc != 250) {
+        else if (rc != 250) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
         }
 
@@ -1395,11 +1426,15 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
         /* 501 Syntax error in parameters or arguments. */
         /* 502 Command not implemented. */
         /* 530 Not logged in. */
-        if (rc == -1 || rc == 421) {
+        if (rc == -1) {
+            return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                    "Error reading from remote server");
+        }
+        else if (rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                  "Error reading from remote server");
+                    "Error reading from remote server");
         }
-        if (rc != 229 && rc != 500 && rc != 501 && rc != 502) {
+        else if (rc != 229 && rc != 500 && rc != 501 && rc != 502) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
         }
         else if (rc == 229) {
@@ -1461,8 +1496,10 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01043)
                                   "EPSV attempt to connect to %pI failed - "
                                   "Firewall/NAT?", &epsv_addr);
-                    return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, apr_psprintf(r->pool,
-                                                                           "EPSV attempt to connect to %pI failed - firewall/NAT?", &epsv_addr));
+                    return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                            apr_psprintf(r->pool,
+                                    "EPSV attempt to connect to %pI failed - firewall/NAT?",
+                                    &epsv_addr));
                 }
                 else {
                     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
@@ -1484,11 +1521,15 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
         /* 501 Syntax error in parameters or arguments. */
         /* 502 Command not implemented. */
         /* 530 Not logged in. */
-        if (rc == -1 || rc == 421) {
+        if (rc == -1) {
+            return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                    "Error reading from remote server");
+        }
+        else if (rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                  "Error reading from remote server");
+                    "Error reading from remote server");
         }
-        if (rc != 227 && rc != 502) {
+        else if (rc != 227 && rc != 502) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
         }
         else if (rc == 227) {
@@ -1550,8 +1591,10 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
                 if (rv != APR_SUCCESS) {
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01048)
                                   "PASV attempt to connect to %pI failed - Firewall/NAT?", pasv_addr);
-                    return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, apr_psprintf(r->pool,
-                                                                           "PASV attempt to connect to %pI failed - firewall/NAT?", pasv_addr));
+                    return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                            apr_psprintf(r->pool,
+                                    "PASV attempt to connect to %pI failed - firewall/NAT?",
+                                    pasv_addr));
                 }
                 else {
                     connect = 1;
@@ -1621,11 +1664,15 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
             /* 501 Syntax error in parameters or arguments. */
             /* 502 Command not implemented. */
             /* 530 Not logged in. */
-            if (rc == -1 || rc == 421) {
+            if (rc == -1) {
+                return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                        "Error reading from remote server");
+            }
+            else if (rc == 421) {
                 return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                      "Error reading from remote server");
+                        "Error reading from remote server");
             }
-            if (rc != 200) {
+            else if (rc != 200) {
                 return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, buffer);
             }
 
@@ -1686,9 +1733,13 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
         rc = proxy_ftp_command(apr_pstrcat(p, "SIZE ",
                            ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL),
                            r, origin, bb, &ftpmessage);
-        if (rc == -1 || rc == 421) {
+        if (rc == -1) {
+            return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                    "Error reading from remote server");
+        }
+        else if (rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                  "Error reading from remote server");
+                    "Error reading from remote server");
         }
         else if (rc == 213) {/* Size command ok */
             int j;
@@ -1713,14 +1764,18 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
             /* 502 Command not implemented. */
             /* 530 Not logged in. */
             /* 550 Requested action not taken. */
-            if (rc == -1 || rc == 421) {
+            if (rc == -1) {
+                return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                        "Error reading from remote server");
+            }
+            else if (rc == 421) {
                 return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                      "Error reading from remote server");
+                        "Error reading from remote server");
             }
-            if (rc == 550) {
+            else if (rc == 550) {
                 return ftp_proxyerror(r, backend, HTTP_NOT_FOUND, ftpmessage);
             }
-            if (rc != 250) {
+            else if (rc != 250) {
                 return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
             }
             path = "";
@@ -1827,11 +1882,15 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
     /* 501 Syntax error in parameters or arguments. */
     /* 530 Not logged in. */
     /* 550 Requested action not taken. */
-    if (rc == -1 || rc == 421) {
+    if (rc == -1) {
+        return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                              "Error reading from remote server");
+    }
+    else if (rc == 421) {
         return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
                               "Error reading from remote server");
     }
-    if (rc == 550) {
+    else if (rc == 550) {
         ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                       "RETR failed, trying LIST instead");
 
@@ -1850,14 +1909,18 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
         /* 502 Command not implemented. */
         /* 530 Not logged in. */
         /* 550 Requested action not taken. */
-        if (rc == -1 || rc == 421) {
+        if (rc == -1) {
+            return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                    "Error reading from remote server");
+        }
+        else if (rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                  "Error reading from remote server");
+                    "Error reading from remote server");
         }
-        if (rc == 550) {
+        else if (rc == 550) {
             return ftp_proxyerror(r, backend, HTTP_NOT_FOUND, ftpmessage);
         }
-        if (rc != 250) {
+        else if (rc != 250) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
         }
 
@@ -1873,9 +1936,14 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
                                r, origin, bb, &ftpmessage);
 
         /* rc is an intermediate response for the LIST command (125 transfer starting, 150 opening data connection) */
-        if (rc == -1 || rc == 421)
+        if (rc == -1) {
+            return ftp_proxyerror(r, backend, HTTP_GATEWAY_TIME_OUT,
+                    "Error reading from remote server");
+        }
+        else if (rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
-                                  "Error reading from remote server");
+                    "Error reading from remote server");
+        }
     }
     if (rc != 125 && rc != 150 && rc != 226 && rc != 250) {
         return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
@@ -1947,7 +2015,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
                 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01053)
                               "failed to accept data connection");
                 proxy_ftp_cleanup(r, backend);
-                return HTTP_BAD_GATEWAY;
+                return HTTP_GATEWAY_TIME_OUT;
             }
         }
     }
index 0712b61d5f1b7bb3faa0d991af226d47cb9bc2ad..2038be306d275fbc8389fbb52ee7a3bf98ca89d2 100644 (file)
@@ -1374,7 +1374,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
                                    " failed.",
                                    backend->hostname, backend->port);
             }
-            return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+            return ap_proxyerror(r, HTTP_GATEWAY_TIME_OUT,
                                  "Error reading from remote server");
         }
         /* XXX: Is this a real headers length send from remote? */
@@ -1722,7 +1722,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
                     }
                     else if (rv != APR_SUCCESS) {
                         /* In this case, we are in real trouble because
-                         * our backend bailed on us. Pass along a 502 error
+                         * our backend bailed on us. Pass along a 504 error
                          * error bucket
                          */
                         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01110)
index 1baf4fe49ccd14438c8f937baaddb7cd2756a02f..d5cfb86548be6b243a6d0f7591300a86bcee4369 100644 (file)
@@ -2203,7 +2203,7 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
     }
 
     if (err != APR_SUCCESS) {
-        return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+        return ap_proxyerror(r, HTTP_GATEWAY_TIME_OUT,
                              apr_pstrcat(p, "DNS lookup failure for: ",
                                          conn->hostname, NULL));
     }
@@ -2761,7 +2761,7 @@ PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
      */
     if (r->main)
         r->main->no_cache = 1;
-    e = ap_bucket_error_create(HTTP_BAD_GATEWAY, NULL, c->pool,
+    e = ap_bucket_error_create(HTTP_GATEWAY_TIME_OUT, NULL, c->pool,
                                c->bucket_alloc);
     APR_BRIGADE_INSERT_TAIL(brigade, e);
     e = apr_bucket_eos_create(c->bucket_alloc);
@@ -3281,7 +3281,7 @@ PROXY_DECLARE(int) ap_proxy_pass_brigade(apr_bucket_alloc_t *bucket_alloc,
                                      "Error during SSL Handshake with"
                                      " remote server");
             }
-            return APR_STATUS_IS_TIMEUP(status) ? HTTP_GATEWAY_TIME_OUT : HTTP_BAD_GATEWAY;
+            return HTTP_GATEWAY_TIME_OUT;
         }
         else {
             return HTTP_BAD_REQUEST;