following up on my own post (the only reponse I received was the suggestion to switch to nginx, and while it does appear that much development is happening there, I am not in a position to deploy current right away...)
On 23 Mar 2012 at 18:26, Jacob L. Leifman wrote: > In the process of migrating a simple reverse proxy from a Linux box to > OpenBSD (4.9-i386) I've come across a problem behavior that seems to > indicate that the directive ProxyPreserveHost is not working. In fact > setting it on or off does not affect the perceived behavior at all. > > The setup is rather simple and syntactically identical between the Linux > Apache2 and OpenBSD base httpd (Apache 1.3+): > > <VirtualHost [public_ip]> > ServerName www.customer.com > ErrorLog logs/error_log > CustomLog logs/access_log common > ProxyPreserveHost On > ProxyPass / http://10.xx.yy.zz/ > ProxyPassReverse / http://10.xx.yy.zz/ > </VirtualHost> > > The resulting behaviors differ thus: > > request http://www.customer.com/test/page.aspx -- > *want/linux: the backend server recognizes that the request is for > virtual server named www.customer.com and delivers the required page; > *openbsd: the backend server sees http://10.xx.yy.zz/test/page.aspx, > does not recognize the site and returns 404 Page not found. > > request http://www.customer.com/ -- > *want/linux: the backend server recognizes the site and correctly forms > all self-referential links on the home page; *openbsd: the backend > server generates all self-referential links as http://10.xx.yy.zz/... > which get handed back to the client outside the firewall, rendering the > website not usable. > > I checked cvsweb for the proxy module of the base httpd, and it has had > no commits in year, so I believe I am running the latest code. > > Please let me know if/what additional diagnostic info is needed, or > hopefully patches to test. > > Thanks, > -Jacob. > > After some code archeology I discovered that a critical piece of the ProxyPreserveHost implementation which was committed to proxy_http.c r1.17 was lost because r1.18 evolved directly from r1.16. I have reconstructed the missing patch and made a minor adjustment related to the evolution of code since then. Below is the resulting "new" patch, which does appear to fix my problem above. I would appreciate the community/devs reviewing it to make sure I did not miss something important. --- proxy_http.c.orig Mon Jan 10 15:05:49 2011 +++ proxy_http.c Sat Mar 24 14:29:30 2012 @@ -151,7 +151,7 @@ { const char *strp; char *strp2; - const char *err, *desthost; + const char *err, *desthost, *hostname; int i, j, sock,/* len,*/ backasswards; table *req_hdrs, *resp_hdrs; array_header *reqhdrs_arr; @@ -362,21 +362,41 @@ ap_hard_timeout("proxy send", r); ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.1" CRLF, NULL); + + if (conf->preserve_host) { + hostname = ap_table_get(r->headers_in, "Host"); + if (!hostname) { + hostname = r->server->server_hostname; + ap_log_rerror(APLOG_MARK, APLOG_WARNING, r, + "proxy: No host line on incoming request " + "and preserve host set forcing hostname to " + "be %s for uri %s", hostname, r->uri); + } + strp2 = strchr(hostname, ':'); + if (strp2 != NULL) { + *(strp2++) = '\0'; + if (ap_isdigit(*strp2)) + destportstr = strp2; + } + } + else + hostname = desthost; + { int rc = DECLINED; ap_hook_use("ap::mod_proxy::http::handler::write_host_header", AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,ptr), AP_HOOK_DECLINE(DECLINED), - &rc, r, f, desthost, destportstr, destportstr); + &rc, r, f, hostname, destportstr, destportstr); if (rc == DECLINED) { destportstrtonum = strtonum(destportstr, 0, 65535, &errstr); if (errstr) errx(1, "The destination port is %s: %s", errstr, destportstr); if (destportstr != NULL && destportstrtonum != destport) - ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL); + ap_bvputs(f, "Host: ", hostname, ":", destportstr, CRLF, NULL); else - ap_bvputs(f, "Host: ", desthost, CRLF, NULL); + ap_bvputs(f, "Host: ", hostname, CRLF, NULL); } }
