Keywords: Nginx Configuration | HTTP Variables | Server Name
Abstract: This article provides an in-depth exploration of the differences and relationships between the $host and $http_host variables in Nginx configuration. Through analysis of official documentation and practical examples, it details the intelligent fallback mechanism, port handling rules, and lowercase conversion features of $host, as well as the raw characteristics of $http_host as a direct mapping of HTTP headers. The article includes comprehensive code examples and practical guidance for server name configuration and rewrite rules, helping developers accurately understand and correctly use these key variables.
Overview of Nginx Variable System
Nginx, as a high-performance web server and reverse proxy, offers a powerful variable system that provides significant flexibility in configuration. During HTTP request processing, Nginx supplies a rich set of built-in variables to access various request attributes and header information. Among these, $host and $http_host are two frequently confused yet critically important variables.
The Nature of $http_host Variable
The $http_host variable belongs to the generic header variable series of Nginx's core module, following the naming convention of $http_HEADER. This variable directly maps to the Host field in the HTTP request header, preserving the complete format from the original request.
From a technical implementation perspective, the value of $http_host is an exact copy of the Host header content sent by the client in the HTTP request. This means:
# Example: When client request header is "Host: example.com:8080"
# $http_host value is "example.com:8080"
# Configuration example: Logging original Host header
location /log-headers {
access_log /var/log/nginx/access.log '$http_host';
}
This direct mapping characteristic makes $http_host invaluable in scenarios requiring precise matching of original request headers.
Intelligent Features of $host Variable
In contrast, the $host variable exhibits more intelligent and robust behavioral characteristics. According to Nginx official documentation, the value determination of this variable follows specific priority rules:
# Intelligent fallback mechanism example
server {
listen 80;
server_name backup.example.com;
location / {
# When Host header is missing or empty, $host uses server_name value
return 200 "Host: $host\n";
}
}
The core characteristics of the $host variable can be summarized into three key aspects:
Automatic Port Stripping
When the HTTP request's Host header includes a port number, $host automatically removes the port portion, retaining only the hostname:
# Input: Host: www.example.com:8080
# $http_host = "www.example.com:8080"
# $host = "www.example.com"
# Practical configuration application
location /api {
# In rewrite rules, typically only the hostname is needed, not the port
rewrite ^/api/(.*)$ https://$host/v2/$1 permanent;
}
Server Name Fallback Mechanism
In special cases where the Host header is missing or has an empty value, $host falls back to the value configured in the server_name directive of the current server block:
server {
listen 80 default_server;
server_name fallback.example.com;
# When client doesn't send Host header
# $host = "fallback.example.com"
location / {
proxy_pass http://backend/$host$request_uri;
}
}
Lowercase Normalization
Since Nginx version 0.8.17, the value of $host is always converted to lowercase, helping to avoid matching issues caused by case inconsistencies:
# Input: Host: WWW.Example.COM
# $http_host = "WWW.Example.COM" # Preserves original case
# $host = "www.example.com" # Uniformly converted to lowercase
# Application in virtual host matching
server {
server_name www.example.com;
# Even if client sends uppercase Host header, $host still matches correctly
}
Practical Scenario Analysis and Code Examples
Correct Choice in Rewrite Rules
In URL rewriting scenarios, selecting the appropriate variable is crucial. The reference article case demonstrates typical application during forum system migration:
location = /vb/showthread.php {
# Handling old forum post link redirections
if ($arg_p) {
# Using $host ensures redirection to correct hostname
return 301 $scheme://$host/forum/index.php?posts/$arg_p/;
}
}
In this example, choosing $host over $http_host offers distinct advantages:
- Compatibility: Redirections work correctly even when clients don't send Host headers
- Simplicity: Automatic port removal avoids redirecting to URLs containing ports
- Consistency: Lowercase normalization ensures stability of redirect targets
Variable Application in Proxy Configuration
In reverse proxy scenarios, the choice between variables affects the information received by backend servers:
location /proxy/ {
# Option A: Pass original Host header
proxy_set_header Host $http_host;
# Option B: Pass processed hostname
proxy_set_header Host $host;
proxy_pass http://backend-server;
}
Option A preserves the client's original request information, suitable for scenarios requiring exact replication of client requests. Option B provides more standardized and robust hostname passing, particularly suitable for multi-environment deployments.
Comprehensive Comparison and Best Practices
<table border="1"> <thead> <tr> <th>Characteristic</th> <th>$http_host</th>
<th>$host</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data Source</td>
<td>Directly from HTTP Host header</td>
<td>Intelligent combination: Host header → server_name fallback</td>
</tr>
<tr>
<td>Port Handling</td>
<td>Includes port number (if present)</td>
<td>Automatically removes port number</td>
</tr>
<tr>
<td>Case Sensitivity</td>
<td>Preserves original case</td>
<td>Uniformly converted to lowercase</td>
</tr>
<tr>
<td>Empty Value Handling</td>
<td>May be empty or undefined</td>
<td>Always has valid value (fallback mechanism)</td>
</tr>
<tr>
<td>Suitable Scenarios</td>
<td>Scenarios requiring original request information</td>
<td>General configuration, redirections, virtual host matching</td>
</tr>
</tbody>
Configuration Recommendations
Based on in-depth analysis, we propose the following configuration suggestions:
# Recommended scenarios for using $host
server {
server_name example.com www.example.com;
# 1. General redirections
if ($host = 'www.example.com') {
return 301 https://example.com$request_uri;
}
# 2. Virtual host routing
location /app1 {
# Using $host ensures correct hostname identification
proxy_pass http://app1-backend/$host$request_uri;
}
# 3. Log recording
access_log /var/log/nginx/access.log '$host - $remote_addr';
}
# Special scenarios requiring original information
location /debug {
# Record complete original Host header for debugging
add_header X-Original-Host $http_host;
return 200 "Debug info recorded";
}
Conclusion
Through systematic analysis, we can clearly recognize the different roles and values of $host and $http_host in Nginx configuration. $http_host, as a direct mapping of the original HTTP header, is indispensable in scenarios requiring precise replication of client request information. Meanwhile, $host, with its intelligent fallback mechanism, automatic port stripping, and lowercase normalization features, provides better robustness and convenience in most general configuration scenarios.
In practical Nginx configuration work, understanding the fundamental differences and applicable scenarios of these two variables enables developers to make more informed choices and build more stable and reliable web service architectures. It is recommended to prioritize using $host in regular configurations, reserving $http_host only for special scenarios that genuinely require original request information.