482 lines
19 KiB
Markdown
482 lines
19 KiB
Markdown
## Модуль совместимости 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]` включает цикл для предотвращения бесконечных перенаправлений (максимум 10 000 раундов)
|
||
- Правила уровня локации переопределяют правила уровня сервера, если не задана опция `Inherit`
|