Preserving HTTP 1.1 Host: headers

HTTP 1.1 requests often include a Host: header, which contains the hostname from the client request. This is because a server may use a single IP address or interface to accept requests for multiple DNS hostnames.

The Host: header identifies the server requested by the client. When a reverse proxy proxies an HTTP 1.1 request between a client and a target server, when it makes the request, it must add the Host: header to the outbound request. The Host: header it sends to the target server should be the same as the Host: header it received from the client. It should not be the Host: header that would be sent if accessing the target server directly.

When the application server needs to create an absolute, fully-qualified URL, such as for a redirect URL or an absolute path to an image or CSS file, it must provide the correct hostname to the client to use in a subsequent request.

For example, a Java application server sends a client-side redirect to a browser (HTTP 302 Moved). It uses the ServletRequest.getServerName() method to fetch the hostname in the request, then constructs a Host: header.

The URL sent by the client is http://mystudio/web/myapp. The actual internal target URL generated by the reverse proxy will be http://studioserver1:8080/eid/web/myapp.

If there is no specific configuration for the target server, then if the reverse proxy retains the Host: header, the header is:
Host: http://mystudio
If the reverse proxy does not retain the Host: header, the result is:
Host: http://studioserver1:8080

In the latter case, where the header uses the actual target server hostname, the client may not have access to studioserver1, or may not be able to resolve the hostname. It also will bypass the reverse proxy on the next request, which may cause security issues.

If the Host: header cannot be relied on as correct for the client, then it must be configured specifically for the web or application server, so that it can render correct absolute URLs.

Most reverse proxy solutions should have a configuration option to allow the Host: header to be preserved.