Added mod_rewrite for nginx module

This commit is contained in:
alexey
2026-03-23 01:15:59 +03:00
commit 0d2c6277e1
124 changed files with 11079 additions and 0 deletions

481
README.ru.md Normal file
View File

@@ -0,0 +1,481 @@
## Модуль совместимости Apache mod_rewrite для Nginx
Этот модуль обеспечивает совместимость Apache `mod_rewrite` для Nginx, позволяя использовать файлы `.htaccess` и стандартные правила переписывания.
---
# Директивы конфигурации
Ниже перечислены доступные директивы в этом модуле:
### 1. RewriteEngine
**Назначение:** Включить или отключить механизм переписывания.
| Контекст | Доступные уровни |
|----------|------------------|
| `main`, `server`, `location` | ✓ Поддерживаются все три уровня |
**Синтаксис:**
```nginx
RewriteEngine on|off
```
**Возможные значения:**
- `on` - Включить механизм переписывания
- `off` - Отключить механизм переписывания (по умолчанию)
**Пример в nginx.conf:**
```nginx
http {
server {
RewriteEngine on;
location /blog/ {
# Правила применяются здесь
}
location /static/ {
RewriteEngine off; # Отключить для этой локации
}
}
}
```
---
### 2. RewriteRule
**Назначение:** Определить правило переписывания, которое сопоставляет шаблон URL и заменяет его новым значением.
| Контекст | Доступные уровни |
|----------|------------------|
| `server`, `location` | ✓ Уровни сервера и локации |
| `.htaccess` | ✓ Поддерживается в файлах .htaccess |
**Синтаксис:**
```nginx
RewriteRule pattern substitution [flags]
```
**Параметры:**
- **pattern** - Регулярное выражение для сопоставления URL (поддерживаются обратные ссылки $1, $2 и т.д.)
- Паттерн может быть префиксирован `!` для отрицания
- `-` в качестве замены означает "нет замены" (только проверка условий)
- **substitution** - Целевой URL или путь файла для переписывания
- Может быть относительным путем (`/new/path`) или абсолютным перенаправлением (`http://example.com/new`)
**Флаги:** `[flag1,flag2,...]` (необязательно):
| Флаг | Короткая запись | Описание |
|------|-----------------|----------|
| `B` | - | Экранировать обратные ссылки в выводе (предотвратить проблемы с кодировкой URL) |
| `C` | Chain | Присоединить это правило к следующему (требует предыдущего совпадения) |
| `D` | DPI | Отбросить информацию о пути после замены |
| `E` | Env=var:val | Установить переменную окружения для последующего использования (FastCGI интеграция) |
| `F` | Forbidden | Вернуть статус HTTP 403 Forbidden |
| `G` | Gone | Вернуть статус HTTP 410 Gone |
| `L` | Last | Остановить обработку правил после этого |
| `N` | Next=limit | Цикл (повторить) до N раз для предотвращения бесконечных переписываний |
| `P` | Proxy | Проксировать запрос внутренне (Фаза 2) |
| `Q` | QSA | Прикрепить исходную строку запроса к URL замены |
| `Q` | QSD | Удалить исходную строку запроса |
| `Q` | QSL | Установить маркер "query string last" |
| `R` | Redirect=code | Выполнить внешнее перенаправление со статусом (301, 302, 307) или: Permanent, Temp, SeeOther |
| `S` | Skip=N | Пропустить N последующих правил после этого |
| `T` | Type=mime | Принудительно установить MIME-тип для ответа |
| `NC` | - | Непрерывное сопоставление без учета регистра |
| `NOESCAPE` | - | Не экранировать специальные символы в выводе |
| `END`| - | Остановить все переписывания и перейти к фазе контента |
**Пример:**
```nginx
# Перенаправление /old-path/ в /new-path/ (постоянное перенаправление)
RewriteRule ^old-path/(.*)$ /new-path/$1 [R=301,L]
# Условное переписывание (цепочка)
RewriteCond %REQUEST_URI !^/admin/
RewriteRule ^admin/(.*)$ /login.php?user=$1 [NC,E,END]
# В .htaccess:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
```
---
### 3. RewriteCond
**Назначение:** Определить условия, которые должны быть выполнены, прежде чем будет применено правило `RewriteRule`. Множественные условия объединяются по умолчанию (AND); можно изменить это с помощью флага OR.
| Контекст | Доступные уровни |
|----------|------------------|
| `server`, `location` | ✓ Уровни сервера и локации |
| `.htaccess` | ✓ Поддерживается в файлах .htaccess |
**Синтаксис:**
```nginx
RewriteCond input_string pattern [flags]
```
**Параметры:**
- **input_string** - Переменная или строка для проверки (например, `%REQUEST_URI`, `%HTTP_HOST`, `%REQUEST_METHOD`, `%REQUEST_FILENAME`)
- Общие переменные: `REQUEST_URI`, `HTTP_HOST`, `REQUEST_METHOD`, `REQUEST_FILENAME`
- **pattern** - Шаблон проверки:
- **Тесты файлов:** `-f` (файл существует), `-d` (директория существует), `-x` (исполняемый), `-s` (не нулевой размер)
- **Тесты ссылок:** `-h` или `-l` (жёсткая/мягкая ссылка), `-L` (цель ссылки существует)
- **Сравнение целых чисел:** `-lt`, `-le`, `-eq`, `-gt`, `-ge`, `-ne`
- **Сравнение строк:** `=`, `>`, `<`, `>=`, `<=`
- **Регулярные выражения:** любой шаблон regex
- **flags** (необязательно):
- `NC` - Не чувствительно к регистру
- `OR` / `ornext` - Логика OR между условиями (вместо AND)
**Примеры:**
```nginx
# Условие: файл существует
RewriteCond %REQUEST_FILENAME -f
# Условие: не директория
RewriteCond %REQUEST_FILENAME !-d
# Сравнение строк
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
# Сравнение целых чисел (размер файла > 1024 байт)
RewriteCond %REQUEST_FILENAME -s
RewriteCond %{FILESIZE} -gt 1024
# Множественные условия с OR
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{HTTPS} off
# Регулярный шаблон
RewriteCond %{REQUEST_URI} ^/old/(.*)$
```
---
### 4. RewriteBase
**Назначение:** Установить базовый URL-путь для относительных замен в правилах переписывания.
| Контекст | Доступные уровни |
|----------|------------------|
| `location` | ✓ Только уровень локации |
| `.htaccess` | ✓ Поддерживается в файлах .htaccess |
**Синтаксис:**
```nginx
RewriteBase /path/
```
**Параметры:**
- Должен начинаться с `/` и заканчиваться `/` (обязательный слеш)
**Пример:**
```nginx
# Внутри конкретной локации
location /blog/ {
RewriteBase /blog/
# Относительная замена разрешается: /blog/news.html
RewriteRule ^news\.html$ news.php [L]
}
# В .htaccess:
RewriteEngine on
RewriteBase /subdir/
RewriteRule ^index\.html$ home.php [L]
```
---
### 5. RewriteOptions
**Назначение:** Настроить параметры поведения переписывания, которые влияют на наследование правил и порядок их обработки.
| Контекст | Доступные уровни |
|----------|------------------|
| `main`, `server`, `location` | ✓ Все три уровня поддерживаются |
**Синтаксис:**
```nginx
RewriteOptions option1 [option2 ...]
```
**Возможные опции:**
| Опция | Описание |
|----------------|----------|
| `Inherit` | Наследовать правила из родительских локаций/серверов (поведение по умолчанию) |
| `InheritBefore` | Обрабатывать правила родительских локаций до правил дочерних |
**Пример:**
```nginx
http {
server {
RewriteOptions Inherit
location /parent/ {
RewriteRule ^parent/(.*)$ /new/$1 [L]
}
location /child/ {
# Наследует правила от родителя по умолчанию с опцией 'Inherit'
RewriteBase /child/
}
}
}
```
---
### 6. RewriteMap
**Назначение:** Определить имя‑значение карты для поиска таблиц в выражениях переписывания.
| Контекст | Доступные уровни |
|----------|------------------|
| `server` | ✓ Только уровень сервера |
| `.htaccess` | ✗ Не поддерживается в .htaccess |
**Синтаксис:**
```nginx
RewriteMap name type:source
```
**Параметры:**
- **name** - Идентификатор карты (используется как переменная, например `%MAPNAME:value`)
- **type** - Тип карты:
- `int` - Внутренняя функция (поддерживаемые: `tolower`, `toupper`, `escape`, `unescape`)
- `txt` - Поиск по текстовому файлу (пока не реализовано)
- `rnd` - Поиск по случайному (пока не реализовано)
- `prg` - Поиск по программе (пока не реализовано)
**Пример:**
```nginx
server {
# Карта к нижнему регистру имени хоста
RewriteMap lc int:tolower
server_name example.com;
location / {
# Использовать сопоставленное значение в правиле
RewriteRule ^lc/([^/]+)$ /redirect/$1 [L]
}
}
# Использование в правилах:
RewriteRule ^(.*)$ /%lc:$1 [L]
```
---
### 7. HtaccessEnable
**Назначение:** Включить или отключить разбор файлов `.htaccess` для сервера/локации.
| Контекст | Доступные уровни |
|----------|------------------|
| `main`, `server` | ✓ Только уровни основного и сервера |
| `.htaccess` | ✗ Не поддерживается в .htaccess |
**Синтаксис:**
```nginx
HtaccessEnable on|off
```
**Параметры:**
- `on` - Включить разбор `.htaccess`
- `off` - Отключить разбор `.htaccess` (по умолчанию)
**Пример:**
```nginx
http {
server {
HtaccessEnable on
# Файлы .htaccess будут искаться вверх от пути запроса
location /subdir/ {
root /var/www/html;
}
}
}
# В nginx.conf, можно включить на уровне http:
http {
HtaccessEnable on;
server {
# Наследует настройку из уровня http
}
}
```
---
### 8. HtaccessName
**Назначение:** Указать альтернативное имя файла для файлов `.htaccess`.
| Контекст | Доступные уровни |
|----------|------------------|
| `main`, `server` | ✓ Только уровни основного и сервера |
| `.htaccess` | ✗ Не поддерживается в .htaccess |
**Синтаксис:**
```nginx
HtaccessName filename
```
**Параметры:**
- Любая строка (по умолчанию `.htaccess`)
**Пример:**
```nginx
server {
HtaccessName .webconfig
# Будет искать файлы .webconfig вместо .htaccess
location / {
root /var/www/html;
}
}
# В .htaccess:
HtaccessEnable on
HtaccessName .custom_htac
```
---
### 9. RewriteFallBack
**Назначение:** Указать альтернативный путь отката, если переписанный файл не существует (вместо стандартного `/index.php`). Эта директива может использоваться только в файлах `.htaccess` и читается функцией `ngx_htaccess_parse_file_from_ha()`. Путь отката кэшируется для каждого запроса и извлекается в `ngx_http_apache_rewrite_url_register_hook_with_fallback()`.
| Контекст | Доступные уровни |
|-----------------|----------------------------------------------|
| `.htaccess` | ✓ Поддерживается только в файлах .htaccess |
**Синтаксис:**
```apache
RewriteFallBack /path/to/fallback.php
```
**Параметры:**
- Путь должен начинаться с `/` (обязательно)
- По умолчанию путь отката `/index.php`, если не указан
**Пример в .htaccess:**
```apache
# Использовать пользовательский откат, если файл не найден
RewriteFallBack /custom/app.php
# Откат перенаправит на /custom/app.php?query_string вместо /index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
```
**Пример с параметром строки запроса:**
```apache
RewriteFallBack /handler.php?lang=ru
# Если файл не существует, запрос будет перенаправлен на путь отката
# с сохранением исходной строки запроса, если она присутствует
```
---
## Сводка уровней конфигурации
| Директива | http/main | server | location | .htaccess |
|------------------|-----------|--------|----------|-----------|
| RewriteEngine | ✓ | ✓ | ✓ | ✓ |
| RewriteRule | - | ✓ | ✓ | ✓ |
| RewriteCond | - | ✓ | ✓ | ✓ |
| RewriteBase | - | - | ✓ | ✓ |
| RewriteOptions | ✓ | ✓ | ✓ | - |
| RewriteMap | - | ✓ | - | - |
| HtaccessEnable | ✓ | ✓ | - | - |
| HtaccessName | ✓ | ✓ | - | - |
| RewriteFallBack | ✗ | ✗ | - | ✓ |
---
## Формат файла .htaccess
Файлы `.htaccess` следуют формату Apache:
```apache
# Комментарии начинаются с #
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/old/(.*)$
RewriteRule ^old/(.*)$ /new/$1 [R=301,L]
# Множественные условия (логика AND по умолчанию)
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]
```
Если после переписывания URL файл не существует, модуль переходит к:
1. Путь `RewriteFallBack`, если указан в `.htaccess`, или
2. `/index.php` как стандартный откат
```
---
## Возможности модуля
### Интеграция с FastCGI
Модуль автоматически передаёт переменные окружения (установленные через флаги `[E=VAR:VAL]`) в приложения FastCGI без дополнительной настройки.
### Переменные окружения
Переменные окружения сохраняются между фазами запроса и доступны downstream-модулям.
### Кэширование .htaccess
Файлы `.htaccess` кэшируются по времени изменения в памяти запроса, чтобы ускорить повторные запросы.
### Директива RewriteFallBack
Директива `RewriteFallBack` позволяет настроить путь отката, который используется, когда переписанный файл не существует:
1. **Кеширование:** Путь отката из `.htaccess` кэшируется на каждый запрос, чтобы избежать повторного разборов.
2. **Логика отката:** Когда `try_files` завершается неудачей, модуль перенаправляет на заданный откат вместо `/index.php`.
3. **Сохранение строки запроса:** Исходная строка запроса сохраняется и добавляется к пути отката.
```
---
## Заметки
- Правила переписывания обрабатываются в порядке, определенном в конфигурации или файлах `.htaccess`
- Флаг `[L]` останавливает обработку на текущем правиле
- Флаг `[N]` включает цикл для предотвращения бесконечных перенаправлений (максимум 10000 раундов)
- Правила уровня локации переопределяют правила уровня сервера, если не задана опция `Inherit`