On Fri, May 31, 2002 at 11:26:55AM +0100, Matt Kern wrote: > 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.
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 > 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 */
