more detailed description of callbacks workflow

version0.2
Sergey Shepelev 16 years ago committed by Ryan
parent 37a0ff8928
commit 9b6b8c288c

@ -52,13 +52,6 @@ When data is received on the socket execute the parser and check for errors.
// handle error. usually just close the connection // handle error. usually just close the connection
} }
During the `http_parser_execute()` call, the callbacks set in `http_parser`
will be executed. The parser maintains state and never looks behind, so
buffering the data is not necessary. If you need to save certain data for
later usage, you can do that from the callbacks. (You can also `read()` into
a heap allocated buffer to avoid copying memory around if this fits your
application.)
Scalar valued message information such as `status_code`, `method`, and the Scalar valued message information such as `status_code`, `method`, and the
HTTP version are stored in the parser structure. This data is only HTTP version are stored in the parser structure. This data is only
temporarlly stored in `http_parser` and gets reset on each new message. If temporarlly stored in `http_parser` and gets reset on each new message. If
@ -74,6 +67,57 @@ need to inspect the body. Decoding gzip is non-neglagable amount of
processing (and requires making allocations). HTTP proxies using this processing (and requires making allocations). HTTP proxies using this
parser, for example, would not want such a feature. parser, for example, would not want such a feature.
Callbacks
---------
During the `http_parser_execute()` call, the callbacks set in `http_parser`
will be executed. The parser maintains state and never looks behind, so
buffering the data is not necessary. If you need to save certain data for
later usage, you can do that from the callbacks.
There are two types of callbacks:
* notification `typedef int (*http_cb) (http_parser*);`
Callbacks: on_message_begin, on_headers_complete, on_message_complete.
* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);`
Callbacks: (requests only) on_path, on_query_string, on_uri, on_fragment,
(common) on_header_field, on_header_value, on_body;
In case you parse HTTP message in chunks (i.e. `read()` request line
from socket, parse, read half headers, parse, etc) your data callbacks
may be called more than once. Http-parser guarantees that data pointer is only
valid for the lifetime of callback. You can also `read()` into a heap allocated
buffer to avoid copying memory around if this fits your application.
Reading headers may be a tricky task if you read/parse headers partially.
Basically, you need to remember whether last header callback was field or value
and apply following logic:
/* on_header_field and on_header_value shortened to on_h_*
------------------------ ------------ --------------------------------------------
| State (prev. callback) | Callback | Description/action |
------------------------ ------------ --------------------------------------------
| nothing (first call) | on_h_field | Allocate new buffer and copy callback data |
| | | into it |
------------------------ ------------ --------------------------------------------
| value | on_h_field | New header started. |
| | | Copy current name,value buffers to headers |
| | | list and allocate new buffer for new name |
------------------------ ------------ --------------------------------------------
| field | on_h_field | Previous name continues. Reallocate name |
| | | buffer and append callback data to it |
------------------------ ------------ --------------------------------------------
| field | on_h_value | Value for current header started. Allocate |
| | | new buffer and copy callback data to it |
------------------------ ------------ --------------------------------------------
| value | on_h_value | Value continues. Reallocate value buffer |
| | | and append callback data to it |
------------------------ ------------ --------------------------------------------
*/
See http://gist.github.com/155877 for a partial example of reading in
headers.
Releases Releases
-------- --------

Loading…
Cancel
Save