Lighttpd启动时完成了一系列初始化操作后,就进入了一个包含11个状态的有限状态机中。
每个连接都是一个connection实例(con),状态的切换取决于con->state。
lighttpd经过初步处理后将con的基本信息初始化,而插件对事件的处理就是针对con进行的,它拿到con后按照业务需要进行相应处理,然后再交还给lighttpd,lighttpd根据con中的信息完成响应。
状态定义如下:
typedef enum
{
CON_STATE_CONNECT, //connect 连接开始
CON_STATE_REQUEST_START, //reqstart 开始读取请求
CON_STATE_READ, //read 读取并解析请求
CON_STATE_REQUEST_END, //reqend 读取请求结束
CON_STATE_READ_POST, //readpost 读取post数据
CON_STATE_HANDLE_REQUEST, //handelreq 处理请求
CON_STATE_RESPONSE_START, //respstart 开始回复
CON_STATE_WRITE, //write 回复写数据
CON_STATE_RESPONSE_END, //respend 回复结束
CON_STATE_ERROR, //error 出错
CON_STATE_CLOSE //close 连接关闭
} connection_state_t;
下面就是lighttpd的状态机:
在每个连接中都会保存这样一个状态机,用以表示当前连接的状态。
在连接建立以后,在connections.c/connection_accpet()函数中,lighttpd调用connection_set_state()函数,将新建立的连接的状态设置为CON_STATE_REQUEST_START。在这个状态中,lighttpd记录连接建立的时间等信息。
整个状态机的核心函数是connections.c/ connection_state_machine()函数。
函数的主体部分删减之后如下:
int connection_state_machine(server * srv, connection * con)
{
int done = 0, r;
while (done == 0)
{
size_t ostate = con -> state;
int b;