Files
ngx_http_apache_rewrite_module/README.md
2026-03-23 15:11:12 +03:00

13 KiB

Apache mod_rewrite Compatibility Module for Nginx

This module provides Apache's mod_rewrite compatibility for Nginx, enabling .htaccess file support and standard rewrite rules.


Configuration Directives

The following directives are available in this module:

1. RewriteEngine

Purpose: Enable or disable the rewrite engine.

Context Available Levels
main, server, location ✓ All three levels supported

Syntax:

RewriteEngine on|off

Possible Values:

  • on - Enable rewrite engine
  • off - Disable rewrite engine (default)

Example in nginx.conf:

http {
    server {
        RewriteEngine on;

        location /blog/ {
            # Rules apply here
        }

        location /static/ {
            RewriteEngine off;  # Disable for this location
        }
    }
}

2. RewriteRule

Purpose: Define a rewrite rule that matches a URL pattern and substitutes it with a new value.

Context Available Levels
server, location ✓ Server and Location level
.htaccess ✓ Supported in .htaccess files

Syntax:

RewriteRule pattern substitution [flags]

Parameters:

  • pattern - Regular expression to match the URL (supports backreferences $1, $2, etc.)

    • Pattern can be prefixed with ! for negation
    • - as substitution means "no substitution" (only match for conditions)
  • substitution - Target URL or file path to rewrite to

    • Can be a relative path (/new/path) or absolute redirect (http://example.com/new)

Flags: [flag1,flag2,...] (optional):

Flag Abbreviation Description
B - Escape backreferences in output (prevent URL encoding issues)
C Chain Chain this rule with the next one (requires previous match)
D DPI Discard path info after substitution
E Env=var:val Set an environment variable for later use (FastCGI integration)
F Forbidden Return HTTP 403 Forbidden status
G Gone Return HTTP 410 Gone status
L Last Stop processing rules after this one
N Next=limit Loop (retry) up to N times for infinite rewriting prevention
P Proxy Proxy the request internally (Phase 2)
Q QSA Append original query string to substitution URL
Q QSD Discard original query string
Q QSL Set "query string last" marker
R Redirect=code Perform external redirect with status code (301, 302, 307) or: Permanent, Temp, SeeOther
S Skip=N Skip N subsequent rules after this one
T Type=mime Force specific MIME type for the response
NC - Case-insensitive matching
NOESCAPE - Do not escape special characters in output
END - Stop all rewriting and pass to content phase

Example:

# Redirect /old-path/ to /new-path/ (permanent redirect)
RewriteRule ^old-path/(.*)$ /new-path/$1 [R=301,L]

# Condition-based rewrite (chain)
RewriteCond %{REQUEST_URI} !^/admin/
RewriteRule ^admin/(.*)$ /login.php?user=$1 [NC,E,END]

# In .htaccess:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]

3. RewriteCond

Purpose: Define conditions that must be met before a RewriteRule is applied. Multiple conditions are ANDed together; OR flag can change this behavior.

Context Available Levels
server, location ✓ Server and Location level
.htaccess ✓ Supported in .htaccess files

Syntax:

RewriteCond input_string pattern [flags]

Parameters:

  • input_string - Variable or string to test (e.g., %REQUEST_URI, %HTTP_HOST, %REQUEST_FILENAME)

    • Common variables: REQUEST_URI, HTTP_HOST, REQUEST_METHOD, REQUEST_FILENAME
  • pattern - Test pattern for the condition:

    • File tests: -f (file exists), -d (directory exists), -x (executable), -s (non-zero size)
    • Link tests: -h or -l (hard/soft link), -L (link target exists)
    • Integer comparisons: -lt, -le, -eq, -gt, -ge, -ne
    • String comparisons: =, >, <, >=, <=
    • Regular expressions: Any regex pattern
  • flags (optional):

    • NC - Case-insensitive matching
    • OR / ornext - OR logic between conditions (instead of AND)

Examples:

# Condition: file exists
RewriteCond %{REQUEST_FILENAME} -f

# Condition: not a directory
RewriteCond %{REQUEST_FILENAME} !-d

# Condition: string comparison
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]

# Multiple conditions with OR logic
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{HTTPS} off

# Regular expression pattern
RewriteCond %{REQUEST_URI} ^/old/(.*)$

4. RewriteBase

Purpose: Set the base URL path for relative substitutions in rewrite rules.

Context Available Levels
location ✓ Location level only
.htaccess ✓ Supported in .htaccess files

Syntax:

RewriteBase /path/

Parameters:

  • Must start with / and end with / (trailing slash required)

Example:

# Inside a specific location
location /blog/ {
    RewriteBase /blog/

    # Relative substitution resolves to: /blog/news.html
    RewriteRule ^news\.html$ news.php [L]
}

# In .htaccess:
RewriteEngine on
RewriteBase /subdir/
RewriteRule ^index\.html$ home.php [L]

5. RewriteOptions

Purpose: Configure rewrite behavior options that affect rule inheritance and processing order.

Context Available Levels
main, server, location ✓ All three levels supported

Syntax:

RewriteOptions option1 [option2 ...]

Possible Options:

Option Description
Inherit Inherit rules from parent locations/servers (default behavior)
InheritBefore Process parent rules before child rules

Example:

http {
    server {
        RewriteOptions Inherit

        location /parent/ {
            RewriteRule ^parent/(.*)$ /new/$1 [L]
        }

        location /child/ {
            # Inherits rules from parent by default with 'Inherit' option
            RewriteBase /child/
        }
    }
}

6. RewriteMap

Purpose: Define name-value mappings for lookup tables in rewrite expressions.

Context Available Levels
server ✓ Server level only
.htaccess ✗ Not supported in .htaccess

Syntax:

RewriteMap name type:source

Parameters:

  • name - Map identifier (used as variable like %MAPNAME:value)
  • type - Type of map:
    • int - Internal function (supported: tolower, toupper, escape, unescape)
    • txt - Text file lookup (not supported yet)
    • rnd - Random lookup (not supported yet)
    • prg - Program lookup (not supported yet)

Example:

server {
    # Map to lowercase version of hostname
    RewriteMap lc int:tolower

    server_name example.com;

    location / {
        # Use mapped value in rule
        RewriteRule ^lc/([^/]+)$ /redirect/$1 [L]
    }
}

# Usage in rules:
RewriteRule ^(.*)$ /%lc:$1 [L]

7. HtaccessEnable

Purpose: Enable or disable .htaccess file parsing for the server/location.

Context Available Levels
main, server ✓ Main and Server level only
.htaccess ✗ Not supported in .htaccess

Syntax:

HtaccessEnable on|off

Parameters:

  • on - Enable .htaccess parsing
  • off - Disable .htaccess parsing (default)

Example:

http {
    server {
        HtaccessEnable on

        # .htaccess files will be searched upward from the request path
        location /subdir/ {
            root /var/www/html;
        }
    }
}

# In nginx.conf, you can also enable at http level:
http {
    HtaccessEnable on;

    server {
        # Inherits setting from http level
    }
}

8. HtaccessName

Purpose: Specify an alternative filename for .htaccess files.

Context Available Levels
main, server ✓ Main and Server level only
.htaccess ✗ Not supported in .htaccess

Syntax:

HtaccessName filename

Parameters:

  • Any string (default is .htaccess)

Example:

server {
    HtaccessName .webconfig

    # Will look for .webconfig files instead of .htaccess
    location / {
        root /var/www/html;
    }
}

# In .htaccess:
HtaccessEnable on
HtaccessName .custom_htac

9. RewriteFallBack

Purpose: Specify an alternative fallback path when the rewritten file doesn't exist (instead of default /index.php). This directive can only be used in .htaccess files and is read by ngx_htaccess_parse_file_from_ha(). The fallback path is cached per request and retrieved in ngx_http_apache_rewrite_url_register_hook_with_fallback().

Context Available Levels
.htaccess ✓ Supported only in .htaccess files

Syntax:

RewriteFallBack /path/to/fallback.php

Parameters:

  • Path must start with / (required)
  • Default fallback is /index.php if not specified

Example in .htaccess:

# Use custom fallback when file not found
RewriteFallBack /custom/app.php

# Fallback will redirect to /custom/app.php?query_string instead of /index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

Example with query string:

RewriteFallBack /handler.php?lang=ru

# When file doesn't exist, request is redirected to the fallback path
# preserving the original query string if present

Configuration Levels Summary

Directive http/main server location .htaccess
RewriteEngine
RewriteRule -
RewriteCond -
RewriteBase - -
RewriteOptions -
RewriteMap - - -
HtaccessEnable - -
HtaccessName - -
RewriteFallBack -

.htaccess File Format

.htaccess files follow the Apache format:

# Comments start with #
RewriteEngine on

RewriteCond %{REQUEST_URI} ^/old/(.*)$
RewriteRule ^old/(.*)$ /new/$1 [R=301,L]

# Multiple conditions (AND logic by default)
RewriteCond %{HTTP_HOST} www\.example\.com$
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

RewriteBase /subdir/
RewriteFallBack /custom/fallback.php
RewriteCond !-f
RewriteCond !-d
RewriteRule ^(.*)$ index.php?route=$1 [QSA,L]

When a file doesn't exist after URL rewriting, the module falls back to:

  1. RewriteFallBack path if specified in .htaccess, or
  2. /index.php as default fallback

Module Features

FastCGI Integration

The module automatically passes environment variables (set via [E=VAR:VAL] flags) to FastCGI applications without manual configuration.

Environment Variables

Environment variables persist across request phases and are available for downstream modules.

.htaccess Caching

.htaccess files are cached by modification time in the request pool to improve performance on repeated requests. The RewriteFallBack directive is also stored in the cache entry and retrieved when needed.

RewriteFallBack Directive

The RewriteFallBack directive allows customizing the fallback path used when a rewritten file doesn't exist:

  1. Caching: The fallback path from .htaccess is cached per request to avoid repeated parsing
  2. Fallback Logic: When try_files fails, the module redirects to the configured fallback instead of /index.php
  3. Query String Preservation: Original query string is preserved and appended to fallback path

Notes

  • Rewrite rules are processed in order as defined in configuration or .htaccess files
  • The [L] flag stops processing at the current rule
  • The [N] flag enables looping for infinite redirects prevention (max 10,000 rounds)
  • Location-level rules override server-level rules unless Inherit option is set