在开发http模块前,首先需要了解典型的http模块是如何介入nginx处理用户请求流程的。图3-1是一个简化的时序图,这里省略了许多异步调用,忽略了多个不同的http处理阶段,仅标识了在一个典型请求的处理过程中主要模块被调用的流程,以此帮助读者理解http模块如何处理用户请求。完整的流程将在第11章中详细介绍。
从图3-1中看到,worker进程会在一个for循环语句里反复调用事件模块检测网络事件。当事件模块检测到某个客户端发起的tcp请求时(接收到syn包),将会为它建立tcp连接,成功建立连接后根据nginx.conf文件中的配置会交由http框架处理。http框架会试图接收完整的http头部,并在接收到完整的http头部后将请求分发到具体的http模块中处理。这种分发策略是多样化的,其中最常见的是根据请求的uri和nginx.conf里location配置项的匹配度来决定如何分发(本章的例子正是应用这种分发策略,在第10章中会介绍其他分发策略)。http模块在处理请求的结束时,大多会向客户端发送响应,此时会自动地依次调用所有的http过滤模块,每个过滤模块可以根据配置文件决定自己的行为。例如,gzip过滤模块根据配置文件中的gzip on|off来决定是否压缩响应。http处理模块在返回时会将控制权交还给http框架,如果在返回前设置了subrequest,那么http框架还会继续异步地调用适合的http模块处理子请求。
开发http模块时,首先要注意的就是http框架到具体的http模块间数据流的传递,以及开发的http模块如何与诸多的过滤模块协同工作(第10章、第11章会详细介绍http框架)。下面正式进入http模块的开发环节。