lighttpd的state engine
当前由11个state组成,贯穿整个connection的生命周期.
有些state是针对特殊操作,还有一些state可能基本不会产生.
:connect
等待连接
:regstart
初始化read-idle定时器
:read
从网络读取http-request-header
:reqend
解析request
:readpost
从网络读取http-request-content
:handlereq
处理request(可能分发成子请求)
:respstart
准备response header
:write
写response-header + content到网络
:respend
清除environment, 记录request日志
:error
重置连接(incl. close())
:close
关闭连接(处理close)
GET请求的流程
connection在'connect'状态休眠以等待一个连接.
当连接建立时立即转入reqstart状态来初始化read-timer并开始从
网络读取数据. 一旦获取到HTTP-request终止符(CRLFCRLF),便把
header转入解析器进行解析.
被解析的request在'handlereq'状态下进行处理,处理后转入
respstart状态以准备HTTP-response header.在write状态,预备好的
内容被写入到网络. 当所有数据发送完毕时转入respend状态以记录
request日志并清除请求相关的环境. 当close()调用后connection重新
被设置为connect状态。
Keep-Alive
Keep-Alive处理的区别在于从respend直接跳转到reqstart状态而非
调用close()和accept()。
POST请求
发送的POST请求可能带有request-body,而这时会在
header被解析完毕后,在获知body的长度之后进入
readpost状态。
Pipelining
HTTP/1.1支持pipelining(发送多个请求而无须等待第一个请求的响应).
这在read状态中被透明处理.
不预期的errors
对于严重的错误,我们会转入error状态进行connection的reset.
仅在没有任何其它方式可以处理当前状况时(e.g. 客户端关闭连接).
如果可能我们将会返回http-status 500('internal server error')并在
errorlog中记录当前请求的错误信息.
如果我们需要在处于error时关注一些来到的数据,close状态用于
初始化一个半关闭连接并从网络上读取所有延迟的包。
子请求
FastCGI, CGI, ...的处理在handlereq的循环中进行.
函数
用于state-engine的关键函数
:state-engine
connnection_state_machine()
:connect
Nothing
:reqstart
(nothing)
: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()