Understanding HTTP_HOST vs HTTPS_HOST in Apache .htaccess: Protocol-Specific Rewrite Rules Explained


3 views

When working with Apache's mod_rewrite in .htaccess files, %{HTTP_HOST} and %{HTTPS} (often mistaken as HTTPS_HOST) serve fundamentally different purposes:

# HTTP_HOST matches the domain name regardless of protocol
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]

# HTTPS is a flag (on/off) indicating SSL usage
RewriteCond %{HTTPS} off

Contrary to some documentation, there is no actual HTTPS_HOST variable in Apache. What developers typically encounter is either:

  1. Confusion between %{HTTPS} (the SSL flag) and HTTP_HOST
  2. Custom variables set by server configurations

Here's how to properly implement protocol-specific rules:

# Force HTTPS for all requests
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Handle specific HTTP-only cases
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^api\.example\.com$ [NC]
RewriteRule ^(.*)$ http://cdn.example.com/$1 [L,P]

For complex routing scenarios, combine protocol checks with host matching:

# Different behavior for HTTP/HTTPS on same domain
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^shop\.example\.com$ [NC]
RewriteRule ^cart$ /secure-cart [L]

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^shop\.example\.com$ [NC]
RewriteRule ^cart$ /unsecured-cart [L]

When troubleshooting, log both values:

RewriteLogLevel 3
RewriteLog /path/to/rewrite.log
RewriteCond %{HTTPS} ^(on|off)$
RewriteRule ^ - [E=PROTOCOL:%{HTTPS},E=HOST:%{HTTP_HOST}]

Remember that protocol handling should always be tested with various combinations:
- http://example.com
- https://example.com
- http://www.example.com
- https://subdomain.example.com


In Apache's mod_rewrite environment, HTTP_HOST and HTTPS_HOST serve fundamentally different purposes:

# HTTP_HOST contains the hostname from the request (protocol-agnostic)
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]

# HTTPS_HOST is a boolean flag (1/0 or on/off) indicating SSL usage
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

Many developers assume these variables work similarly, but they don't:

  • HTTP_HOST: Contains the requested hostname (e.g., "www.example.com") regardless of protocol
  • HTTPS (not HTTPS_HOST): Boolean indicating if SSL is being used

Case 1: Force HTTPS for Specific Domains

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

Case 2: Protocol-Specific Redirects

# Redirect HTTP traffic for specific paths
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/secure-path
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

Environment Detection

# Set environment variable based on protocol
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=PROTO:https]

RewriteCond %{HTTPS} off
RewriteRule ^ - [E=PROTO:http]

Load-Balanced Environments

# Handle X-Forwarded-Proto headers in cloud environments
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

To verify your rules are working:

# Create a test endpoint
RewriteRule ^test-protocol$ - [E=INFO:https=%{HTTPS},host=%{HTTP_HOST}]
Header set X-Protocol-Info "%{INFO}e" env=INFO

When working with these conditions:

  • Place protocol checks early in your ruleset
  • Combine multiple conditions where possible
  • Avoid redundant checks for the same protocol