ngx_http_internal_redirect
2026/6/7 13:16:28 网站建设 项目流程

1 定义

ngx_http_internal_redirect 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_core_module.c
ngx_int_tngx_http_internal_redirect(ngx_http_request_t*r,ngx_str_t*uri,ngx_str_t*args){ngx_http_core_srv_conf_t*cscf;r->uri_changes--;if(r->uri_changes==0){ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"rewrite or internal redirection cycle ""while internally redirecting to \"%V\"",uri);r->main->count++;ngx_http_finalize_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);returnNGX_DONE;}r->uri=*uri;if(args){r->args=*args;}else{ngx_str_null(&r->args);}ngx_log_debug2(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"internal redirect: \"%V?%V\"",uri,&r->args);ngx_http_set_exten(r);/* clear the modules contexts */ngx_memzero(r->ctx,sizeof(void*)*ngx_http_max_module);cscf=ngx_http_get_module_srv_conf(r,ngx_http_core_module);r->loc_conf=cscf->ctx->loc_conf;ngx_http_update_location_config(r);#if(NGX_HTTP_CACHE)r->cache=NULL;#endifr->internal=1;r->valid_unparsed_uri=0;r->add_uri_to_alias=0;r->main->count++;ngx_http_handler(r);returnNGX_DONE;}
ngx_http_internal_redirect 函数是 Nginx 实现内部重定向的核心函数。 它用新的 URI 和参数替换请求当前的值, 清除模块上下文并重置配置, 然后重新调用 `ngx_http_handler` 使请求从 `server rewrite` 阶段重新走一遍完整的处理流程, 同时通过计数器防止无限循环。

2 详解

1 函数签名

ngx_int_tngx_http_internal_redirect(ngx_http_request_t*r,ngx_str_t*uri,ngx_str_t*args)
返回值 表示函数执行结果的状态码
参数1 ngx_http_request_t *r 指向 当前 HTTP 请求结构体
参数2 ngx_str_t *uri 表示新 URI 字符串
参数3 ngx_str_t *args 表示新查询参数字符串

2 逻辑流程

1 重定向计数器 2 请求状态重置 3 重新启动请求处理

1 重定向计数器

{ngx_http_core_srv_conf_t*cscf;r->uri_changes--;
将请求的内部重写剩余次数减 1。

if(r->uri_changes==0){ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"rewrite or internal redirection cycle ""while internally redirecting to \"%V\"",uri);r->main->count++;ngx_http_finalize_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);returnNGX_DONE;}
检查计数器是否归零。 归零表示重写次数超过限制 进行错误处理
增加主请求的引用计数。 即将调用 ngx_http_finalize_request 结束请求,该函数会递减引用计数。 先递增可避免计数降为 0 导致请求被过早释放。 意义:保证请求对象在终结期间有效。
以 500 状态码终结请求,发送错误响应
返回 NGX_DONE, 告诉调用者请求已处理完毕, 当前处理路径应停止。

2 请求状态重置

r->uri=*uri;
将请求的 URI 替换为新的目标 URI。

if(args){r->args=*args;}else{ngx_str_null(&r->args);}ngx_log_debug2(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"internal redirect: \"%V?%V\"",uri,&r->args);
如果调用者提供了新参数,则更新 r->args。 如果 args 为 NULL,则清空请求的参数(设为空字符串)。

ngx_http_set_exten(r);
根据新 URI 提取文件扩展名(如 .html),存入 r->exten

/* clear the modules contexts */ngx_memzero(r->ctx,sizeof(void*)*ngx_http_max_module);
清空模块上下文 将 r->ctx 数组(每个模块一个指针)全部清零。 内部重定向相当于重新处理请求, 每个模块在上次处理中可能存储的私有数据必须清空,防止干扰新流程。 意义:保证请求状态干净如新,是正确执行第二次处理的前提。

cscf=ngx_http_get_module_srv_conf(r,ngx_http_core_module);r->loc_conf=cscf->ctx->loc_conf;
重置 location 配置 获取当前虚拟主机的核心模块配置 cscf 将请求的 location 配置指针重置为 server 级别的默认 location 配置 重定向后需要重新匹配 location, 因此先脱离之前匹配到的具体 location, 回到 server 默认配置作为起点。

ngx_http_update_location_config(r);
根据当前的 r->loc_conf(现在是 server 默认配置)更新请求的运行状态 虽然随后会再次匹配 location 并可能再次调用此函数, 但此时先应用 server 基本配置,保证处理基础环境正确。

#if(NGX_HTTP_CACHE)r->cache=NULL;#endif
清除缓存指针 如果启用了 HTTP 缓存模块, 将请求的缓存对象指针置 NULL。 意义:避免旧缓存上下文干扰新请求的处理。

r->internal=1;r->valid_unparsed_uri=0;r->add_uri_to_alias=0;r->main->count++;
标记当前请求为“内部请求” 清除“未解析 URI 有效”标志。 原未解析 URI 已失效,后续如果需要会重新生成。 清除 add_uri_to_alias 标志, 该标志用于 alias 处理时控制是否将 URI 附加到别名路径后。 意义:避免 alias 逻辑错误拼接。 增加主请求的引用计数。 逻辑:接下来调用 ngx_http_handler(r) 会重新进入异步处理流程, 请求可能被挂起(如等待子请求、I/O)。 增加引用计数确保在此期间请求对象不被释放。 意义:遵循 Nginx 的引用计数管理,保证异步安全。

3 重新启动请求处理

ngx_http_handler(r);
调用 HTTP 请求处理的总入口函数

returnNGX_DONE;}
返回 NGX_DONE 给调用者 逻辑:NGX_DONE 表示“请求已转交,当前处理应停止”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询