当前位置: 首页 > news >正文

ngx_http_terminate_request

1 定义

night_http_terminate_request 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_request.c
staticvoidngx_http_terminate_request(ngx_http_request_t*r,ngx_int_trc){ngx_http_cleanup_t*cln;ngx_http_request_t*mr;ngx_http_ephemeral_t*e;mr=r->main;ngx_log_debug1(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"http terminate request count:%d",mr->count);if(rc>0&&(mr->headers_out.status==0||mr->connection->sent==0)){mr->headers_out.status=rc;}cln=mr->cleanup;mr->cleanup=NULL;while(cln){if(cln->handler){cln->handler(cln->data);}cln=cln->next;}ngx_log_debug2(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"http terminate cleanup count:%d blk:%d",mr->count,mr->blocked);if(mr->write_event_handler){if(mr->blocked){r->connection->error=1;r->write_event_handler=ngx_http_request_finalizer;return;}e=ngx_http_ephemeral(mr);mr->posted_requests=NULL;mr->write_event_handler=ngx_http_terminate_handler;(void)ngx_http_post_request(mr,&e->terminal_posted_request);return;}ngx_http_close_request(mr,rc);}
ngx_http_terminate_request 函数 是 nginx 中用于安全终止 HTTP 请求的核心函数。

2 详解

1 函数签名

staticvoidngx_http_terminate_request(ngx_http_request_t*r,ngx_int_trc)
返回值 返回类型 `void` 函数不向调用者返回任何值。 该函数是一次副作用操作,它不负责计算或返回成功/失败指示, 而是直接修改请求的状态、执行清理、并将最终关闭动作插入事件循环或立即执行。 请求终止的结果通过修改请求对象本身及事件驱动机制来体现,无需通过返回值传递。
第一个参数 `ngx_http_request_t *r` 指向 `ngx_http_request_t` 结构体的指针。 该结构体是 nginx 中表示一个 HTTP 请求的核心对象 该参数是输入,是本函数要 终止的HTTP 请求
第二个参数 `ngx_int_t rc` 此次终止的原因码

2 逻辑流程

1 局部变量 2 设置 HTTP 状态码 3 清理回调 4 延迟终结 5 关闭请求

1 局部变量
{ngx_http_cleanup_t*cln;ngx_http_request_t*mr;ngx_http_ephemeral_t*e;mr=r->main;ngx_log_debug1(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"http terminate request count:%d",mr->count);

2 设置 HTTP 状态码
if(rc>0&&(mr->headers_out.status==0||mr->connection->sent==0)){mr->headers_out.status=rc;}
设置 HTTP 状态码: 判断条件:rc > 0(是有效的 HTTP 状态码), 并且主请求的响应状态尚未设置(mr->headers_out.status == 0) 或者连接上还没有发送过任何字节(mr->connection->sent == 0)。 若条件成立,将主请求的 headers_out.status 设为 rc。 意义:只有在“还有机会告知客户端失败原因”的前提下才写入状态码。 如果响应头已经发送,强行修改状态码会导致协议错误; 如果已经有数据发送,则通常状态码已定。 因此这里做了一次“尽力而为”的尝试, 确保错误状态能尽可能传回客户端,但不破坏已建立的响应流。

3 清理回调
cln=mr->cleanup;mr->cleanup=NULL;while(cln){if(cln->handler){cln->handler(cln->data);}cln=cln->next;}ngx_log_debug2(NGX_LOG_DEBUG_HTTP,r->connection->log,0,"http terminate cleanup count:%d blk:%d",mr->count,mr->blocked);
#1 取出并清除清理链表: mr->cleanup 指向主请求关联的清理回调链表头。 将其拷贝到局部变量 cln 后立即置空 mr->cleanup。 目的:防止在后续执行清理回调的过程中, 某些逻辑再次试图添加新的清理项或触发二次清理,
#2 执行所有清理回调: 遍历从主请求获取的清理链表。 对每一个节点,若其 handler 不为空,则调用 handler(cln->data)。 这些回调通常由模块注册, 用于释放与该请求关联的各种资源:关闭文件描述符、删除临时文件、 归还内存池中的大块内存、释放外部连接等。 遍历完全部节点,意味着该请求占用的所有外部资源已被释放, 只剩请求结构体本身和连接尚待处理。

4 延迟终结
if(mr->write_event_handler){if(mr->blocked){r->connection->error=1;r->write_event_handler=ngx_http_request_finalizer;return;}e=ngx_http_ephemeral(mr);mr->posted_requests=NULL;mr->write_event_handler=ngx_http_terminate_handler;(void)ngx_http_post_request(mr,&e->terminal_posted_request);return;}
#1 判断主请求是否仍在参与写事件: write_event_handler 是请求的一个函数指针, 当请求需要向客户端发送数据时, 该指针被设置为相应的处理函数。 若请求已进入最终完成状态或从未开始发送响应,该指针可能为空。 如果指针非空,说明请求还“活”在 nginx 的事件循环中,正在或等待执行写操作。 此时不能直接销毁请求对象,必须通过事件机制安排其关闭,否则可能引发悬空指针或事件混乱。
#2 阻塞状态下的特殊处理: 如果主请求被标记为 blocked(例如正在等待子请求或持有内部锁), 强行将其投入终端队列可能会破坏同步逻辑或导致死锁。 此时采取更保守的策略: 将当前请求所在连接标记为出错(r->connection->error = 1), 这会使后续事件处理检测到错误并尽快结束连接。 将当前请求 r 的写事件处理器替换为 ngx_http_request_finalizer。 该终结器函数会在下一次写事件被触发时执行,最终安全销毁请求。 直接返回,不再进行后续的投递或关闭操作。 这样保证了在复杂异步场景下,请求的销毁被推迟到解除阻塞之后的安全点, 且通过错误标记避免了死等。
#3 当主请求有写事件处理器且未被阻塞时, 执行以下操作: e = ngx_http_ephemeral(mr); 获取主请求的临时数据(ephemeral 结构), mr->posted_requests = NULL; mr->posted_requests 一个挂在主请求(mr)上的 “待处理任务”链表。 请求要终止,这些任务已经毫无意义,清空 mr->write_event_handler = ngx_http_terminate_handler; 将主请求的写事件处理器替换为 ngx_http_terminate_handler。 ngx_http_terminate_handler 是一个特定回调, 它的职责就是在被事件循环调用时执行最终的关闭操作 这样就把“请求最终销毁”的动作封装成了一个可通过事件触发的任务。 把 write_event_handler 更新为 ngx_http_terminate_handler, 下一次写事件被触发时,执行 ngx_http_terminate_handler 函数,终结请求 (void) ngx_http_post_request(mr, &e->terminal_posted_request); 将主请求通过 terminal_posted_request 节点挂接到 nginx 的全局终端事件队列中。 当当前正在处理的事件结束后,nginx 的事件循环会检查并处理 posted 请求队列, 此时会调用刚才设置的 ngx_http_terminate_handler,从而在安全的环境中完成请求销毁。 return; 函数立即返回
逻辑总结 1 获取临时数据:取得预分配的 `terminal_posted_request` 节点,为内部队列挂载做准备。 2 清空待处理任务:丢弃所有尚未执行的子请求或其他延迟任务,终结时不再需要它们。 3 改变行为定义:将 `write_event_handler` 设置为 `ngx_http_terminate_handler`, 这意味着“将来当这个请求被调度执行时,执行的是终结销毁动作”。 4 投递到内部队列:通过 `ngx_http_post_request` 将请求挂入事件循环的终端 posted 队列, 从而强制事件循环在本次迭代的末尾无条件地调用刚才设置的终结 handler。

5 关闭请求
ngx_http_close_request(mr,rc);}
如果主请求的 write_event_handler 为空, 说明请求已经不在任何写事件流程中(可能从未开始发送响应,或已完整结束), 此时可以安全地立即销毁。 调用 ngx_http_close_request(mr, rc), 该函数会减少主请求的引用计数、释放连接资源、回收内存池等,完成请求的最终销毁
http://www.jsqmd.com/news/897018/

相关文章:

  • 2026年苏州市本地上门黄金回收门店指南 彩金+铂金+金条+白银回收门店联系方式推荐 - 百福黄金回收
  • ORCHA框架:异构计算任务编排与性能优化实践
  • 2026年5月揭阳黄金回收:6家门店实测排名,这份榜单请收好 - 润富黄金珠宝行
  • ssm基于vue技术的品牌银饰售卖平台(10118)
  • 乌鲁木齐各区黄金回收哪家靠谱?2026年5月行情参考与变现指南 - 润富黄金珠宝行
  • 3秒找到任何文件!FSearch:Linux系统极速文件搜索神器完全指南
  • H.264视频编码中基于中心预测的快速运动估计算法(CPFMS)详解
  • 物联网与模型驱动方法在核废料监测中的安全与可持续性权衡
  • 盒马鲜生卡回收全流程揭秘:从使用方法到回收提现一站搞定 - 团团收购物卡回收
  • 2026年4月头部角钢代加工厂家推荐,16MN卷管/精轧钢管/45#无缝管/大口径厚壁钢管,角钢加工定制商推荐分析 - 品牌推荐师
  • HoRain云--Claude Code Git 工作流
  • 中银通支付卡怎么回收?3种正规方法+实操步骤,轻松盘活余额 - 可可收公众号
  • 荆州市纪南文旅区黄金回收全指南——2026年5月高位金价下的变现选择与六大机构测评 - 润富黄金珠宝行
  • 药品冷链监控如何通过AI实现自动预警和上报?基于企业级智能体的全链路合规落地方案
  • 一份 Agent 工程岗 JD,暴露了市场真正想要什么样的人
  • 6G核心技术HMIMO:从全息天线到动态超表面的硬件实现与工程实践
  • AI时代求职利器:8款主流简历平台深度测评,哪款能助你脱颖而出?
  • 第二十一届温州国际泵阀管道展览会圆满收官 - GrowthUME
  • 10分钟搞定黑苹果:OpCore Simplify智能配置终极指南
  • 2026 年 AI视频创作培训机构TOP10排行榜:实战选校避坑指南与权威推荐 - GrowthUME
  • 2026年5月惠州黄金回收全攻略:金价高位震荡,六大正规机构助你安全变现 - 润富黄金珠宝行
  • 品牌商标转让平台怎么选?一站式商标转让服务指南,选标、签约、过户全流程代办 - 资讯纵览
  • CORE数据集:LLM辅助构建的标准化RTL基准库及其在EDA与ML4EDA中的应用
  • 3分钟掌握Vin象棋:AI视觉分析让你的棋力瞬间翻倍 [特殊字符]
  • 毫米波大规模MIMO混合预编码:基于哈达玛码书的低成本波束赋形设计
  • 终极Windows OCR文字识别方案:Text Grab四大模式让屏幕文字无处可逃
  • 基于深度卷积特征匹配的通信辐射源识别:从射频指纹到硬件身份验证
  • 2026年苏州军事夏令营哪家强?这些企业值得你深入了解! - GrowthUME
  • 汕头黄金回收行业实测解析:六家正规门店工商资质+专业设备+全域上门,2026年实时金价一览 - 润富黄金珠宝行
  • 2026广州专利补贴新规!哪些专利能拿钱,哪些白申? - 速递信息