5.2.4 process_header回调方法

process_header是用于解析上游服务器返回的基于TCP的响应头部的,因此,process_header可能会被多次调用,它的调用次数与process_header的返回值有关。如图5-5所示,如果process_header返回NGX_AGAIN,这意味着还没有接收到完整的响应头部,如果再次接收到上游服务器发来的TCP流,还会把它当做头部,仍然调用process_header处理。而在图5-6中,如果process_header返回NGX_OK(或者其他非NGX_AGAIN的值),那么在这次连接的后续处理中将不会再次调用process_header。

5.2.4 process_header回调方法 - 图1

图 5-5 process_header回调场景的序列图

下面简单地介绍一下图5-5中列出的步骤。

1)Nginx主循环中会定期地调用事件模块,检查是否有网络事件发生。

2)事件模块接收到上游服务器发来的响应时,会回调upstream模块处理。

3)upstream模块这时可以从套接字缓冲区中读取到来自上游的TCP流。

4)读取的响应会存放到r->upstream->buffer指向的内存中。注意:在未解析完响应头部前,若多次接收到字符流,所有接收自上游的响应都会完整地存放到r->upstream->buffer缓冲区中。因此,在解析上游响应包头时,如果buffer缓冲区全满却还没有解析到完整的响应头部(也就是说,process_header一直在返回NGX_AGAIN),那么请求就会出错。

5)调用mytest模块实现的process_header方法。

6)process_header方法实际上就是在解析r->upstream->buffer缓冲区,试图从中取到完整的响应头部(当然,如果上游服务器与Nginx通过HTTP通信,就是接收到完整的HTTP头部)。

7)如果process_header返回NGX_AGAIN,那么表示还没有解析到完整的响应头部,下次还会调用process_header处理接收到的上游响应。

8)调用无阻塞的读取套接字接口。

9)这时有可能返回套接字缓冲区已经为空。

10)当第2步中的读取上游响应事件处理完毕后,控制权交还给事件模块。

11)事件模块处理完本轮网络事件后,交还控制权给Nginx主循环。