From 2cb396b1d0f973c10fdc4508d8cab83e4f908cec Mon Sep 17 00:00:00 2001 From: Alexey Berezhok Date: Wed, 24 Jun 2026 02:08:54 +0300 Subject: [PATCH] - Added evaluation variables in docroot --- extract_nginx_args.py | 1 + .../ngx_http_apache_rewrite_module.c | 99 ++++++++++++++++--- 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/extract_nginx_args.py b/extract_nginx_args.py index 0a5b429..af2e95b 100755 --- a/extract_nginx_args.py +++ b/extract_nginx_args.py @@ -109,6 +109,7 @@ def main(nginx_src_dir="."): # Добавляем наш модуль в конец 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) diff --git a/modules/mod_rewrite/ngx_http_apache_rewrite_module.c b/modules/mod_rewrite/ngx_http_apache_rewrite_module.c index 0b0141b..f25435d 100644 --- a/modules/mod_rewrite/ngx_http_apache_rewrite_module.c +++ b/modules/mod_rewrite/ngx_http_apache_rewrite_module.c @@ -775,6 +775,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); 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) { return NGX_ERROR; } @@ -792,6 +795,8 @@ ngx_htaccess_search_upward(ngx_http_request_t *r, u_char *docroot, size_t docroo /* Iterate upward from current directory up to docroot */ while (1) { /* 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; if (stat((char *)path_buf, &st) == 0 && ngx_is_file(&st)) { /* Found .htaccess! */ @@ -812,6 +817,8 @@ ngx_htaccess_search_upward(ngx_http_request_t *r, u_char *docroot, size_t docroo if (last_slash == NULL) { /* 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; } @@ -820,6 +827,8 @@ ngx_htaccess_search_upward(ngx_http_request_t *r, u_char *docroot, size_t docroo if (current_pos < docroot_len) { /* 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; } @@ -1496,8 +1505,13 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r) 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 */ 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 */ if (lcf->rules->nelts == 0) { return NGX_DECLINED; @@ -1533,20 +1547,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"; 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; - 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; /* Remove last component (filename) to search from parent directory */ if (rc == NGX_OK && current_path.len > 0) { - /* Search upward for .htaccess file */ - rc = ngx_htaccess_search_upward(r, clcf->root.data, clcf->root.len, ¤t_path, - htaccess_name, htaccess_name_len, &htaccess_path); + /* Search upward for .htaccess file - use evaluated root here too! */ + rc = ngx_htaccess_search_upward(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, + &htaccess_path); 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 */ ctx = ngx_http_get_module_ctx(r, ngx_http_apache_rewrite_module); if (ctx && ctx->end) { @@ -1558,18 +1608,35 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r) return ngx_process_rules_result(rc, ctx, r, 0); } - htaccess_docroot.data = ngx_pcalloc(r->pool, htaccess_path.len); - size_t htaccess_docroot_vlen = htaccess_path.len - (clcf->root.len + 1) - htaccess_name_len; - if ((long)htaccess_docroot_vlen < 0) htaccess_docroot_vlen = 0; - ngx_memcpy(htaccess_docroot.data, htaccess_path.data + clcf->root.len + 1, htaccess_docroot_vlen); + /* LOG: Show found htaccess path */ + if (rc == NGX_OK && htaccess_path.data) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "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 */ struct stat st; if (!htaccess_path.data || stat((char *)htaccess_path.data, &st) == -1) { /* 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) { return NGX_DECLINED; } @@ -1641,6 +1708,9 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r) /* If no cached rules, parse .htaccess file */ 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); if (!parsed_rules){ @@ -1660,11 +1730,17 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r) /* Store in cache — add/update entry in linked list */ 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) 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 */ if (ctx == NULL) { ctx = ngx_pcalloc(r->pool, sizeof(ngx_rewrite_ctx_t)); @@ -1685,7 +1761,8 @@ ngx_http_apache_rewrite_location_handler(ngx_http_request_t *r) /* Combine location rules with .htaccess rules (.htaccess has priority - added first) */ 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) { /* Create combined array: htaccess rules first, then location rules */ ngx_array_t *final_rules = ngx_array_create(r->pool,