Mastering Apache mod_rewrite: Comprehensive Guide to URL Redirection, HTTP/HTTPS Switching, and Regex Pattern Optimization


4 views

At its core, mod_rewrite operates through a simple but powerful syntax:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule pattern substitution [flags]
</IfModule>

The real magic happens in the pattern matching using PCRE (Perl Compatible Regular Expressions). Here's a basic example that forces HTTPS:

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Understanding these PCRE patterns is crucial:

  • ^ - Start of string anchor
  • $ - End of string anchor
  • (.*) - Captures any character (except newline)
  • ([a-z]+) - Matches one or more lowercase letters
  • \d{4} - Matches exactly 4 digits

Here are practical examples you'll frequently encounter:

1. HTTP to HTTPS Redirect

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

2. Non-www to www

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

3. Old URL to New URL

RewriteEngine On
RewriteRule ^old-page\.html$ /new-page.html [R=301,L]

Enable logging in your Apache config:

RewriteLog "/var/log/apache2/rewrite.log"
RewriteLogLevel 3

Use the NC (no case) and OR flags carefully:

RewriteRule ^product/([0-9]+)/?$ /prod.php?id=$1 [NC,L]
  • Place frequently accessed rules first
  • Use [L] flag to stop processing when matched
  • Avoid complex regex in high-traffic scenarios
  • Consider using Redirect or RedirectMatch for simple cases

Here's a complex rule that handles multiple conditions:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/static/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]

This rule:

  1. Excludes /static/ directory
  2. Checks if requested file doesn't exist
  3. Checks if requested directory doesn't exist
  4. Routes everything else to index.php

Always use 301 (permanent) redirects for moved content:

Redirect 301 /old-path.html /new-path.html

For parameter changes while maintaining SEO value:

RewriteRule ^category/([^/]+)/([^/]+)/?$ /products.php?cat=$1&subcat=$2 [L]

Apache's mod_rewrite module provides a powerful way to manipulate URLs through rule-based rewriting. The basic syntax follows this structure:

RewriteEngine On
RewriteCond %{REQUEST_URI} pattern [flags]
RewriteRule pattern substitution [flags]

mod_rewrite uses Perl-compatible regular expressions (PCRE). Key patterns include:

  • ^ - Start of string
  • $ - End of string
  • . - Any single character
  • * - Zero or more of preceding element
  • + - One or more of preceding element
  • ? - Makes preceding element optional

HTTP to HTTPS Redirection

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

URL Format Conversion

Convert ?id=123 to /id/123:

RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^(.*)$ /id/%1? [R=301,L]

Enable logging for troubleshooting:

RewriteLog "/path/to/rewrite.log"
RewriteLogLevel 3

Keep these in mind:

  • Use [L] flag to stop processing further rules
  • Place most frequently matched rules first
  • Avoid complex regex patterns when possible

Watch out for:

  • Infinite redirect loops
  • Case sensitivity issues
  • Missing RewriteEngine On directive
  • Incorrect flag usage (e.g., forgetting [R] for external redirects)

Consider these when mod_rewrite might be overkill:

  • Use Redirect or RedirectMatch for simple redirects
  • Implement URL routing at application level when possible
  • Use Alias for simple path translations