When would you consider using one over the other and why?
HTTP_HOST is obtained from the HTTP request header and this is what the client actually used as "target host" of the request. The
SERVER_NAME is defined in server config. Which one to use depends on what you need it for. You should now however realize that the one is a client-controlled value which may thus not be reliable for use in business logic and the other is a server-controlled value which is more reliable. You however need to ensure that the webserver in question has the
SERVER_NAME correctly configured. Taking Apache HTTPD as an example, here's an extract from its documentation:
ServerNameis specified, then the server attempts to deduce the hostname by performing a reverse lookup on the IP address. If no port is specified in the
ServerName, then the server will use the port from the incoming request. For optimal reliability and predictability, you should specify an explicit hostname and port using the
Update: after checking the answer of Pekka on your question which contains a link to bobince's answer that PHP would always return
HTTP_HOST's value for
SERVER_NAME, which goes against my own PHP 4.x + Apache HTTPD 1.2.x experiences from a couple of years ago, I blew some dust from my current XAMPP environment on Windows XP (Apache HTTPD 2.2.1 with PHP 5.2.8), started it, created a PHP page which prints the both values, created a Java test application using
URLConnection to modify the
Host header and tests taught me that this is indeed (incorrectly) the case.
After first suspecting PHP and digging in some PHP bug reports regarding the subject, I learned that the root of the problem is in web server used, that it incorrectly returned HTTP
Host header when
SERVER_NAME was requested. So I dug into Apache HTTPD bug reports using various keywords regarding the subject and I finally found a related bug. This behaviour was introduced since around Apache HTTPD 1.3. You need to set
UseCanonicalName directive to
on in the
<VirtualHost> entry of the
httpd.conf (also check the warning at the bottom of the document!).
<VirtualHost *> ServerName example.com UseCanonicalName on </VirtualHost>
This worked for me.
SERVER_NAME is more reliable, but you're dependent on the server config!
HTTP_HOST is the target host sent by the client. It can be manipulated freely by the user. It's no problem to send a request to your site asking for a
HTTP_HOST value of
SERVER_NAME comes from the server's
VirtualHost definition and is therefore considered more reliable. It can, however, also be manipulated from outside under certain conditions related to how your web server is set up: See this This SO question that deals with the security aspects of both variations.
You shouldn't rely on either to be safe. That said, what to use really depends on what you want to do. If you want to determine which domain your script is running on, you can safely use
HTTP_HOST as long as invalid values coming from a malicious user can't break anything.