lighttpd 的状态引擎¶
描述¶
状态¶
状态引擎目前由 11 种状态组成,每种连接都会遍历这些状态。其中一些是针对特定操作的
而有些可能永远不会被触发。
- connect
等待连接 - reqstart
初始化读取空闲计时器 - read
从网络读取 HTTP 请求头 - reqend
解析请求 - readpost
从网络读取 HTTP 请求内容 - handlereq
内部处理请求(可能会产生子请求) - respstart
准备响应头 - write
将响应头 + 内容写入网络 - respend
清理环境,记录请求 - error
重置连接(包括 close()) - close
关闭连接(处理滞留关闭)
一个简单的 GET 请求(绿色路径)¶
连接在 'connect' 状态下空闲,等待建立连接。
一旦连接建立,我们会在 'reqstart' 状态中初始化读取计时器
并开始从网络读取数据。一旦我们收到
HTTP 请求终止符 (CRLFCRLF),我们会将请求头转发给解析器。
解析后的请求由 'handlereq' 处理,一旦对请求做出决定,
它就会被发送到 'respstart' 状态以准备
HTTP 响应头。在 'write' 状态中,准备好的内容会被发送到
网络。当所有内容都发送完毕后,进入 'respend' 状态记录
请求并清理环境。在 close() 调用之后,连接
会再次回到 'connect' 状态。
Keep-Alive(蓝色路径)¶
Keep-Alive 处理是通过从 'respend' 状态
直接跳转到 'reqstart' 实现的,无需调用 close() 和 accept()。
POST 请求(灰色路径)¶
由于请求可能包含请求体,一旦请求头被解析并且我们知道期望的数据量,就会进入 'readpost' 状态。
一旦解析了标头,我们就知道预期的数据量。
管线化¶
HTTP/1.1 支持管线化(在不等待第一个请求响应的情况下发送多个请求)。这由
作为第一个请求的响应)。这由以下方式透明处理:
'read' 状态透明地处理。
意外错误(红色路径)¶
对于严重的错误,我们使用 'error' 状态,它会重置
连接,并且可以从任何状态调用。它仅在没有
其他方式处理问题时使用(例如,客户端关闭连接)。
如果可能,我们应该使用 HTTP 状态码 500(“内部服务器错误”)并
将问题记录在错误日志中。
如果我们需要处理在我们遇到错误情况后进入的某些数据,
则使用 'close' 状态来初始化半关闭并
从网络读取所有延迟的数据包。
子请求(浅蓝色)¶
FastCGI、CGI 等集成是通过在 'handlereq' 中引入一个循环来完成的,
以处理确定需要向客户端发送什么所需的所有方面。
将被发送回客户端。
函数¶
状态引擎使用的重要函数
- 状态引擎
connection_state_machine()
- connect
(无) - reqstart
(无) - read
connection_handle_read_state()
connection_handle_read()
- reqend
http_request_parse()
- readpost
connection_handle_read_state()
connection_handle_read()
- handlereq
http_response_prepare()
- respstart
connection_handle_write_prepare()
- write
connection_handle_write()
- respend
plugins_call_handle_request_done()
plugins_call_handle_connection_close()
connection_close()
(如果不是 Keep-Alive)connection_reset()
- error
plugins_call_handle_request_done()
plugins_call_handle_connection_close()
connection_reset()
- close
connection_close()