1 定义
ngx_http_core_rewrite_phase 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_core_module.c
ngx_int_tngx_http_core_rewrite_phase(ngx_http_request_t*r,ngx_http_phase_handler_t*ph){ngx_int_trc;ngx_log_debug1(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"rewrite phase: %ui",r->phase_handler);rc=ph->handler(r);if(rc==NGX_DECLINED){r->phase_handler++;returnNGX_AGAIN;}if(rc==NGX_DONE){returnNGX_OK;}/* NGX_OK, NGX_AGAIN, NGX_ERROR, NGX_HTTP_... */ngx_http_finalize_request(r,rc);returnNGX_OK;}
ngx_http_core_rewrite_phase 函数 是 Nginx HTTP 阶段引擎中 rewrite 阶段的调度器(checker)。 它调用模块注册的 rewrite 处理函数,根据返回值决定后续动作
2 详解
1 函数签名
ngx_int_tngx_http_core_rewrite_phase(ngx_http_request_t*r,ngx_http_phase_handler_t*ph)
返回值 用于表示函数执行的结果的状态码
参数1 ngx_http_request_t *r 当前请求的请求结构体
参数2 ngx_http_phase_handler_t *ph 指向当前阶段处理器项的指针,通过它可以调用实际模块的 handler
2 逻辑流程
1 调用 handler 2 根据返回值处理
{ngx_int_trc;ngx_log_debug1(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"rewrite phase: %ui",r->phase_handler);rc=ph->handler(r);
调用 handler
if(rc==NGX_DECLINED){r->phase_handler++;returnNGX_AGAIN;}
条件 rc == NGX_DECLINED: 模块 handler 返回 NGX_DECLINED, 表示当前处理器不处理该请求(例如 rewrite 规则没有匹配), 应当继续尝试同阶段的下一个处理器。 r->phase_handler++: 将阶段处理器索引递增 1,指向数组中的下一个处理器项 return NGX_AGAIN: 向引擎返回 NGX_AGAIN,引擎会继续 while 循环,再次调用新索引指向的
if(rc==NGX_DONE){returnNGX_OK;}
条件 rc == NGX_DONE: 模块 handler 返回 NGX_DONE, 表明请求已经被完全终结。 通常 handler 内部已经调用了 ngx_http_finalize_request 或类似的终止函数, 请求对象不再可用 直接向引擎返回 NGX_OK
/* NGX_OK, NGX_AGAIN, NGX_ERROR, NGX_HTTP_... */ngx_http_finalize_request(r,rc);
调用 ngx_http_finalize_request, 以 handler 返回的 rc 作为终止码,结束当前请求的处理。
returnNGX_OK;}
向阶段引擎返回 NGX_OK。 引擎的响应: 引擎收到 NGX_OK 后立即退出 while 循环, 停止执行任何后续阶段处理器。
因为阶段处理引擎只认 NGX_OK(停止)和 NGX_AGAIN(继续)两个控制指令, 不认 HTTP 状态码或错误码。 Checker 必须将所有“终态结果”翻译为 NGX_OK, 并在翻译前调用 ngx_http_finalize_request 完成安全交接
rewrite 阶段的本质决定“一旦处理即终止” rewrite 阶段(包括 server rewrite 和 location rewrite)的核心任务是 对请求 URI 进行改写(也可能直接产生重定向或最终响应)。
在这个阶段:
如果 handler 返回 `NGX_DECLINED`, 说明当前规则没有匹配,可以继续尝试下一个 handler。
如果 handler 返回了其他值,则表明 rewrite 已经给出了最终结论:
`NGX_OK`:通常表示 rewrite 成功修改了 URI 此时请求的 URI 已经确定,要么生成重定向响应
`NGX_ERROR` 或 HTTP 状态码: 表示发生错误或需要直接返回一个特定的 HTTP 响应(如 403、404 等)。
在这些情况下 都意味着当前 URI 路径处理 到此为止, 用 ngx_http_finalize_request 结束掉当前处理路径 然后返回 return 结束这条路径的 ngx_http_core_run_phases ngx_http_finalize_request 结束掉当前处理路径前 会将修改 URI 后的请求加入 延迟请求链表 当这条路径执行结束后 后面会遍历处理 延迟请求链表 会再次调用 ngx_http_core_run_phases 来处理新的 URI 路径
即 1 修改 URI 后的请求加入 延迟请求链表,稍后处理 2 当前 URI 路径处理 结束,向上返回,清理,结束 3 处理 延迟请求链表 中的请求, 调用 ngx_http_core_run_phases 处理修改后的 URI
ngx_http_core_run_phases 每次调用处理的是一条 URI 路径 URI 路径 修改后,这次调用的 ngx_http_core_run_phases 任务就完成了 新的 URI 路径 需要再次调用 ngx_http_core_run_phases 来处理
一次 `ngx_http_core_run_phases` 调用 = 处理一条 URI 路径 它从当前的 `phase_handler` 索引开始, 在阶段引擎的驱动下走完这条路径的所有阶段, 直到遇到最终响应、内部重定向或需要挂起为止。 当 rewrite 阶段 修改了 URI 并触发内部重定向时, 当前的 `ngx_http_core_run_phases` 会通过 checker 调用 `ngx_http_finalize_request`, 然后 checker 返回 `NGX_OK`,`run_phases` 退出。 这意味着 旧 URI 路径的处理已经完成 修改后的 URI 作为 新的处理路径,会在稍后从 `posted_requests` 延迟链表中被取出, 并由事件循环 再次调用 `ngx_http_core_run_phases` 来重新执行, 从 `SERVER_REWRITE_PHASE` 开始。 因此,一次 `ngx_http_core_run_phases` 调用就是一次“路径处理任。 URI 的修改标志着当前任务的结束, 新 URI 的处理需要另一次独立的 `run_phases` 调用。