What is the difference between Nginx variables $host, $http_host, and $server_name?
You should almost always use
$host, as it's the only one guaranteed to have something sensible regardless of how the user-agent behaves, unless you specifically need the semantics of one of the other variables.
The difference is explained in the nginx documentation:
$hostcontains "in this order of precedence: host name from the request line, or host name from the 'Host' request header field, or the server name matching a request"
$http_hostcontains the content of the HTTP "Host" header field, if it was present in the request
server_nameof the virtual host which processed the request, as it was defined in the nginx configuration. If a
server_names, only the first one will be present in this variable.
Since it is legal for user-agents to send the hostname in the request line rather than in a Host: header, though it is rarely done except when connecting to proxies, you have to account for this.
You also have to account for the case where the user-agent doesn't send a hostname at all, e.g. ancient HTTP/1.0 requests and modern badly-written software. You might do so by diverting them to a catch-all virtual host which doesn't serve anything, if you are serving multiple web sites, or if you only have a single web site on your server you might process everything through a single virtual host. In the latter case you have to account for this as well.
$host variable accounts for all the possible things that a user-agent may do when forming an HTTP request.
I would like to add another important point not mentioned in the accepted answer.
$host do NOT have port number, while
$http_host does include the port number.
edit: not always.
I set up a header "add_header Y-blog-http_host "$http_host" always;"
curl -I -L domain.com:80 (or 443) and the header doesn't show a port number at all. Verified with nginx-extra 1.10.3. Is is because it's common http(s) ports or nginx configuration? This comment just to say things do not always behave the way you think.