From: Ian Holsman Date: Thu, 20 Sep 2001 05:34:50 +0000 (+0000) Subject: Added New Option 'HTTPProxyOverrideReturnedErrors' which lets the server override X-Git-Tag: 2.0.26~211 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=65d5d7b65c8b83b7640fb185333b5cf0ea7eea4b;p=thirdparty%2Fapache%2Fhttpd.git Added New Option 'HTTPProxyOverrideReturnedErrors' which lets the server override the error pages returned from the proxied server and replace them with the standard server error handling on the main server. Reviewed by: Graham, Chuck git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@91092 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/CHANGES b/modules/proxy/CHANGES index e5b3df5e3d8..26bed8e98c4 100644 --- a/modules/proxy/CHANGES +++ b/modules/proxy/CHANGES @@ -1,3 +1,11 @@ +mod_proxy changes for httpd 2.0.26-dev + *) Add New option 'HTTPProxyOverrideReturnedErrors'. By Turning the + Flag on, you will mask the error pages returned by the proxied + server, and will it will be handled as if your server generated + the error. This change was put in so that a 404 on a included + r-proxied component will act in the same manner as a 404 on a + included file. [Ian Holsman ] + mod_proxy changes for httpd 2.0.25-dev *) Split proxy: space using directive blocks from diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 40f128c931e..f7f331b52f9 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -482,7 +482,7 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s) ps->recv_buffer_size_set = 0; ps->maxfwd = DEFAULT_MAX_FORWARDS; ps->maxfwd_set = 0; - + ps->HTTPOverrideErrors=0; return ps; } @@ -760,6 +760,15 @@ static const char * psf->req_set = 1; return NULL; } +static const char * + set_http_proxy_override_error(cmd_parms *parms, void *dummy, int flag) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + psf->HTTPOverrideErrors = flag; + return NULL; +} static const char * set_recv_buffer_size(cmd_parms *parms, void *dummy, const char *arg) @@ -931,6 +940,8 @@ static const command_rec proxy_cmds[] = "A list of ports which CONNECT may connect to"), AP_INIT_TAKE1("ProxyVia", set_via_opt, NULL, RSRC_CONF, "Configure Via: proxy header header to one of: on | off | block | full"), + AP_INIT_FLAG("HTTPProxyOverrideReturnedErrors", set_http_proxy_override_error, NULL, RSRC_CONF, + "use our error handling pages instead of the servers we are proxying"), {NULL} }; diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 3f01e9819af..8eff71d743b 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -177,6 +177,16 @@ typedef struct { char recv_buffer_size_set; long maxfwd; char maxfwd_set; + /** + * the following setting masks the error page + * returned from the 'proxied server' and just + * forwards the status code upwards. + * This allows the main server (us) to generate + * the error page, (so it will look like a error + * returned from the rest of the system + */ + int HTTPOverrideErrors; + } proxy_server_conf; typedef struct { diff --git a/modules/proxy/proxy_http.c b/modules/proxy/proxy_http.c index 5ff0b0a4484..8158b7c57b4 100644 --- a/modules/proxy/proxy_http.c +++ b/modules/proxy/proxy_http.c @@ -824,24 +824,33 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server, "proxy: start body send"); + /* + * if we are overriding the errors, we cant put the content of the + * page into the brigade + */ + if ( (conf->HTTPOverrideErrors ==0) || r->status < 400 ) { /* read the body, pass it to the output filters */ - while (ap_get_brigade(rp->input_filters, bb, AP_MODE_NONBLOCKING, &readbytes) == APR_SUCCESS) { + while (ap_get_brigade(rp->input_filters, + bb, + AP_MODE_NONBLOCKING, + &readbytes) == APR_SUCCESS) { #if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - r->server, "proxy (PID %d): readbytes: %#x", - getpid(), readbytes); + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, + r->server, "proxy (PID %d): readbytes: %#x", + getpid(), readbytes); #endif - if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { - ap_pass_brigade(r->output_filters, bb); - break; - } - if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) { - /* Ack! Phbtt! Die! User aborted! */ - p_conn->close = 1; /* this causes socket close below */ - break; + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { + ap_pass_brigade(r->output_filters, bb); + break; + } + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) { + /* Ack! Phbtt! Die! User aborted! */ + p_conn->close = 1; /* this causes socket close below */ + break; + } + apr_brigade_cleanup(bb); } - apr_brigade_cleanup(bb); } ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server, "proxy: end body send"); @@ -850,7 +859,11 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, "proxy: header only"); } } - return OK; + + if ( conf->HTTPOverrideErrors ) + return r->status; + else + return OK; } static @@ -954,6 +967,8 @@ int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf, status = ap_proxy_http_process_response(p, r, p_conn, origin, backend, conf, bb, server_portstr); if ( status != OK ) { + /* clean up even if there is an error */ + ap_proxy_http_cleanup(r, p_conn, backend); return status; }