You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx 1.16未完整接收HTTP请求体的处理疑问(FastCGI场景)

Nginx 1.16 HTTP请求体分段接收场景的疑问

最近在阅读Nginx 1.16的源码,研究HTTP模块处理HTTP请求体的逻辑时,遇到了请求体未一次性完整接收、剩余内容后续到达的场景。若数据涉及FastCGI,Body handler会被插入到CONTENT_PHASE,对应ngx_http_fastcgi_module.c#L3513。

假设条件

1. ngx_http_request_t中的buffers足够(无需额外分配缓冲区内存)
2. Transfer-Encoding非分块编码
3. Content-Length为100字节,首次仅接收50字节,剩余50字节后续到达
4. HTTP请求体用于FastCGI,因此ngx_http_fastcgi_handler会被插入到CONTENT_PHASE

代码流程梳理(可能存在偏差)

  1. 在ngx_http_request_body.c#L100处,经过ngx_http_request_body_filter处理后,新的ngx_chain_t会挂载到ngx_http_request r->request_body->bufs上。
  2. 在ngx_http_request_body.c#L128处,因未完整接收HTTP请求体,会进入该if分支。在执行do_read_client_request_body前,read_event_handler会被设置为ngx_http_read_client_request_body_handler,该动作会在epoll_wait后回调的ngx_http_request_handler中触发。
  3. 在ngx_http_request_body.c#L336处,读取socket内核缓冲区中的数据,若内核缓冲区中无数据包则退出循环,随后进入ngx_http_request_body.c#L387。由于ngx_unix_recv已接收所有数据包,c->read_ready标志会被重置为false,且request_body_no_buffering值为0,因此代码会直接跳转到ngx_http_request_body.c#L407,添加client_body_timeout定时器事件,并注册c->read事件(回调函数为ngx_http_request_handler,但实际执行的事件动作为ngx_http_read_client_request_body_handler,因为read_event_handler会在ngx_http_request_handler中执行)。随后返回NGX_AGAIN。
  4. 代码会从ngx_http_request_body.c#L133跳转到ngx_http_request_body.c#L208,再返回到ngx_http_fastcgi_module.c#L754,此时返回值变为NGX_DONE。
  5. 代码返回到ngx_http_core_module.c#L1169。
  6. 在ngx_http_finalize_request函数中,代码会进入ngx_http_request.c#L2426,随后跳转到ngx_http_request.c#L2720。
  7. 接着跳转到ngx_http_request.c#L2992,在ngx_http_set_keepalive函数中,最终会跳转到ngx_http_free_request(r, 0),此时内存池会被清理,对应ngx_http_request.c#L3654。

疑问

请求内存池被清理后,后续到达的剩余50字节会如何处理?步骤1中挂载的存储首次50字节的ngx_chain_t也会被删除,相关内存均来自内存池,那已接收的50字节会被丢弃吗?


内容的提问来源于stack exchange,提问作者Drakeeagle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:26:16