三、丢弃剩余的包体
ngx_http_discarded_request_body_handler用于在一次调度中没有丢弃完所有包体,则该函数会表调用,用于丢弃剩余的包体。函数内部也会调用实际的丢弃包体函数,进行接收包体然后丢弃操作。nginx服务器做了一个优化处理,会设置一个总超时时间,如果超过这个时间都还没有丢弃完全部的包体,则会关闭这个连接。这是一种对服务器保护的措施,避免长时间的丢包操作占用服务器资源。
//功能: 第1次未能全部丢弃包体时,该函数被调用。之后有读事件时,该函数被调用
void ngx_http_discarded_request_body_handler(ngx_http_request_t *r)
{
//检测延迟关闭时间,如果总时长超过了lingering_time,则不再接收任何包体,这是一个总时间。
//总超时后,将直接光比连接
if (r->lingering_time)
{
timer = (ngx_msec_t) (r->lingering_time - ngx_time());
//已经到达了延迟关闭时间
if (timer <= 0)
{
//清空丢弃包体标识,表示包体已经丢弃
r->discard_body = 0;
//延迟关闭开关清0
r->lingering_close = 0;
ngx_http_finalize_request(r, NGX_ERROR);
return;
}
}
//接收包体后丢弃
rc = ngx_http_read_discarded_request_body(r);
//表示包体已经全部丢弃
if (rc == NGX_OK)
{
r->discard_body = 0; //包体已经全部接收完
r->lingering_close = 0; //清空延迟关闭标志
ngx_http_finalize_request(r, NGX_DONE);
return;
}
}
ngx_http_discarded_request_body_handler这个函数是怎么被事件对象调用的呢? 在前面的文章已经分析了,ngx_connection_s读事件的回调设置为ngx_http_request_handler。 因此在读事件发生时,会回调请求结构的读回调。如果还不是不清楚这个调用过程,可以参考: nginx处理http请求这篇文章
static void ngx_http_request_handler(ngx_event_t *ev)
{
//如果同时发生读写事件,则只有写事件才会触发。写事件优先级更高
if (ev->write)
{
r->write_event_handler(r); //在函数ngx_http_handler设置为ngx_http_core_run_phases
}
else
{
r->read_event_handler(r); //在函数ngx_http_process_request设置为ngx_http_block_reading
}
}
到此为止,http框架丢弃包体的流程已经分析完成了。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!








