1 定义
ngx_http_core_access_phase 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_core_module.c
ngx_int_tngx_http_core_access_phase(ngx_http_request_t*r,ngx_http_phase_handler_t*ph){ngx_int_trc;ngx_table_elt_t*h;ngx_http_core_loc_conf_t*clcf;if(r!=r->main){r->phase_handler=ph->next;returnNGX_AGAIN;}ngx_log_debug1(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"access phase: %ui",r->phase_handler);rc=ph->handler(r);if(rc==NGX_DECLINED){r->phase_handler++;returnNGX_AGAIN;}if(rc==NGX_AGAIN||rc==NGX_DONE){returnNGX_OK;}clcf=ngx_http_get_module_loc_conf(r,ngx_http_core_module);if(clcf->satisfy==NGX_HTTP_SATISFY_ALL){if(rc==NGX_OK){r->phase_handler++;returnNGX_AGAIN;}}else{if(rc==NGX_OK){r->access_code=0;for(h=r->headers_out.www_authenticate;h;h=h->next){h->hash=0;}r->phase_handler=ph->next;returnNGX_AGAIN;}if(rc==NGX_HTTP_FORBIDDEN||rc==NGX_HTTP_UNAUTHORIZED){if(r->access_code!=NGX_HTTP_UNAUTHORIZED){r->access_code=rc;}r->phase_handler++;returnNGX_AGAIN;}}/* rc == NGX_ERROR || rc == NGX_HTTP_... */if(rc==NGX_HTTP_UNAUTHORIZED){returnngx_http_core_auth_delay(r);}ngx_http_finalize_request(r,rc);returnNGX_OK;}
ngx_http_core_access_phase 函数是 `NGX_HTTP_ACCESS_PHASE` 阶段的调度器, 其核心作用是:执行访问控制模块的 handler
2 详解
1 函数签名
ngx_int_tngx_http_core_access_phase(ngx_http_request_t*r,ngx_http_phase_handler_t*ph)
返回值 用于返回函数执行结果的状态码 NGX_AGAIN:告诉引擎“继续循环,处理下一个处理器” NGX_OK:告诉引擎“停止循环,挂起或终结请求”。
参数1 ngx_http_request_t *r 指向当前 HTTP 请求上下文结构体
参数2 ngx_http_phase_handler_t *ph 指向 ngx_http_phase_handler_t 结构体的指针, 代表当前在 阶段处理引擎 数组 中的处理器项
2 逻辑流程
1 局部变量 2 子请求直接跳过访问控制阶段 3 调用实际的访问控制模块 4 处理返回结果 4-1 NGX_DECLINED 4-2 NGX_AGAIN || NGX_DONE 4-3 satisfy all / satisfy any 策略 处理 4-4 错误处理
1 局部变量
{ngx_int_trc;ngx_table_elt_t*h;ngx_http_core_loc_conf_t*clcf;
2 子请求直接跳过访问控制阶段
if(r!=r->main){r->phase_handler=ph->next;returnNGX_AGAIN;}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"access phase: %ui",r->phase_handler);
3 调用实际的访问控制模块
rc=ph->handler(r);
4 处理返回结果
4-1 NGX_DECLINED
if(rc==NGX_DECLINED){r->phase_handler++;returnNGX_AGAIN;}
模块不处理此请求 如果 handler 返回 NGX_DECLINED, 表示该模块对此请求不生效(如 IP 不在列表中), 将阶段索引加 1,继续调用同阶段的下一个访问控制模块。
4-2 NGX_AGAIN || NGX_DONE
if(rc==NGX_AGAIN||rc==NGX_DONE){returnNGX_OK;}
需要异步等待或请求已终结 NGX_AGAIN: 模块需要挂起等待 NGX_DONE: 模块已主动调用 ngx_http_finalize_request 结束了请求。 动作: 直接返回 NGX_OK 给引擎, 通知其退出当前阶段循环,暂停或结束请求。
4-3 satisfy all / satisfy any 策略 处理
clcf=ngx_http_get_module_loc_conf(r,ngx_http_core_module);
获取 satisfy 配置
if(clcf->satisfy==NGX_HTTP_SATISFY_ALL){if(rc==NGX_OK){r->phase_handler++;returnNGX_AGAIN;}}else{if(rc==NGX_OK){r->access_code=0;for(h=r->headers_out.www_authenticate;h;h=h->next){h->hash=0;}r->phase_handler=ph->next;returnNGX_AGAIN;}if(rc==NGX_HTTP_FORBIDDEN||rc==NGX_HTTP_UNAUTHORIZED){if(r->access_code!=NGX_HTTP_UNAUTHORIZED){r->access_code=rc;}r->phase_handler++;returnNGX_AGAIN;}}
satisfy all 模式处理
satisfy any 模式处理
4-4 错误处理
/* rc == NGX_ERROR || rc == NGX_HTTP_... */if(rc==NGX_HTTP_UNAUTHORIZED){returnngx_http_core_auth_delay(r);}
对 401 进行延迟处理(防暴力破解) 如果需要返回 401,调用 ngx_http_core_auth_delay 执行认证延迟逻辑。 该函数通常会设置一个定时器来推迟发送 401 响应,增大暴力破解的时间成本。
ngx_http_finalize_request(r,rc);returnNGX_OK;}