1 定义ngx_http_rewrite_handler 函数 定义在 ./nginx-1.24.0/src/http/modules/ngx_http_rewrite_module.cstaticngx_int_tngx_http_rewrite_handler(ngx_http_request_t*r){ngx_int_tindex;ngx_http_script_code_pt code;ngx_http_script_engine_t*e;ngx_http_core_srv_conf_t*cscf;ngx_http_core_main_conf_t*cmcf;ngx_http_rewrite_loc_conf_t*rlcf;cmcfngx_http_get_module_main_conf(r,ngx_http_core_module);cscfngx_http_get_module_srv_conf(r,ngx_http_core_module);indexcmcf-phase_engine.location_rewrite_index;if(r-phase_handlerindexr-loc_confcscf-ctx-loc_conf){/* skipping location rewrite phase for server null location */returnNGX_DECLINED;}rlcfngx_http_get_module_loc_conf(r,ngx_http_rewrite_module);if(rlcf-codesNULL){returnNGX_DECLINED;}engx_pcalloc(r-pool,sizeof(ngx_http_script_engine_t));if(eNULL){returnNGX_HTTP_INTERNAL_SERVER_ERROR;}e-spngx_pcalloc(r-pool,rlcf-stack_size*sizeof(ngx_http_variable_value_t));if(e-spNULL){returnNGX_HTTP_INTERNAL_SERVER_ERROR;}e-iprlcf-codes-elts;e-requestr;e-quote1;e-logrlcf-log;e-statusNGX_DECLINED;while(*(uintptr_t*)e-ip){code*(ngx_http_script_code_pt*)e-ip;code(e);}returne-status;}ngx_http_rewrite_handler 函数 是 ngx_http_rewrite_module 在 rewrite 阶段注册的处理函数 其作用是 对请求的 URI、变量等进行改写 或执行 return/break 等指令并返回相应的状态码 从而驱动阶段检查器决定继续、跳转或终止请求。2 详解1 函数签名staticngx_int_tngx_http_rewrite_handler(ngx_http_request_t*r)返回值 代表 执行后的最终状态的 状态码 这个值会被阶段检查器ngx_http_core_rewrite_phase 用来决定如何调度请求参数 ngx_http_request_t *r 指向当前 HTTP 请求上下文指针2 逻辑流程1 局部变量 2 跳过 location rewrite 3 获取 location 的 rewrite 配置 4 无 rewrite 规则 5 为脚本执行分配空间 6 初始化脚本引擎 7 脚本执行主循环 8 返回脚本执行状态1 局部变量{ngx_int_tindex;ngx_http_script_code_pt code;ngx_http_script_engine_t*e;ngx_http_core_srv_conf_t*cscf;ngx_http_core_main_conf_t*cmcf;ngx_http_rewrite_loc_conf_t*rlcf;cmcfngx_http_get_module_main_conf(r,ngx_http_core_module);cscfngx_http_get_module_srv_conf(r,ngx_http_core_module);indexcmcf-phase_engine.location_rewrite_index;cmcf 取得核心主配置 其中 phase_engine 包含了所有阶段处理器的数组。 cscf 取得核心 server 配置 主要用于后续判断当前 location 是否为 server 级的空 location。 index 获取 NGX_HTTP_REWRITE_PHASE 阶段在引擎数组中的第一个处理器的索引。 该值在配置合并后确定用于下一步判断是否应跳过该阶段。2 跳过 location rewriteif(r-phase_handlerindexr-loc_confcscf-ctx-loc_conf){/* skipping location rewrite phase for server null location */returnNGX_DECLINED;}跳过 location rewrite 阶段NGX_HTTP_REWRITE_PHASE的处理 直接返回 NGX_DECLINED 给阶段检查器 使之继续同阶段的下一个处理器或进入下一个阶段。条件一r-phase_handler index index 在前面被赋值为 cmcf-phase_engine.location_rewrite_index 即 NGX_HTTP_REWRITE_PHASE 阶段在阶段引擎数组中的第一个处理器的索引。 r-phase_handler 是当前请求所执行的阶段处理器索引。 条件成立 → 当前正要开始执行 location rewrite 阶段的第一个处理器。 确认当前正处于 Location 级 Rewrite 阶段 Nginx 的 Rewrite 模块同时服务于 server 级和 location 级指令。 此判断确保优化仅作用于 Location 阶段不误伤 Server 级重写条件二r-loc_conf cscf-ctx-loc_conf 确认请求的 Location 配置指针仍指向 Server 的默认合并配置即未匹配到任何具体 location {} 块 cscf-ctx-loc_conf 是 Server 上下文在启动期生成的默认 Location 配置数组。 若请求仍指向它说明 FIND_CONFIG_PHASE 尚未找到匹配的 location 意味着没有显式的 location 块被匹配到。两个条件结合 表示 请求正进入 location rewrite 阶段 但是没有匹配到实际的 location 先匹配到 实际的 location 块 才能根据 实际的 location 块 的具体配置进行 location rewrite 前提条件都不满足 也就无法进行 Location 重写 所以需要跳过 返回 NGX_DECLINED 表示 该请求不需要本处理器处理总结 1 前提 location rewrite 阶段的脚本rewrite、return、set 等 只存在于显式定义的 location 块内。 2 判断 当前请求匹配的是 server 级别的“空 location”没有实际的 location 块 则 location rewrite 的前提条件不成立。 3 动作 直接跳过该阶段返回 NGX_DECLINED。 4 语义 NGX_DECLINED 在这里的含义就是 “本处理器无法处理此请求请阶段引擎继续尝试下一个处理器或进入下一个阶段”。 - 先有实际的 location才能有 location 级别的 rewrite 规则 - 没有实际 location → 没有 location rewrite 规则 → location rewrite 阶段处理器理应“弃权” - 通过返回 NGX_DECLINED 实现这个“弃权”保证阶段引擎的调度不会卡死在空处理上。3 获取 location 的 rewrite 配置rlcfngx_http_get_module_loc_conf(r,ngx_http_rewrite_module);获取 rewrite 模块在当前请求 location下的配置结构。 意义该配置包含了在配置解析阶段编译好的 rewrite 脚本数组codes 以及脚本执行所需的栈大小stack_size和日志标志等。4 无 rewrite 规则if(rlcf-codesNULL){returnNGX_DECLINED;}检查是否有脚本代码 如果该 location/server 下没有定义任何 rewrite、return、break、set 等指令 codes 为 NULL。 动作返回 NGX_DECLINED 表示该 handler 无事可做 让阶段检查器继续下一个处理器5 为脚本执行分配空间engx_pcalloc(r-pool,sizeof(ngx_http_script_engine_t));if(eNULL){returnNGX_HTTP_INTERNAL_SERVER_ERROR;}e-spngx_pcalloc(r-pool,rlcf-stack_size*sizeof(ngx_http_variable_value_t));if(e-spNULL){returnNGX_HTTP_INTERNAL_SERVER_ERROR;}分配脚本引擎结构体 从请求内存池中分配并清零一个脚本引擎结构体。 分配失败返回 NGX_HTTP_INTERNAL_SERVER_ERROR 该返回值会被 checker 传递给 ngx_http_finalize_request 最终向客户端发送 500 错误。分配脚本运行栈 作用 为脚本引擎的变量栈分配内存大小为 stack_size 个 ngx_http_variable_value_t 单元。 stack_size在配置解析时通过分析 rewrite 脚本的复杂度预先计算出所需的最大栈深度。 错误处理分配失败同样返回 500 错误。 意义栈用于保存脚本执行过程中的临时值如变量值、表达式中间结果是 Nginx 轻量级脚本引擎的关键组件。6 初始化脚本引擎e-iprlcf-codes-elts;e-requestr;e-quote1;e-logrlcf-log;e-statusNGX_DECLINED;7 脚本执行主循环while(*(uintptr_t*)e-ip){code*(ngx_http_script_code_pt*)e-ip;code(e);}8 返回脚本执行状态returne-status;}返回脚本执行后的最终状态码。 可能的返回值 NGX_DECLINED 脚本中没有任何规则被触发或所有规则都未匹配 请求 URI 未改变请求应继续后续阶段处理。 NGX_OK 脚本成功执行并修改了 URI如执行了 rewrite ... break 或 set 但未产生最终响应后续可能需要内部重定向或进入内容阶段。 NGX_DONE 脚本中执行了 return 指令已主动调用 ngx_http_finalize_request请求完全终结。 HTTP 状态码如 NGX_HTTP_MOVED_TEMPORARILY、NGX_HTTP_FORBIDDEN 等 脚本执行重定向或返回特定错误需要生成对应响应。 NGX_HTTP_INTERNAL_SERVER_ERROR 脚本引擎分配失败内部错误。 意义该返回值被 rewrite 阶段的 checker 接收 并以此决定是继续推进、终结请求还是触发内部重定向 从而将模块的业务逻辑无缝融入到框架的调度流水线中。