Mastering Nginx: Two Common HTTP‑to‑HTTPS Redirect Scenarios Explained
This guide walks through the two most typical Nginx HTTP‑to‑HTTPS redirection setups—direct client access and proxy‑mediated access—showing why the simple 301 rule works in the first case, why it fails with an upstream proxy, and how to correctly use request headers and Nginx variables to achieve reliable redirects.
1. Nginx without an upstream proxy (direct client access)
This straightforward scenario gives you full control over both HTTP and HTTPS servers, and users connect directly to Nginx.
Configure a 301 redirect on the HTTP server to point to the HTTPS server.
<code># http server
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
# https server
server {
listen 443 ssl http2;
server_name www.example.com;
# ... other settings
}
</code>Many prefer to place both server blocks in the same file, keeping detailed logic inside the HTTPS server block.
2. Nginx behind an upstream proxy
When an upstream proxy terminates TLS, the client never talks to Nginx over HTTPS; the proxy always forwards requests to Nginx using HTTP.
Using the built‑in
schemevariable therefore fails because Nginx always sees "http".
<code># Incorrect configuration
server {
listen 80;
server_name _;
if ($scheme = "http") {
return 301 https://$host$request_uri;
}
}
</code>This results in an endless redirect loop. The fix is to inspect a header set by the proxy (e.g.,
X-Forward-Scheme) and redirect only when it indicates HTTP.
<code># Correct configuration
server {
listen 80;
server_name _;
# ... other settings
if ($http_x_forward_scheme = "http") {
return 301 https://$host$request_uri;
}
}
</code>The variable
$http_x_forward_schemecorresponds to the
X-Forward-Schemerequest header; the exact header name may vary between proxies.
3. Nginx Header Retrieval Rules
Nginx automatically maps HTTP headers to variables. By default, the mapping follows these rules:
Convert the header name to lower‑case, replace hyphens (
-) with underscores (
_).
Prefix the result with
http_.
Headers containing underscores are not recognized unless the
underscores_in_headersdirective is enabled.
<code># Correct examples
Server-Version => http_server_version
X-Forward-Scheme => http_x_forward_scheme
X-Customize-Header => http_x_customize_header
# Incorrect example
Server_Verver (unsupported without special settings)
</code>If you need to support headers with underscores, enable the
underscores_in_headersdirective:
<code>underscores_in_headers on; # context: http, server
</code>After enabling, variables like
http_server_versionbecome available.
3.1 Common Header Variable Operations
Check if a header variable exists:
<code>server {
if ($x_customize_header) {
# statements
}
}
</code>Validate the header value (using standard Nginx
ifsyntax):
<code>server {
if ($x_customize_header = "vscode-client/v1.2") {
# statements
}
}
</code>Reference Documents
Heroku Routing Header: https://devcenter.heroku.com/articles/http-routing
Nginx Header Tricks: https://liqiang.io/post/nginx-redirect-with-request-header-3c575166
Nginx configuration: reading custom headers, AND conditions, response body modification, domain redirects: https://segmentfault.com/a/1190000020852253
Nginx If‑Condition guide: https://blog.xinac.cn/archives/nginx%E9%85%8D%E7%BD%AE%E4%B8%ADifelse%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95.html
Why
ifis evil in Nginx: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
Creating Nginx rewrite rules: https://www.nginx.com/blog/creating-nginx-rewrite-rules/
Nginx
ifusage: https://www.ucloud.cn/yun/40533.html
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.