1============================ 2The State Engine of lighttpd 3============================ 4 5------------ 6Module: core 7------------ 8 9:Author: Jan Kneschke 10:Date: $Date: 2004/08/01 07:01:29 $ 11:Revision: $Revision: 1.1 $ 12 13:abstract: 14 This is a short summary of the state-engine which is driving the lighttpd 15 webserver. It describes the basic concepts and the way the different parts 16 of the server are connected. 17 18.. meta:: 19 :keywords: lighttpd, state-engine 20 21.. contents:: Table of Contents 22 23Description 24=========== 25 26States 27------ 28 29The state-engine is currently made of 11 states which are walk-through on 30the way each connection. Some of them are specific for a special operation 31and some may never be hit at all. 32 33:connect: 34 waiting for a connection 35:reqstart: 36 init the read-idle timer 37:read: 38 read http-request-header from network 39:reqend: 40 parse request 41:readpost: 42 read http-request-content from network 43:handlereq: 44 handle the request internally (might result in sub-requests) 45:respstart: 46 prepare response header 47:write: 48 write response-header + content to network 49:respend: 50 cleanup environment, log request 51:error: 52 reset connection (incl. close()) 53:close: 54 close connection (handle lingering close) 55 56.. image:: state.png 57 58A simple GET request (green path) 59--------------------------------- 60 61The connection is idling in the 'connect' state waiting for a connection. 62As soon as the connection is set up we init the read-timer in 'reqstart' 63and start to read data from the network. As soon as we get the 64HTTP-request terminator (CRLFCRLF) we forward the header to the parser. 65 66The parsed request is handled by 'handlereq' and as soon as a decision out 67the request is made it is sent to 'respstart' to prepare the 68HTTP-response header. In the 'write' state the prepare content is sent out 69to the network. When everything is sent 'respend' is entered to log the 70request and cleanup the environment. After the close() call the connection 71is set back to the 'connect' state again. 72 73Keep-Alive (blue path) 74---------------------- 75 76The Keep-Alive handling is implemented by going from the 'respend' 77directly to 'reqstart' without the close() and the accept() calls. 78 79POST requests (grey path) 80------------------------- 81 82As requests might contain a request-body the state 'readpost' entered as 83soon as the header is parsed and we know how much data we expect. 84 85Pipelining 86---------- 87 88HTTP/1.1 supports pipelining (sending multiple requests without waiting 89for the response of the first request). This is handled transparently by 90the 'read' state. 91 92Unexpected errors (red path) 93---------------------------- 94 95For really hard errors we use the 'error' state which resets the 96connection and can be call from every state. It is only use if there is no 97other way to handle the issue (e.g. client-side close of the connection). 98If possible we should use http-status 500 ('internal server error') and 99log the issue in the errorlog. 100 101If we have to take care of some data which is coming in after we ran into 102the error condition the 'close' state is used the init a half-close and 103read all the delay packet from the network. 104 105Sub-Requests (lightblue) 106------------------------ 107 108The FastCGI, CGI, ... integration is done by introducing a loop in 109'handlereq' to handle all aspect which are necessary to find out what has 110to be sent back to the client. 111 112Functions 113========= 114 115Important functions used by the state-engine 116 117:state-engine: 118 119- ``connection_state_machine()`` 120 121:connect: 122 123- (nothing) 124 125:reqstart: 126 127- (nothing) 128 129:read: 130 131- ``connection_handle_read_state()`` 132- ``connection_handle_read()`` 133 134:reqend: 135 136- ``http_request_parse()`` 137 138:readpost: 139 140- ``connection_handle_read_state()`` 141- ``connection_handle_read()`` 142 143:handlereq: 144 145- ``http_response_prepare()`` 146 147:respstart: 148 149- ``connection_handle_write_prepare()`` 150 151:write: 152 153- ``connection_handle_write()`` 154 155:respend: 156 157- ``plugins_call_handle_request_done()`` 158- ``plugins_call_handle_connection_close()`` 159- ``connection_close()`` (if not keep-alive) 160- ``connection_reset()`` 161 162:error: 163 164- ``plugins_call_handle_request_done()`` 165- ``plugins_call_handle_connection_close()`` 166- ``connection_reset()`` 167 168:close: 169 170- ``connection_close()`` 171