From da7c38a0c60894b8d062e70838d464f5968adac0 Mon Sep 17 00:00:00 2001 From: Alexey Berezhok Date: Sat, 27 Jun 2026 00:24:56 +0300 Subject: [PATCH] Added GlobalLocationRewriteEngine --- .../ngx_http_apache_rewrite_engine.c | 21 +---- .../ngx_http_apache_rewrite_engine.h | 2 + .../ngx_http_apache_rewrite_module.c | 84 +++++++++++++++++-- 3 files changed, 82 insertions(+), 25 deletions(-) diff --git a/modules/mod_rewrite/ngx_http_apache_rewrite_engine.c b/modules/mod_rewrite/ngx_http_apache_rewrite_engine.c index c0b8499..5da25ee 100644 --- a/modules/mod_rewrite/ngx_http_apache_rewrite_engine.c +++ b/modules/mod_rewrite/ngx_http_apache_rewrite_engine.c @@ -597,10 +597,11 @@ ngx_rewrite_apply_rule(ngx_rewrite_rule_t *rule, ngx_rewrite_ctx_t *ctx, ngx_str size_t combined_len = ctx->redirect_url.len + 1 + new_args.len; tmp_data = ngx_pnalloc(r->pool, combined_len); if (tmp_data) { - ngx_memcpy(tmp_data, ctx->redirect_url.data, ctx->redirect_url.len); + u_char *start = tmp_data; + tmp_data = ngx_cpymem(tmp_data, ctx->redirect_url.data, ctx->redirect_url.len); *tmp_data++ = '&'; - ngx_memcpy(tmp_data, new_args.data, new_args.len); - ctx->redirect_url.data = 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; } } @@ -655,20 +656,6 @@ ngx_rewrite_apply_rule(ngx_rewrite_rule_t *rule, ngx_rewrite_ctx_t *ctx, ngx_str ctx->uri = newuri; - /* Append old query args to URI if present and redirect_url wasn't modified */ - if (new_args.len > 0 && ctx->redirect_url.data == NULL - && ctx->uri.data != NULL && ctx->uri.len > 0) { - u_char *tmp_data; - size_t combined_len = ctx->uri.len + 1 + new_args.len; - tmp_data = ngx_pnalloc(r->pool, combined_len); - if (tmp_data) { - ngx_memcpy(tmp_data, ctx->uri.data, ctx->uri.len); - *tmp_data++ = '&'; - ngx_memcpy(tmp_data, new_args.data, new_args.len); - ctx->uri.data = tmp_data; - ctx->uri.len = combined_len; - } - } ngx_str_null(&ctx->redirect_url); ctx->redirect_code = 0; diff --git a/modules/mod_rewrite/ngx_http_apache_rewrite_engine.h b/modules/mod_rewrite/ngx_http_apache_rewrite_engine.h index 8caef96..11cc046 100644 --- a/modules/mod_rewrite/ngx_http_apache_rewrite_engine.h +++ b/modules/mod_rewrite/ngx_http_apache_rewrite_engine.h @@ -223,6 +223,8 @@ typedef struct { /* Fallback to index.php with query string after try_files miss */ ngx_int_t fallback_to_index; // 0|1: enable fallback mechanism unsigned fallback_to_index_set:1; + ngx_int_t glstate; + unsigned glstate_set:1; } ngx_http_apache_rewrite_srv_conf_t; /* diff --git a/modules/mod_rewrite/ngx_http_apache_rewrite_module.c b/modules/mod_rewrite/ngx_http_apache_rewrite_module.c index f25435d..8f9c339 100644 --- a/modules/mod_rewrite/ngx_http_apache_rewrite_module.c +++ b/modules/mod_rewrite/ngx_http_apache_rewrite_module.c @@ -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, 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, void *conf); 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, NULL }, + { ngx_string("GlobalLocationRewriteEngine"), + NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_http_rewrite_engine_global, + 0, + 0, + NULL }, { ngx_string("RewriteRule"), 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; } - -static void * -ngx_http_apache_rewrite_create_loc_conf(ngx_conf_t *cf) -{ +static ngx_http_apache_rewrite_loc_conf_t * +ngx_http_apache_rewrite_create_loc_conf_(ngx_pool_t *pool){ 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) { return NULL; } @@ -286,8 +292,8 @@ ngx_http_apache_rewrite_create_loc_conf(ngx_conf_t *cf) conf->state = ENGINE_DISABLED; conf->options = OPTION_NONE; - conf->rules = ngx_array_create(cf->pool, 4, sizeof(ngx_rewrite_rule_t)); - conf->pending_conds = ngx_array_create(cf->pool, 4, + conf->rules = ngx_array_create(pool, 4, sizeof(ngx_rewrite_rule_t)); + conf->pending_conds = ngx_array_create(pool, 4, sizeof(ngx_rewrite_cond_t)); 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; } +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 * ngx_http_apache_rewrite_merge_loc_conf(ngx_conf_t *cf, @@ -1494,6 +1506,7 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r) ngx_str_t baseurl_htacess = ngx_null_string; ngx_int_t options_htaccess = -1; ngx_int_t state_htaccess = -1; + ngx_int_t global_enabled = 0; (void)options_htaccess; @@ -1501,8 +1514,21 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r) 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); + if (sconf != NULL && sconf->glstate_set == 1 && sconf->glstate == ENGINE_ENABLED) { + global_enabled = 1; + } + if (lcf == NULL || lcf->state != ENGINE_ENABLED) { - return NGX_DECLINED; + 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, @@ -2254,6 +2280,48 @@ ngx_http_rewrite_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 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 [...]