From: Graham Leggett Date: Tue, 7 May 2013 20:27:37 +0000 (+0000) Subject: mod_proxy: Ensure network errors detected by the proxy are returned as X-Git-Tag: 2.5.0-alpha~5484 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a7fc0f013e80d62a6dd949395a7f5972b6e8b607;p=apache 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. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1480058 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 66a3375621..c0f607d73b 100644 --- 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 ] + *) 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 ] diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c index b93f58768c..6be17c0d9a 100644 --- a/modules/proxy/mod_proxy_ftp.c +++ b/modules/proxy/mod_proxy_ftp.c @@ -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; } } } diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 0712b61d5f..2038be306d 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -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) diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 1baf4fe49c..d5cfb86548 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -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;