Compare commits
7 Commits
c74ae3bec6
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
842ddd80b1 | ||
|
|
252170f667 | ||
|
|
bf484db84e | ||
|
|
1b37117a09 | ||
|
|
da7c38a0c6 | ||
|
|
7b16ebc72f | ||
|
|
2cb396b1d0 |
@@ -188,6 +188,7 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Или сборка руками с помощью сборочного скрипта, вызывать в корне проекта:
|
Или сборка руками с помощью сборочного скрипта, вызывать в корне проекта:
|
||||||
|
|
||||||
|
|||||||
80
README.md
80
README.md
@@ -15,6 +15,54 @@ The following directives are available in this module:
|
|||||||
| Context | Available Levels |
|
| Context | Available Levels |
|
||||||
|----------------|---------------------------------------------|
|
|----------------|---------------------------------------------|
|
||||||
| `main`, `server`, `location` | ✓ All three levels supported |
|
| `main`, `server`, `location` | ✓ All three levels supported |
|
||||||
|
| `GlobalLocation` | ✓ Global location level (new) |
|
||||||
|
|
||||||
|
**Syntax:**
|
||||||
|
```nginx
|
||||||
|
RewriteEngine on|off
|
||||||
|
```
|
||||||
|
|
||||||
|
**Possible Values:**
|
||||||
|
- `on` - Enable rewrite engine
|
||||||
|
- `off` - Disable rewrite engine (default)
|
||||||
|
|
||||||
|
**Example in nginx.conf:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
server {
|
||||||
|
RewriteEngine on;
|
||||||
|
|
||||||
|
location /blog/ {
|
||||||
|
# Rules apply here
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
RewriteEngine off; # Disable for this location
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**GlobalLocation Configuration (new):**
|
||||||
|
The `GlobalLocationRewriteEngine` directive allows setting the rewrite engine state for server-level locations:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
server {
|
||||||
|
GlobalLocationRewriteEngine on;
|
||||||
|
|
||||||
|
# All locations in this server inherit the global setting
|
||||||
|
|
||||||
|
location /blog/ {
|
||||||
|
# RewriteEngine is enabled by default
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
RewriteEngine off; # Override for this location if needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Syntax:**
|
**Syntax:**
|
||||||
```nginx
|
```nginx
|
||||||
@@ -395,17 +443,18 @@ RewriteFallBack /handler.php?lang=ru
|
|||||||
|
|
||||||
## Configuration Levels Summary
|
## Configuration Levels Summary
|
||||||
|
|
||||||
| Directive | http/main | server | location | .htaccess |
|
| Directive | http/main | server | location | .htaccess |
|
||||||
|-----------------|-----------|--------|----------|-----------|
|
|--------------------------|-----------|--------|----------|-----------|
|
||||||
| RewriteEngine | ✓ | ✓ | ✓ | ✓ |
|
| RewriteEngine | ✓ | ✓ | ✓ | ✓ |
|
||||||
| RewriteRule | - | ✓ | ✓ | ✓ |
|
| GlobalLocationRewriteEngine | - | ✓ | - | - |
|
||||||
| RewriteCond | - | ✓ | ✓ | ✓ |
|
| RewriteRule | - | ✓ | ✓ | ✓ |
|
||||||
| RewriteBase | - | - | ✓ | ✓ |
|
| RewriteCond | - | ✓ | ✓ | ✓ |
|
||||||
| RewriteOptions | ✓ | ✓ | ✓ | - |
|
| RewriteBase | - | - | ✓ | ✓ |
|
||||||
| RewriteMap | - | ✓ | - | - |
|
| RewriteOptions | ✓ | ✓ | ✓ | - |
|
||||||
| HtaccessEnable | ✓ | ✓ | - | - |
|
| RewriteMap | - | ✓ | - | - |
|
||||||
| HtaccessName | ✓ | ✓ | - | - |
|
| HtaccessEnable | ✓ | ✓ | - | - |
|
||||||
| RewriteFallBack | ✗ | ✗ | - | ✓ |
|
| HtaccessName | ✓ | ✓ | - | - |
|
||||||
|
| RewriteFallBack | ✗ | ✗ | - | ✓ |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -458,6 +507,15 @@ The `RewriteFallBack` directive allows customizing the fallback path used when a
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### GlobalLocationRewriteEngine Directive (new)
|
||||||
|
The `GlobalLocationRewriteEngine` directive allows setting the rewrite engine state for server-level locations:
|
||||||
|
|
||||||
|
1. **Scope:** Configured only at the server block level within http context
|
||||||
|
2. **Inheritance:** All new locations inherit the global configuration by default
|
||||||
|
3. **Override Support:** Individual locations can still override the global setting with their own `RewriteEngine` directive
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Rewrite rules are processed in order as defined in configuration or `.htaccess` files
|
- Rewrite rules are processed in order as defined in configuration or `.htaccess` files
|
||||||
|
|||||||
60
README.ru.md
60
README.ru.md
@@ -42,6 +42,27 @@ http {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Конфигурация GlobalLocation (новое):**
|
||||||
|
Директива `GlobalLocationRewriteEngine` позволяет установить состояние движка переписывания для всех location этого сервера:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
server {
|
||||||
|
GlobalLocationRewriteEngine on;
|
||||||
|
|
||||||
|
# Все location в этом сервере наследуют глобальную настройку
|
||||||
|
|
||||||
|
location /blog/ {
|
||||||
|
# RewriteEngine включён по умолчанию
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
RewriteEngine off; # Можно переопределить для этой локации
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
@@ -400,19 +421,29 @@ RewriteFallBack /handler.php?lang=ru
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Директива GlobalLocationRewriteEngine (новое)
|
||||||
|
Директива `GlobalLocationRewriteEngine` позволяет установить состояние движка переписывания для всех location этого сервера:
|
||||||
|
|
||||||
|
1. **Область применения:** Настраивается только на уровне server внутри http контекста
|
||||||
|
2. **Наследование:** Все новые location наследуют глобальную конфигурацию по умолчанию
|
||||||
|
3. **Переопределение:** Отдельные location могут переопределить глобальную настройку своей собственной директивой `RewriteEngine`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Сводка уровней конфигурации
|
## Сводка уровней конфигурации
|
||||||
|
|
||||||
| Директива | http/main | server | location | .htaccess |
|
| Директива | http/main | server | location | .htaccess |
|
||||||
|------------------|-----------|--------|----------|-----------|
|
|-------------------------------|-----------|--------|----------|-----------|
|
||||||
| RewriteEngine | ✓ | ✓ | ✓ | ✓ |
|
| RewriteEngine | ✓ | ✓ | ✓ | ✓ |
|
||||||
| RewriteRule | - | ✓ | ✓ | ✓ |
|
| GlobalLocationRewriteEngine | - | ✓ | - | - |
|
||||||
| RewriteCond | - | ✓ | ✓ | ✓ |
|
| RewriteRule | - | ✓ | ✓ | ✓ |
|
||||||
| RewriteBase | - | - | ✓ | ✓ |
|
| RewriteCond | - | ✓ | ✓ | ✓ |
|
||||||
| RewriteOptions | ✓ | ✓ | ✓ | - |
|
| RewriteBase | - | - | ✓ | ✓ |
|
||||||
| RewriteMap | - | ✓ | - | - |
|
| RewriteOptions | ✓ | ✓ | ✓ | - |
|
||||||
| HtaccessEnable | ✓ | ✓ | - | - |
|
| RewriteMap | - | ✓ | - | - |
|
||||||
| HtaccessName | ✓ | ✓ | - | - |
|
| HtaccessEnable | ✓ | ✓ | - | - |
|
||||||
| RewriteFallBack | ✗ | ✗ | - | ✓ |
|
| HtaccessName | ✓ | ✓ | - | - |
|
||||||
|
| RewriteFallBack | ✗ | ✗ | - | ✓ |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -465,6 +496,13 @@ RewriteRule ^(.*)$ index.php?route=$1 [QSA,L]
|
|||||||
1. **Кеширование:** Путь отката из `.htaccess` кэшируется на каждый запрос, чтобы избежать повторного разборов.
|
1. **Кеширование:** Путь отката из `.htaccess` кэшируется на каждый запрос, чтобы избежать повторного разборов.
|
||||||
2. **Логика отката:** Когда `try_files` завершается неудачей, модуль перенаправляет на заданный откат вместо `/index.php`.
|
2. **Логика отката:** Когда `try_files` завершается неудачей, модуль перенаправляет на заданный откат вместо `/index.php`.
|
||||||
3. **Сохранение строки запроса:** Исходная строка запроса сохраняется и добавляется к пути отката.
|
3. **Сохранение строки запроса:** Исходная строка запроса сохраняется и добавляется к пути отката.
|
||||||
|
|
||||||
|
### Директива GlobalLocationRewriteEngine (новое)
|
||||||
|
Директива `GlobalLocationRewriteEngine` позволяет установить состояние движка переписывания для всех location этого сервера:
|
||||||
|
|
||||||
|
1. **Область применения:** Настраивается только на уровне server внутри http контекста
|
||||||
|
2. **Наследование:** Все новые location наследуют глобальную конфигурацию по умолчанию
|
||||||
|
3. **Переопределение:** Отдельные location могут переопределить глобальную настройку своей собственной директивой `RewriteEngine`
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ def main(nginx_src_dir="."):
|
|||||||
|
|
||||||
# Добавляем наш модуль в конец
|
# Добавляем наш модуль в конец
|
||||||
args_list.append("--add-dynamic-module=../modules/mod_rewrite")
|
args_list.append("--add-dynamic-module=../modules/mod_rewrite")
|
||||||
|
#args_list.append("--with-debug")
|
||||||
|
|
||||||
print(f"Added --add-dynamic-module=../modules/mod_rewrite", file=sys.stderr)
|
print(f"Added --add-dynamic-module=../modules/mod_rewrite", file=sys.stderr)
|
||||||
|
|
||||||
|
|||||||
@@ -479,12 +479,11 @@ ngx_rewrite_apply_rule(ngx_rewrite_rule_t *rule, ngx_rewrite_ctx_t *ctx, ngx_str
|
|||||||
"mod_rewrite: rewrite \"%V\" -> \"%V\" (flags=0x%xd, code=%d)",
|
"mod_rewrite: rewrite \"%V\" -> \"%V\" (flags=0x%xd, code=%d)",
|
||||||
&ctx->uri, &newuri, rule->flags, rule->forced_responsecode);
|
&ctx->uri, &newuri, rule->flags, rule->forced_responsecode);
|
||||||
|
|
||||||
/* Split out query string */
|
|
||||||
{
|
ngx_str_t new_args = r->args;
|
||||||
ngx_str_t new_args = r->args;
|
ngx_rewrite_splitout_queryargs(r, &newuri, rule->flags, &new_args);
|
||||||
ngx_rewrite_splitout_queryargs(r, &newuri, rule->flags, &new_args);
|
r->args = new_args;
|
||||||
r->args = new_args;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for absolute URI → redirect */
|
/* Check for absolute URI → redirect */
|
||||||
if (rule->flags & RULEFLAG_FORCEREDIRECT) {
|
if (rule->flags & RULEFLAG_FORCEREDIRECT) {
|
||||||
@@ -539,7 +538,7 @@ ngx_rewrite_apply_rule(ngx_rewrite_rule_t *rule, ngx_rewrite_ctx_t *ctx, ngx_str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
len = scheme.len + 3 + host.len + newuri.len + 3;
|
len = scheme.len + 3 + host.len + newuri.len + 3 + new_args.len + 2;
|
||||||
if (port) {
|
if (port) {
|
||||||
len += 6; /* :NNNNN */
|
len += 6; /* :NNNNN */
|
||||||
}
|
}
|
||||||
@@ -568,6 +567,10 @@ ngx_rewrite_apply_rule(ngx_rewrite_rule_t *rule, ngx_rewrite_ctx_t *ctx, ngx_str
|
|||||||
*p++ = '/';
|
*p++ = '/';
|
||||||
}
|
}
|
||||||
p = ngx_cpymem(p, newuri.data, newuri.len);
|
p = ngx_cpymem(p, newuri.data, newuri.len);
|
||||||
|
if (new_args.len > 0) {
|
||||||
|
*p++ = '?';
|
||||||
|
p = ngx_cpymem(p, new_args.data, new_args.len);
|
||||||
|
}
|
||||||
newuri.data = start;
|
newuri.data = start;
|
||||||
newuri.len = p - start;
|
newuri.len = p - start;
|
||||||
}
|
}
|
||||||
@@ -587,8 +590,32 @@ ngx_rewrite_apply_rule(ngx_rewrite_rule_t *rule, ngx_rewrite_ctx_t *ctx, ngx_str
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx->redirect_url = newuri;
|
ctx->redirect_url = newuri;
|
||||||
|
|
||||||
|
/* Append old query args if present */
|
||||||
|
if (new_args.len > 0 && ctx->redirect_url.data != NULL && ctx->redirect_url.len > 0) {
|
||||||
|
u_char *tmp_data;
|
||||||
|
size_t combined_len = ctx->redirect_url.len + 1 + new_args.len;
|
||||||
|
tmp_data = ngx_pnalloc(r->pool, combined_len);
|
||||||
|
if (tmp_data) {
|
||||||
|
u_char *start = tmp_data;
|
||||||
|
tmp_data = ngx_cpymem(tmp_data, ctx->redirect_url.data, ctx->redirect_url.len);
|
||||||
|
*tmp_data++ = '&';
|
||||||
|
tmp_data = ngx_cpymem(tmp_data, new_args.data, new_args.len);
|
||||||
|
ctx->redirect_url.data = start;
|
||||||
|
ctx->redirect_url.len = combined_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ctx->redirect_code = code;
|
ctx->redirect_code = code;
|
||||||
|
/* Update URI to include appended args (for subsequent processing) */
|
||||||
ctx->uri = newuri;
|
ctx->uri = newuri;
|
||||||
|
if (ctx->redirect_url.len > 0 && ctx->redirect_url.data != NULL
|
||||||
|
&& ngx_strcmp(ctx->uri.data, ctx->redirect_url.data) != 0) {
|
||||||
|
/* redirect_url has more data (args appended), copy it */
|
||||||
|
ctx->uri.data = ctx->redirect_url.data;
|
||||||
|
ctx->uri.len = ctx->redirect_url.len;
|
||||||
|
}
|
||||||
|
|
||||||
return RULE_RC_MATCH;
|
return RULE_RC_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,6 +655,7 @@ ngx_rewrite_apply_rule(ngx_rewrite_rule_t *rule, ngx_rewrite_ctx_t *ctx, ngx_str
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx->uri = newuri;
|
ctx->uri = newuri;
|
||||||
|
|
||||||
ngx_str_null(&ctx->redirect_url);
|
ngx_str_null(&ctx->redirect_url);
|
||||||
ctx->redirect_code = 0;
|
ctx->redirect_code = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -223,6 +223,8 @@ typedef struct {
|
|||||||
/* Fallback to index.php with query string after try_files miss */
|
/* Fallback to index.php with query string after try_files miss */
|
||||||
ngx_int_t fallback_to_index; // 0|1: enable fallback mechanism
|
ngx_int_t fallback_to_index; // 0|1: enable fallback mechanism
|
||||||
unsigned fallback_to_index_set:1;
|
unsigned fallback_to_index_set:1;
|
||||||
|
ngx_int_t glstate;
|
||||||
|
unsigned glstate_set:1;
|
||||||
} ngx_http_apache_rewrite_srv_conf_t;
|
} ngx_http_apache_rewrite_srv_conf_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ static ngx_int_t ngx_http_apache_rewrite_postconfiguration(ngx_conf_t *cf);
|
|||||||
|
|
||||||
static char *ngx_http_rewrite_engine(ngx_conf_t *cf, ngx_command_t *cmd,
|
static char *ngx_http_rewrite_engine(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *conf);
|
void *conf);
|
||||||
|
static char *ngx_http_rewrite_engine_global(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
|
void *conf);
|
||||||
static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd,
|
static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *conf);
|
void *conf);
|
||||||
static char *ngx_http_rewrite_cond(ngx_conf_t *cf, ngx_command_t *cmd,
|
static char *ngx_http_rewrite_cond(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
@@ -92,6 +94,12 @@ static ngx_command_t ngx_http_apache_rewrite_commands[] = {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
{ ngx_string("GlobalLocationRewriteEngine"),
|
||||||
|
NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||||
|
ngx_http_rewrite_engine_global,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("RewriteRule"),
|
{ ngx_string("RewriteRule"),
|
||||||
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
|
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
|
||||||
@@ -272,13 +280,11 @@ ngx_http_apache_rewrite_merge_srv_conf(ngx_conf_t *cf,
|
|||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ngx_http_apache_rewrite_loc_conf_t *
|
||||||
static void *
|
ngx_http_apache_rewrite_create_loc_conf_(ngx_pool_t *pool){
|
||||||
ngx_http_apache_rewrite_create_loc_conf(ngx_conf_t *cf)
|
|
||||||
{
|
|
||||||
ngx_http_apache_rewrite_loc_conf_t *conf;
|
ngx_http_apache_rewrite_loc_conf_t *conf;
|
||||||
|
|
||||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_apache_rewrite_loc_conf_t));
|
conf = ngx_pcalloc(pool, sizeof(ngx_http_apache_rewrite_loc_conf_t));
|
||||||
if (conf == NULL) {
|
if (conf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -286,8 +292,8 @@ ngx_http_apache_rewrite_create_loc_conf(ngx_conf_t *cf)
|
|||||||
conf->state = ENGINE_DISABLED;
|
conf->state = ENGINE_DISABLED;
|
||||||
conf->options = OPTION_NONE;
|
conf->options = OPTION_NONE;
|
||||||
|
|
||||||
conf->rules = ngx_array_create(cf->pool, 4, sizeof(ngx_rewrite_rule_t));
|
conf->rules = ngx_array_create(pool, 4, sizeof(ngx_rewrite_rule_t));
|
||||||
conf->pending_conds = ngx_array_create(cf->pool, 4,
|
conf->pending_conds = ngx_array_create(pool, 4,
|
||||||
sizeof(ngx_rewrite_cond_t));
|
sizeof(ngx_rewrite_cond_t));
|
||||||
|
|
||||||
if (conf->rules == NULL || conf->pending_conds == NULL) {
|
if (conf->rules == NULL || conf->pending_conds == NULL) {
|
||||||
@@ -299,6 +305,12 @@ ngx_http_apache_rewrite_create_loc_conf(ngx_conf_t *cf)
|
|||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
ngx_http_apache_rewrite_create_loc_conf(ngx_conf_t *cf)
|
||||||
|
{
|
||||||
|
return ngx_http_apache_rewrite_create_loc_conf_(cf->pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
ngx_http_apache_rewrite_merge_loc_conf(ngx_conf_t *cf,
|
ngx_http_apache_rewrite_merge_loc_conf(ngx_conf_t *cf,
|
||||||
@@ -775,6 +787,9 @@ ngx_htaccess_search_upward(ngx_http_request_t *r, u_char *docroot, size_t docroo
|
|||||||
u_char *path_buf = (u_char *)ngx_palloc(r->pool, current_path->len + 1 + htaccess_name_len);
|
u_char *path_buf = (u_char *)ngx_palloc(r->pool, current_path->len + 1 + htaccess_name_len);
|
||||||
size_t current_pos;
|
size_t current_pos;
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: try to find .htaccess %s, uri=\"%V\"", path_buf, &r->uri);
|
||||||
|
|
||||||
if (!path_buf) {
|
if (!path_buf) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@@ -792,6 +807,8 @@ ngx_htaccess_search_upward(ngx_http_request_t *r, u_char *docroot, size_t docroo
|
|||||||
/* Iterate upward from current directory up to docroot */
|
/* Iterate upward from current directory up to docroot */
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Check if file exists at this level */
|
/* Check if file exists at this level */
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: try to find(1) .htaccess %s, uri=\"%V\"", path_buf, &r->uri);
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat((char *)path_buf, &st) == 0 && ngx_is_file(&st)) {
|
if (stat((char *)path_buf, &st) == 0 && ngx_is_file(&st)) {
|
||||||
/* Found .htaccess! */
|
/* Found .htaccess! */
|
||||||
@@ -812,6 +829,8 @@ ngx_htaccess_search_upward(ngx_http_request_t *r, u_char *docroot, size_t docroo
|
|||||||
|
|
||||||
if (last_slash == NULL) {
|
if (last_slash == NULL) {
|
||||||
/* Reached DocRoot without finding htaccess */
|
/* Reached DocRoot without finding htaccess */
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: try to find .htaccess %s, uri=\"%V\" error(1)", path_buf, &r->uri);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,6 +839,8 @@ ngx_htaccess_search_upward(ngx_http_request_t *r, u_char *docroot, size_t docroo
|
|||||||
|
|
||||||
if (current_pos < docroot_len) {
|
if (current_pos < docroot_len) {
|
||||||
/* Reached or passed DocRoot - no htaccess found */
|
/* Reached or passed DocRoot - no htaccess found */
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: try to find .htaccess %s, uri=\"%V\" error(2)", path_buf, &r->uri);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1485,6 +1506,7 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r)
|
|||||||
ngx_str_t baseurl_htacess = ngx_null_string;
|
ngx_str_t baseurl_htacess = ngx_null_string;
|
||||||
ngx_int_t options_htaccess = -1;
|
ngx_int_t options_htaccess = -1;
|
||||||
ngx_int_t state_htaccess = -1;
|
ngx_int_t state_htaccess = -1;
|
||||||
|
ngx_int_t global_enabled = 0;
|
||||||
|
|
||||||
(void)options_htaccess;
|
(void)options_htaccess;
|
||||||
|
|
||||||
@@ -1492,12 +1514,30 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r)
|
|||||||
sconf = ngx_http_get_module_srv_conf(r, ngx_http_apache_rewrite_module);
|
sconf = ngx_http_get_module_srv_conf(r, ngx_http_apache_rewrite_module);
|
||||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
if (lcf == NULL || lcf->state != ENGINE_ENABLED) {
|
if (sconf != NULL && sconf->glstate_set == 1 && sconf->glstate == ENGINE_ENABLED) {
|
||||||
return NGX_DECLINED;
|
global_enabled = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lcf == NULL || lcf->state != ENGINE_ENABLED) {
|
||||||
|
if (global_enabled == 1) {
|
||||||
|
if (lcf == NULL) {
|
||||||
|
lcf = ngx_http_apache_rewrite_create_loc_conf_(r->pool);
|
||||||
|
}
|
||||||
|
if (lcf == NULL) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: location handler engine enabled in location, uri=\"%V\"", &r->uri);
|
||||||
|
|
||||||
/* Check htaccess parsing enable */
|
/* Check htaccess parsing enable */
|
||||||
if (!sconf->htaccess_enable_set || sconf->htaccess_enable != 1) {
|
if (!sconf->htaccess_enable_set || sconf->htaccess_enable != 1) {
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: location handler htaccess disabled, uri=\"%V\"", &r->uri);
|
||||||
/* Use only location rules */
|
/* Use only location rules */
|
||||||
if (lcf->rules->nelts == 0) {
|
if (lcf->rules->nelts == 0) {
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
@@ -1533,20 +1573,56 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r)
|
|||||||
u_char *htaccess_name = sconf->htaccess_name.data ? (u_char *)sconf->htaccess_name.data : (u_char *)".htaccess";
|
u_char *htaccess_name = sconf->htaccess_name.data ? (u_char *)sconf->htaccess_name.data : (u_char *)".htaccess";
|
||||||
size_t htaccess_name_len = sconf->htaccess_name.data ? sconf->htaccess_name.len : 9;
|
size_t htaccess_name_len = sconf->htaccess_name.data ? sconf->htaccess_name.len : 9;
|
||||||
|
|
||||||
/* Build initial path: docroot + r->uri */
|
|
||||||
ngx_str_t current_path;
|
ngx_str_t current_path;
|
||||||
rc = ngx_htaccess_build_path(r, clcf->root.data, clcf->root.len, ¤t_path, htaccess_name, htaccess_name_len);
|
ngx_str_t evaluated_root = {0, NULL};
|
||||||
|
size_t evaluated_root_len = 0;
|
||||||
|
|
||||||
|
/* Check if root contains variables and evaluate them */
|
||||||
|
if (clcf->root_lengths != NULL) {
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: root has script variables, evaluating");
|
||||||
|
|
||||||
|
/* Run the script to evaluate variables in clcf->root */
|
||||||
|
if (ngx_http_script_run(r, &evaluated_root,
|
||||||
|
clcf->root_lengths->elts, 0,
|
||||||
|
clcf->root_values->elts) == NULL) {
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
|
"mod_rewrite: failed to evaluate root path script");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluated_root_len = evaluated_root.len > 0 ? evaluated_root.len : 0;
|
||||||
|
|
||||||
|
/* LOG: Show evaluated root */
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: evaluated root path len=%uz", evaluated_root_len);
|
||||||
|
} else {
|
||||||
|
/* LOG: No script variables in root */
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: root has no script variables, using clcf->root directly");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build initial path: docroot + r->uri using evaluated or original root */
|
||||||
|
rc = ngx_htaccess_build_path(r,
|
||||||
|
evaluated_root.data ? evaluated_root.data : clcf->root.data,
|
||||||
|
evaluated_root.len > 0 ? evaluated_root.len : clcf->root.len,
|
||||||
|
¤t_path, htaccess_name, htaccess_name_len);
|
||||||
|
|
||||||
ngx_str_t htaccess_docroot = ngx_null_string;
|
ngx_str_t htaccess_docroot = ngx_null_string;
|
||||||
|
|
||||||
/* Remove last component (filename) to search from parent directory */
|
/* Remove last component (filename) to search from parent directory */
|
||||||
if (rc == NGX_OK && current_path.len > 0) {
|
if (rc == NGX_OK && current_path.len > 0) {
|
||||||
|
|
||||||
/* Search upward for .htaccess file */
|
/* Search upward for .htaccess file - use evaluated root here too! */
|
||||||
rc = ngx_htaccess_search_upward(r, clcf->root.data, clcf->root.len, ¤t_path,
|
rc = ngx_htaccess_search_upward(r,
|
||||||
htaccess_name, htaccess_name_len, &htaccess_path);
|
evaluated_root.data ? evaluated_root.data : clcf->root.data,
|
||||||
|
evaluated_root.len > 0 ? evaluated_root.len : clcf->root.len,
|
||||||
|
¤t_path, htaccess_name, htaccess_name_len,
|
||||||
|
&htaccess_path);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: location handler .htaccess not found, uri=\"%V\"", &r->uri);
|
||||||
/* File not found — use only location rules */
|
/* File not found — use only location rules */
|
||||||
ctx = ngx_http_get_module_ctx(r, ngx_http_apache_rewrite_module);
|
ctx = ngx_http_get_module_ctx(r, ngx_http_apache_rewrite_module);
|
||||||
if (ctx && ctx->end) {
|
if (ctx && ctx->end) {
|
||||||
@@ -1558,18 +1634,35 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r)
|
|||||||
return ngx_process_rules_result(rc, ctx, r, 0);
|
return ngx_process_rules_result(rc, ctx, r, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
htaccess_docroot.data = ngx_pcalloc(r->pool, htaccess_path.len);
|
/* LOG: Show found htaccess path */
|
||||||
size_t htaccess_docroot_vlen = htaccess_path.len - (clcf->root.len + 1) - htaccess_name_len;
|
if (rc == NGX_OK && htaccess_path.data) {
|
||||||
if ((long)htaccess_docroot_vlen < 0) htaccess_docroot_vlen = 0;
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
ngx_memcpy(htaccess_docroot.data, htaccess_path.data + clcf->root.len + 1, htaccess_docroot_vlen);
|
"mod_rewrite: found .htaccess at: %V", &htaccess_path);
|
||||||
|
} else {
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: .htaccess not found, uri=%V", &r->uri);
|
||||||
|
}
|
||||||
|
|
||||||
htaccess_docroot.len = htaccess_path.len - (clcf->root.len + 1) - htaccess_name_len;
|
/* Extract htaccess_docroot path - now correctly works with evaluated root */
|
||||||
|
size_t used_root_len = (evaluated_root.len > 0) ? evaluated_root.len : clcf->root.len;
|
||||||
|
|
||||||
|
htaccess_docroot.data = ngx_pcalloc(r->pool, htaccess_path.len);
|
||||||
|
size_t htaccess_docroot_vlen = htaccess_path.len - (used_root_len + 1) - htaccess_name_len;
|
||||||
|
if ((long)htaccess_docroot_vlen < 0) htaccess_docroot_vlen = 0;
|
||||||
|
ngx_memcpy(htaccess_docroot.data, htaccess_path.data + used_root_len + 1, htaccess_docroot_vlen);
|
||||||
|
|
||||||
|
htaccess_docroot.len = htaccess_path.len - (used_root_len + 1) - htaccess_name_len;
|
||||||
|
} else {
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: failed to build current path for .htaccess search");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if htaccess file exists */
|
/* Check if htaccess file exists */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (!htaccess_path.data || stat((char *)htaccess_path.data, &st) == -1) {
|
if (!htaccess_path.data || stat((char *)htaccess_path.data, &st) == -1) {
|
||||||
/* File does not exist — use only location rules */
|
/* File does not exist — use only location rules */
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: location handler .htaccess nto found by stat, uri=\"%V\"", &r->uri);
|
||||||
if (lcf->rules->nelts == 0) {
|
if (lcf->rules->nelts == 0) {
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
}
|
}
|
||||||
@@ -1641,6 +1734,9 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r)
|
|||||||
/* If no cached rules, parse .htaccess file */
|
/* If no cached rules, parse .htaccess file */
|
||||||
if (combined_rules == NULL) {
|
if (combined_rules == NULL) {
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: location handler rules from .htaccess not in cache reread, .htaccess=\"%V\"", &htaccess_path);
|
||||||
|
|
||||||
parsed_rules = ngx_htaccess_parse_file_from_ha(r, &htaccess_path);
|
parsed_rules = ngx_htaccess_parse_file_from_ha(r, &htaccess_path);
|
||||||
|
|
||||||
if (!parsed_rules){
|
if (!parsed_rules){
|
||||||
@@ -1660,11 +1756,17 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r)
|
|||||||
/* Store in cache — add/update entry in linked list */
|
/* Store in cache — add/update entry in linked list */
|
||||||
ngx_htaccess_update_cache(r, htaccess_path, st.st_mtime, parsed_rules);
|
ngx_htaccess_update_cache(r, htaccess_path, st.st_mtime, parsed_rules);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: location handler get rules from cache .htaccess, .htaccess=\"%V\"", &htaccess_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state_htaccess == ENGINE_DISABLED)
|
if (state_htaccess == ENGINE_DISABLED)
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: location handler engine enabled in .htaccess, .htaccess=\"%V\"", &htaccess_path);
|
||||||
|
|
||||||
/* Ensure ctx exists */
|
/* Ensure ctx exists */
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
ctx = ngx_pcalloc(r->pool, sizeof(ngx_rewrite_ctx_t));
|
ctx = ngx_pcalloc(r->pool, sizeof(ngx_rewrite_ctx_t));
|
||||||
@@ -1685,7 +1787,8 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
/* Combine location rules with .htaccess rules (.htaccess has priority - added first) */
|
/* Combine location rules with .htaccess rules (.htaccess has priority - added first) */
|
||||||
ngx_int_t final_rc;
|
ngx_int_t final_rc;
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"mod_rewrite: location handler rules from .htaccess found %d, .htaccess=\"%V\"", combined_rules->nelts, &htaccess_path);
|
||||||
if (combined_rules->nelts > 0 && lcf->rules->nelts > 0) {
|
if (combined_rules->nelts > 0 && lcf->rules->nelts > 0) {
|
||||||
/* Create combined array: htaccess rules first, then location rules */
|
/* Create combined array: htaccess rules first, then location rules */
|
||||||
ngx_array_t *final_rules = ngx_array_create(r->pool,
|
ngx_array_t *final_rules = ngx_array_create(r->pool,
|
||||||
@@ -2177,6 +2280,48 @@ ngx_http_rewrite_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GlobalLocationRewriteEngine on|off
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
ngx_http_rewrite_engine_global(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
|
{
|
||||||
|
ngx_str_t *value;
|
||||||
|
ngx_http_apache_rewrite_srv_conf_t *sconf = NULL;
|
||||||
|
|
||||||
|
value = cf->args->elts;
|
||||||
|
|
||||||
|
/* Определяем контекст: проверяем cmd_type */
|
||||||
|
if (cf->cmd_type & NGX_HTTP_SRV_CONF) {
|
||||||
|
/* Server контекст */
|
||||||
|
sconf = ngx_http_conf_get_module_srv_conf(cf,
|
||||||
|
ngx_http_apache_rewrite_module);
|
||||||
|
if (sconf == NULL) {
|
||||||
|
return NGX_CONF_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_strcasecmp(value[1].data, (u_char *) "on") == 0) {
|
||||||
|
sconf->glstate = ENGINE_ENABLED;
|
||||||
|
sconf->glstate_set = 1;
|
||||||
|
} else if (ngx_strcasecmp(value[1].data, (u_char *) "off") == 0) {
|
||||||
|
sconf->glstate = ENGINE_DISABLED;
|
||||||
|
sconf->glstate_set = 1;
|
||||||
|
} else {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"GlobalLocationRewriteEngine: invalid value \"%V\"", &value[1]);
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Непредвиденный контекст */
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"GlobalLocationRewriteEngine: unexpected context");
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_CONF_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper: strip surrounding brackets [...]
|
* Helper: strip surrounding brackets [...]
|
||||||
|
|||||||
@@ -193,13 +193,17 @@ installmod)
|
|||||||
if command -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1; then
|
if command -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1; then
|
||||||
mkdir -p /usr/share/nginx/modules /usr/lib64/nginx/modules/
|
mkdir -p /usr/share/nginx/modules /usr/lib64/nginx/modules/
|
||||||
cp *.so /usr/lib64/nginx/modules/
|
cp *.so /usr/lib64/nginx/modules/
|
||||||
echo 'load_module "/usr/lib64/nginx/modules/ngx_http_apache_rewrite_module.so";' \
|
if [ ! -e "/usr/share/nginx/modules/ngx_http_apache_rewrite_module.conf" ]; then
|
||||||
> /usr/share/nginx/modules/ngx_http_apache_rewrite_module.conf
|
echo 'load_module "/usr/lib64/nginx/modules/ngx_http_apache_rewrite_module.so";' \
|
||||||
|
> /usr/share/nginx/modules/ngx_http_apache_rewrite_module.conf
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
mkdir -p /usr/share/nginx/modules/ /etc/nginx/modules
|
mkdir -p /usr/share/nginx/modules/ /etc/nginx/modules
|
||||||
cp *.so /usr/share/nginx/modules/
|
cp *.so /usr/share/nginx/modules/
|
||||||
echo 'load_module "/usr/share/nginx/modules/ngx_http_apache_rewrite_module.so";' \
|
if [ ! -e "/etc/nginx/modules/ngx_http_apache_rewrite_module.conf" ]; then
|
||||||
> /etc/nginx/modules/ngx_http_apache_rewrite_module.conf
|
echo 'load_module "/usr/share/nginx/modules/ngx_http_apache_rewrite_module.so";' \
|
||||||
|
> /etc/nginx/modules/ngx_http_apache_rewrite_module.conf
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
packageprep)
|
packageprep)
|
||||||
|
|||||||
Reference in New Issue
Block a user