I am having a problem with ProxyPreserveHost after upgrading from 2.4.12 to 2.4.46. # ProxyPreserveHost on ProxyRequests on <Proxy *> AllowOverride None Require all granted </Proxy> ProxyPreserveHost On RequestHeader set Host_Host "expr=%{HTTP:Host}" RequestHeader set Host_Host2 "expr=%{HTTP_HOST}" ## Request GET http://foo.example.net:80/hello/ HTTP/1.1 Host: bar.example.net ## Proxy request GET /hello/ HTTP/1.1 Host: foo.example.net:80 Host_Host: foo.example.net:80 Host_Host2: foo.example.net:80 # ProxyPreserveHost off ProxyRequests on <Proxy *> AllowOverride None Require all granted </Proxy> ProxyPreserveHost Off RequestHeader set Host_Host "expr=%{HTTP:Host}" RequestHeader set Host_Host2 "expr=%{HTTP_HOST}" ## Request GET http://foo.example.net:80/hello/ HTTP/1.1 Host: bar.example.net ## Proxy request GET /hello/ HTTP/1.1 Host: foo.example.net Host_Host: foo.example.net:80 Host_Host2: foo.example.net:80 # The problem When ProxyPreserveHost is on the value of the Host header proxy request should be bar.example.net (like Host header in the original request). Also in both cases the HTTP:Host and HTTP_HOST variables were rewritten based on the host in the URL. It looks like the request Host header is rewritten to the content of the URL before ProxyPreserveHost has a chance to set it. This was working correctly with httpd 2.4.12. The only workaround I found was to have the upstream server (Varnish in my case) preserve the value of the Host request header under different name (e.g. X-Host) and then use ProxyPreserveHost on with RequestHeader set Host "expr=%{HTTP:X-Host}".
The behavior in 2.4.12 was wrong. According to RFC7230 5.4: When a proxy receives a request with an absolute-form of request-target, the proxy MUST ignore the received Host header field (if any) and instead replace it with the host information of the request-target. A proxy that forwards such a request MUST generate a new Host field-value based on the received request-target rather than forward the received Host field-value.