深度测评:中小企业72小时小程序快速上线,关键难点与解决路径
2026/6/7 14:24:14
ngx_http_internal_redirect 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_core_module.cngx_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` 阶段重新走一遍完整的处理流程, 同时通过计数器防止无限循环。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 表示新查询参数字符串1 重定向计数器 2 请求状态重置 3 重新启动请求处理{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, 告诉调用者请求已处理完毕, 当前处理路径应停止。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 的引用计数管理,保证异步安全。ngx_http_handler(r);调用 HTTP 请求处理的总入口函数returnNGX_DONE;}返回 NGX_DONE 给调用者 逻辑:NGX_DONE 表示“请求已转交,当前处理应停止”。