11.10.4 ngx_http_finalize_connection

ngx_http_finalize_connection方法虽然比ngx_http_close_request方法高了一个层次,但HTTP模块一般还是不会直接调用它。ngx_http_finalize_connection方法在结束请求时,解决了keepalive特性和子请求的问题,图11-25中展示了它所做的工作。

11.10.4 ngx_http_finalize_connection - 图1

图 11-25 ngx_http_finalize_connection方法的流程

下面简单分析一下ngx_http_finalize_connection方法所做的工作。

1)首先查看原始请求的引用计数,如果不等于1,则表示还有多个动作在操作着请求,接着继续检查discard_body标志位。如果discard_body为0,则直接跳到第3步;如果discard_body为1,则表示正在丢弃包体,这时会再一次把请求的read_event_handler成员设为ngx_http_discarded_request_body_handler方法,就如同11.8.2节中描述的一样。

如果引用计数为1,则说明这时要真的准备结束请求了。不过,还要检查请求的keepalive成员,如果keepalive为1,则说明这个请求需要释放,但TCP连接还是要复用的,这时跳到第5步执行;如果keepalive为0就不需要考虑keepalive请求了,但还需要检测请求的lingering_close成员,如果lingering_close为1,则说明需要延迟关闭请求,这时也不能真的去结束请求,而是跳到第4步,如果lingering_close为0,才真的跳到第5步结束请求。

2)将读事件添加到定时器中,其中超时时间是lingering_timeout配置项。

3)调用11.10.3节介绍的ngx_http_close_request方法结束请求。

4)调用ngx_http_set_lingering_close方法延迟关闭请求。实际上,这个方法的意义就在于把一些必须做的事情做完(如接收用户端发来的字符流)再关闭连接。

5)调用ngx_http_set_keepalive方法将当前连接设为keepalive状态。它实际上会把表示请求的ngx_http_request_t结构体释放,却又不会调用ngx_http_close_connection方法关闭连接,同时也在检测keepalive连接是否超时,对于这个方法,此处不做详细解释。