From: Graham Leggett Date: Wed, 20 Oct 2010 18:33:55 +0000 (+0000) Subject: mod_proxy: Move the ProxyErrorOverride directive to have per directory scope. X-Git-Tag: 2.3.9~249 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84a346c5bb57b91977f70306b55acb9109a27934;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy: Move the ProxyErrorOverride directive to have per directory scope. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1025666 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index c5212cf3983..2e3522dda45 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,9 @@ Changes with Apache 2.3.9 Fix a denial of service attack against mod_reqtimeout. [Stefan Fritsch] + *) mod_proxy: Move the ProxyErrorOverride directive to have per + directory scope. [Graham Leggett] + *) mod_allowmethods: New module to deny certain HTTP methods without interfering with authentication/authorization. [Paul Querna, Igor Galić, Stefan Fritsch] diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml index e1caaa28c58..18539f5323a 100644 --- a/docs/manual/mod/mod_proxy.xml +++ b/docs/manual/mod/mod_proxy.xml @@ -1547,6 +1547,7 @@ header for proxied requests ProxyErrorOverride On|Off ProxyErrorOverride Off server configvirtual host +directory Available in version 2.0 and later diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index d8d712def49..a2e99b339f3 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -1122,8 +1122,6 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s) ps->io_buffer_size_set = 0; ps->maxfwd = DEFAULT_MAX_FORWARDS; ps->maxfwd_set = 0; - ps->error_override = 0; - ps->error_override_set = 0; ps->timeout = 0; ps->timeout_set = 0; ps->badopt = bad_error; @@ -1160,8 +1158,6 @@ static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv) ps->io_buffer_size_set = overrides->io_buffer_size_set || base->io_buffer_size_set; ps->maxfwd = (overrides->maxfwd_set == 0) ? base->maxfwd : overrides->maxfwd; ps->maxfwd_set = overrides->maxfwd_set || base->maxfwd_set; - ps->error_override = (overrides->error_override_set == 0) ? base->error_override : overrides->error_override; - ps->error_override_set = overrides->error_override_set || base->error_override_set; ps->timeout = (overrides->timeout_set == 0) ? base->timeout : overrides->timeout; ps->timeout_set = overrides->timeout_set || base->timeout_set; ps->badopt = (overrides->badopt_set == 0) ? base->badopt : overrides->badopt; @@ -1188,6 +1184,8 @@ static void *create_proxy_dir_config(apr_pool_t *p, char *dummy) new->preserve_host_set = 0; new->preserve_host = 0; new->interpolate_env = -1; /* unset */ + new->error_override = 0; + new->error_override_set = 0; return (void *) new; } @@ -1215,6 +1213,9 @@ static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv) new->preserve_host = (add->preserve_host_set == 0) ? base->preserve_host : add->preserve_host; new->preserve_host_set = add->preserve_host_set || base->preserve_host_set; + new->error_override = (add->error_override_set == 0) ? base->error_override + : add->error_override; + new->error_override_set = add->error_override_set || base->error_override_set; return new; } @@ -1611,13 +1612,12 @@ static const char * } static const char * - set_proxy_error_override(cmd_parms *parms, void *dummy, int flag) + set_proxy_error_override(cmd_parms *parms, void *dconf, int flag) { - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); + proxy_dir_conf *conf = dconf; - psf->error_override = flag; - psf->error_override_set = 1; + conf->error_override = flag; + conf->error_override_set = 1; return NULL; } static const char * @@ -2119,7 +2119,7 @@ static const command_rec proxy_cmds[] = "The default intranet domain name (in absence of a domain in the URL)"), 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("ProxyErrorOverride", set_proxy_error_override, NULL, RSRC_CONF, + AP_INIT_FLAG("ProxyErrorOverride", set_proxy_error_override, NULL, RSRC_CONF|ACCESS_CONF, "use our error handling pages instead of the servers' we are proxying"), AP_INIT_FLAG("ProxyPreserveHost", set_preserve_host, NULL, RSRC_CONF|ACCESS_CONF, "on if we should preserve host header while proxying"), diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 95b3a85c044..500774b54c0 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -146,15 +146,6 @@ typedef struct { apr_size_t io_buffer_size; long maxfwd; apr_interval_time_t timeout; - /** - * 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 error_override; enum { bad_error, bad_ignore, @@ -172,7 +163,6 @@ typedef struct { char io_buffer_size_set; char maxfwd_set; char timeout_set; - char error_override_set; char badopt_set; char proxy_status_set; } proxy_server_conf; @@ -195,10 +185,20 @@ typedef struct { const apr_strmatch_pattern* cookie_path_str; const apr_strmatch_pattern* cookie_domain_str; + /** + * 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 error_override; signed char p_is_fnmatch; /* Is the path an fnmatch candidate? */ signed char interpolate_env; signed char preserve_host; signed char preserve_host_set; + int error_override_set:1; } proxy_dir_conf; /* if we interpolate env vars per-request, we'll need a per-request diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 4cb598ebe21..7ef71d21630 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -1411,6 +1411,9 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, const char *proxy_status_line = NULL; conn_rec *origin = backend->connection; apr_interval_time_t old_timeout = 0; + proxy_dir_conf *dconf; + + dconf = ap_get_module_config(r->per_dir_config, &proxy_module); int do_100_continue; @@ -1742,7 +1745,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, * ProxyPassReverse/etc from here to ap_proxy_read_headers */ - if ((proxy_status == 401) && (conf->error_override)) { + if ((proxy_status == 401) && (dconf->error_override)) { const char *buf; const char *wa = "WWW-Authenticate"; if ((buf = apr_table_get(r->headers_out, wa))) { @@ -1779,7 +1782,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, APR_BRIGADE_INSERT_TAIL(bb, e); } /* PR 41646: get HEAD right with ProxyErrorOverride */ - if (ap_is_HTTP_ERROR(r->status) && conf->error_override) { + if (ap_is_HTTP_ERROR(r->status) && dconf->error_override) { /* clear r->status for override error, otherwise ErrorDocument * thinks that this is a recursive error, and doesn't find the * custom error page @@ -1824,7 +1827,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, * if we are overriding the errors, we can't put the content * of the page into the brigade */ - if (!conf->error_override || !ap_is_HTTP_ERROR(proxy_status)) { + if (!dconf->error_override || !ap_is_HTTP_ERROR(proxy_status)) { /* read the body, pass it to the output filters */ apr_read_type_e mode = APR_NONBLOCK_READ; int finish = FALSE; @@ -1834,7 +1837,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, * error status so that an underlying error (eg HTTP_NOT_FOUND) * doesn't become an HTTP_OK. */ - if (conf->error_override && !ap_is_HTTP_ERROR(proxy_status) + if (dconf->error_override && !ap_is_HTTP_ERROR(proxy_status) && ap_is_HTTP_ERROR(original_status)) { r->status = original_status; r->status_line = original_status_line;