From: Graham Leggett Date: Fri, 13 Apr 2001 15:51:33 +0000 (+0000) Subject: Added Max-Forwards support for all request types so as to prevent X-Git-Tag: 2.0.17~25 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=81ef5d35b2b87f0b895ab9a7510acd085e018c4b;p=apache Added Max-Forwards support for all request types so as to prevent loops. PR: 1085 Obtained from: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88848 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 5d2cf97009..fdab3b31bc 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -269,15 +269,17 @@ static int proxy_handler(request_rec *r) struct proxy_remote *ents = (struct proxy_remote *) proxies->elts; int i, rc; int direct_connect = 0; - const char *maxfwd_str; + const char *str; const char *pragma, *auth, *imstr; + long maxfwd; + /* is this for us? */ if (!r->proxyreq || strncmp(r->filename, "proxy:", 6) != 0) return DECLINED; - if ((r->method_number == M_TRACE || r->method_number == M_OPTIONS) && - (maxfwd_str = apr_table_get(r->headers_in, "Max-Forwards")) != NULL) { - long maxfwd = strtol(maxfwd_str, NULL, 10); + /* handle max-forwards / OPTIONS / TRACE */ + if ((str = apr_table_get(r->headers_in, "Max-Forwards"))) { + maxfwd = strtol(str, NULL, 10); if (maxfwd < 1) { switch (r->method_number) { case M_TRACE: { @@ -298,11 +300,20 @@ static int proxy_handler(request_rec *r) ap_finalize_request_protocol(r); return OK; } + default: { + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Max-Forwards has reached zero - proxy loop?"); + } } } - apr_table_setn(r->headers_in, "Max-Forwards", - apr_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd-1 : 0)); + maxfwd = (maxfwd > 0) ? maxfwd - 1 : 0; + } + else { + /* set configured max-forwards */ + maxfwd = conf->maxfwd; } + apr_table_setn(r->headers_in, "Max-Forwards", + apr_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd : 0)); if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) return rc; @@ -417,6 +428,8 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s) ps->req_set = 0; ps->recv_buffer_size = 0; /* this default was left unset for some reason */ ps->recv_buffer_size_set = 0; + ps->maxfwd = DEFAULT_MAX_FORWARDS; + ps->maxfwd_set = 0; return ps; } @@ -438,6 +451,7 @@ static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv) ps->viaopt = (overrides->viaopt_set == 0) ? base->viaopt : overrides->viaopt; ps->req = (overrides->req_set == 0) ? base->req : overrides->req; ps->recv_buffer_size = (overrides->recv_buffer_size_set == 0) ? base->recv_buffer_size : overrides->recv_buffer_size; + ps->maxfwd = (overrides->maxfwd_set == 0) ? base->maxfwd : overrides->maxfwd; return ps; } @@ -664,6 +678,21 @@ static const char * return NULL; } +static const char * + set_max_forwards(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + long s = atol(arg); + if (s < 0) { + return "ProxyMaxForwards must be greater or equal to zero.."; + } + + psf->maxfwd = s; + psf->maxfwd_set = 1; + return NULL; +} + static const char* set_via_opt(cmd_parms *parms, void *dummy, const char *arg) { @@ -701,6 +730,8 @@ static const command_rec proxy_cmds[] = "A list of names, hosts or domains to which the proxy will not connect"), AP_INIT_TAKE1("ProxyReceiveBufferSize", set_recv_buffer_size, NULL, RSRC_CONF, "Receive buffer size for outgoing HTTP and FTP connections in bytes"), + AP_INIT_TAKE1("ProxyMaxForwards", set_max_forwards, NULL, RSRC_CONF, + "The maximum number of proxies a request may be forwarded through."), AP_INIT_ITERATE("NoProxy", set_proxy_dirconn, NULL, RSRC_CONF, "A list of domains, hosts, or subnets to which the proxy will connect directly"), AP_INIT_TAKE1("ProxyDomain", set_proxy_domain, NULL, RSRC_CONF, diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 9e32cda9e7..2838986eff 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -134,6 +134,8 @@ enum enctype { #define CRLF "\015\012" #endif /*APR_CHARSET_EBCDIC*/ +/* default Max-Forwards header setting */ +#define DEFAULT_MAX_FORWARDS 10 /* static information about a remote proxy */ struct proxy_remote { @@ -179,6 +181,8 @@ typedef struct { char viaopt_set; size_t recv_buffer_size; char recv_buffer_size_set; + long maxfwd; + char maxfwd_set; } proxy_server_conf; struct per_thread_data {