[PATCH] 1.3: mod_proxy
There is a feature I have wanted in Apache for a little while now: the ability to preserve the host header when using mod_proxy. This is mostly useful for two (or more) tier systems, where it is desirable to pass certain virtual server requests through to backend servers. The attached patch adds an option: ProxyPreserveHostHeader On|Off This option, when set, causes the Host: header of the proxy request to be passed on intact (including port number) to the backend server. I know there are other ways of jiggering this, but none I have found are quite as neat. My primary goal in implementing this is to leave the front end server configuration untouched (with a wildcard dns entry pointed at it) and have unmatched virtual hosts passed through to a backend server on a different host/port. The servers running on this backend server change with time. Regards, Matt -- Matt Kern http://www.undue.org/ diff -ur proxy/mod_proxy.c proxy/mod_proxy.c --- proxy/mod_proxy.c Thu May 30 17:11:32 2002 +++ proxy/mod_proxy.c Thu May 30 17:54:01 2002 -436,6 +436,8 ps-viaopt_set = 0; /* 0 means default */ ps-req = 0; ps-req_set = 0; +ps-hheader = 0; +ps-hheader_set = 0; ps-recv_buffer_size = 0; /* this default was left unset for some * reason */ ps-recv_buffer_size_set = 0; -483,6 +485,7 ps-domain = (overrides-domain == NULL) ? base-domain : overrides-domain; ps-viaopt = (overrides-viaopt_set == 0) ? base-viaopt : overrides-viaopt; ps-req = (overrides-req_set == 0) ? base-req : overrides-req; +ps-hheader = (overrides-hheader_set == 0) ? base-hheader : overrides-hheader; ps-recv_buffer_size = (overrides-recv_buffer_size_set == 0) ? base-recv_buffer_size : overrides-recv_buffer_size; ps-io_buffer_size = (overrides-io_buffer_size_set == 0) ? base-io_buffer_size : overrides-io_buffer_size; -703,6 +706,19 static const char * + set_proxy_preserve_host_header(cmd_parms *parms, void *dummy, int flag) +{ +proxy_server_conf *psf = +ap_get_module_config(parms-server-module_config, proxy_module); + +psf-hheader = flag; +psf-hheader_set = 1; + +return NULL; +} + + +static const char * set_cache_size(cmd_parms *parms, char *struct_ptr, char *arg) { proxy_server_conf *psf = -936,6 +952,8 a virtual path and a URL}, {ProxyPassReverse, add_pass_reverse, NULL, RSRC_CONF, TAKE2, a virtual path and a URL for reverse proxy behaviour}, +{ProxyPreserveHostHeader, set_proxy_preserve_host_header, NULL, RSRC_CONF, FLAG, +on if the original Host: header should be preserved}, {ProxyBlock, set_proxy_exclude, NULL, RSRC_CONF, ITERATE, A list of names, hosts or domains to which the proxy will not connect}, {ProxyReceiveBufferSize, set_recv_buffer_size, NULL, RSRC_CONF, TAKE1, diff -ur proxy/mod_proxy.h proxy/mod_proxy.h --- proxy/mod_proxy.h Thu May 30 17:11:32 2002 +++ proxy/mod_proxy.h Thu May 30 17:52:48 2002 -192,6 +192,8 char *domain; /* domain name to use in absence of a domain name in the request */ int req;/* true if proxy requests are enabled */ char req_set; +int hheader; /* true if we want to preserve the host header */ +char hheader_set; enum { via_off, via_on, diff -ur proxy/proxy_http.c proxy/proxy_http.c --- proxy/proxy_http.c Thu May 30 17:11:32 2002 +++ proxy/proxy_http.c Thu May 30 18:38:03 2002 -177,6 +177,7 struct noproxy_entry *npent = (struct noproxy_entry *) conf-noproxies-elts; struct nocache_entry *ncent = (struct nocache_entry *) conf-nocaches-elts; int nocache = 0; +int incoming_port = htons ((unsigned short)r-connection-local_addr.sin_port); if (conf-cache.root == NULL) nocache = 1; -312,10 +313,20 ap_bvputs(f, r-method, , proxyhost ? url : urlptr, HTTP/1.1 CRLF, NULL); /* Send Host: now, adding it to req_hdrs wouldn't be much better */ -if (destportstr != NULL destport != DEFAULT_HTTP_PORT) +if (conf-hheader) { + i = ap_get_server_port(r); + if (ap_is_default_port(i, r)) + strcpy(portstr, ); + else + ap_snprintf (portstr, sizeof portstr, :%d, i); + ap_bvputs(f, Host: , r-hostname, portstr, CRLF, NULL); +} +else { + if (destportstr != NULL destport != DEFAULT_HTTP_PORT) ap_bvputs(f, Host: , desthost, :, destportstr, CRLF, NULL); -else + else ap_bvputs(f, Host: , desthost, CRLF, NULL); +} if (conf-viaopt == via_block) { /* Block all outgoing Via: headers */
Re: [PATCH] 1.3: mod_proxy
This is already implemented in 2.0 as ProxyPreserveHost, you may want to backport it to 1.3 http://httpd.apache.org/docs-2.0/mod/mod_proxy.html#proxypreservehost Ah. I have fixed up my patch to have the same name and few minor tweaks to the patch to make it smaller. Can someone with CVS access look the patch over and put it in? Matt -- Matt Kern http://www.undue.org/ diff -ur apache.orig/htdocs/manual/mod/mod_proxy.html apache_1.3.24/htdocs/manual/mod/mod_proxy.html --- apache.orig/htdocs/manual/mod/mod_proxy.htmlThu Mar 21 17:28:49 2002 +++ apache_1.3.24/htdocs/manual/mod/mod_proxy.html Fri May 31 18:57:58 2002 -61,6 +61,8 lia href=#proxypassreverseProxyPassReverse/a/li + lia href=#proxypreservehostProxyPreserveHost/a/li + lia href=#proxyblockProxyBlock/a/li lia href=#allowconnectAllowCONNECT/a/li -453,6 +455,31 href=mod_rewrite.html#RewriteRulettmod_rewrite/tt/a because its doesn't depend on a corresponding sampProxyPass/samp directive./p +hr / + +h2a id=proxypreservehost +name=proxypreservehostProxyPreserveHost/a directive/h2 +a href=directive-dict.html#Syntax +rel=HelpstrongSyntax:/strong/a ProxyPreserveHost +on|offbr / + a href=directive-dict.html#Default +rel=HelpstrongDefault:/strong/a codeProxyPreserveHost Off/codebr / + a href=directive-dict.html#Context +rel=HelpstrongContext:/strong/a server config, virtual +hostbr / + a href=directive-dict.html#Override +rel=HelpstrongOverride:/strong/a emNot +applicable/embr / + a href=directive-dict.html#Status +rel=HelpstrongStatus:/strong/a Basebr / + a href=directive-dict.html#Module +rel=HelpstrongModule:/strong/a mod_proxybr / + a href=directive-dict.html#Compatibility +rel=HelpstrongCompatibility:/strong/a ProxyPassReverse +is only available in Apache 1.3.25 and later. + +pThis directive tells Apache to preserve the ttHost/tt +header from incoming requests on outgoing proxy requests./p hr / h2a id=allowconnect name=allowconnectAllowCONNECT/a diff -ur apache.orig/src/modules/proxy/mod_proxy.c apache_1.3.24/src/modules/proxy/mod_proxy.c --- apache.orig/src/modules/proxy/mod_proxy.c Fri May 31 18:56:10 2002 +++ apache_1.3.24/src/modules/proxy/mod_proxy.c Fri May 31 18:57:58 2002 -436,6 +436,8 ps-viaopt_set = 0; /* 0 means default */ ps-req = 0; ps-req_set = 0; +ps-phh = 0; +ps-phh_set = 0; ps-recv_buffer_size = 0; /* this default was left unset for some * reason */ ps-recv_buffer_size_set = 0; -483,6 +485,7 ps-domain = (overrides-domain == NULL) ? base-domain : overrides-domain; ps-viaopt = (overrides-viaopt_set == 0) ? base-viaopt : overrides-viaopt; ps-req = (overrides-req_set == 0) ? base-req : overrides-req; +ps-phh = (overrides-phh_set == 0) ? base-phh : overrides-phh; ps-recv_buffer_size = (overrides-recv_buffer_size_set == 0) ? base-recv_buffer_size : overrides-recv_buffer_size; ps-io_buffer_size = (overrides-io_buffer_size_set == 0) ? base-io_buffer_size : overrides-io_buffer_size; -703,6 +706,19 static const char * + set_proxy_preserve_host(cmd_parms *parms, void *dummy, int flag) +{ +proxy_server_conf *psf = +ap_get_module_config(parms-server-module_config, proxy_module); + +psf-phh = flag; +psf-phh_set = 1; + +return NULL; +} + + +static const char * set_cache_size(cmd_parms *parms, char *struct_ptr, char *arg) { proxy_server_conf *psf = -936,6 +952,8 a virtual path and a URL}, {ProxyPassReverse, add_pass_reverse, NULL, RSRC_CONF, TAKE2, a virtual path and a URL for reverse proxy behaviour}, +{ProxyPreserveHost, set_proxy_preserve_host, NULL, RSRC_CONF, FLAG, +on if the original Host: header should be preserved}, {ProxyBlock, set_proxy_exclude, NULL, RSRC_CONF, ITERATE, A list of names, hosts or domains to which the proxy will not connect}, {ProxyReceiveBufferSize, set_recv_buffer_size, NULL, RSRC_CONF, TAKE1, diff -ur apache.orig/src/modules/proxy/mod_proxy.h apache_1.3.24/src/modules/proxy/mod_proxy.h --- apache.orig/src/modules/proxy/mod_proxy.h Fri May 31 18:56:10 2002 +++ apache_1.3.24/src/modules/proxy/mod_proxy.h Fri May 31 18:57:58 2002 -192,6 +192,8 char *domain; /* domain name to use in absence of a domain name in the request */ int req;/* true if proxy requests are enabled */ char req_set; +int phh; /* true if we want to preserve the host header */ +char phh_set; enum { via_off, via_on, diff -ur apache.orig/src/modules/proxy/proxy_http.c apache_1.3.24/src/modules/proxy/proxy_http.c --- apache.orig/src/modules/proxy/proxy_http.c Fri May 31 18:56:10 2002 +++ apache_1.3.24/src/modules/proxy/proxy_http.cFri May 31 18:57:58 2002 -311,11 +311,14