@@ -94,7 +94,7 @@ The Special Problem of Upgrade
9494------------------------------
9595
9696HTTP supports upgrading the connection to a different protocol. An
97- increasingly common example of this is the Web Socket protocol which sends
97+ increasingly common example of this is the WebSocket protocol which sends
9898a request like
9999
100100 GET /demo HTTP/1.1
@@ -106,8 +106,8 @@ a request like
106106
107107followed by non-HTTP data.
108108
109- (See http ://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 for more
110- information the Web Socket protocol.)
109+ (See [ RFC6455 ] ( https ://tools.ietf.org/html/rfc6455 ) for more information the
110+ WebSocket protocol.)
111111
112112To support this, the parser will treat this as a normal HTTP message without a
113113body, issuing both on_headers_complete and on_message_complete callbacks. However
@@ -137,6 +137,69 @@ There are two types of callbacks:
137137Callbacks must return 0 on success. Returning a non-zero value indicates
138138error to the parser, making it exit immediately.
139139
140+ For cases where it is necessary to pass local information to/from a callback,
141+ the ` http_parser ` object's ` data ` field can be used.
142+ An example of such a case is when using threads to handle a socket connection,
143+ parse a request, and then give a response over that socket. By instantiation
144+ of a thread-local struct containing relevant data (e.g. accepted socket,
145+ allocated memory for callbacks to write into, etc), a parser's callbacks are
146+ able to communicate data between the scope of the thread and the scope of the
147+ callback in a threadsafe manner. This allows http-parser to be used in
148+ multi-threaded contexts.
149+
150+ Example:
151+ ```
152+ typedef struct {
153+ socket_t sock;
154+ void* buffer;
155+ int buf_len;
156+ } custom_data_t;
157+
158+
159+ int my_url_callback(http_parser* parser, const char *at, size_t length) {
160+ /* access to thread local custom_data_t struct.
161+ Use this access save parsed data for later use into thread local
162+ buffer, or communicate over socket
163+ */
164+ parser->data;
165+ ...
166+ return 0;
167+ }
168+
169+ ...
170+
171+ void http_parser_thread(socket_t sock) {
172+ int nparsed = 0;
173+ /* allocate memory for user data */
174+ custom_data_t *my_data = malloc(sizeof(custom_data_t));
175+
176+ /* some information for use by callbacks.
177+ * achieves thread -> callback information flow */
178+ my_data->sock = sock;
179+
180+ /* instantiate a thread-local parser */
181+ http_parser *parser = malloc(sizeof(http_parser));
182+ http_parser_init(parser, HTTP_REQUEST); /* initialise parser */
183+ /* this custom data reference is accessible through the reference to the
184+ parser supplied to callback functions */
185+ parser->data = my_data;
186+
187+ http_parser_settings settings; / * set up callbacks */
188+ settings.on_url = my_url_callback;
189+
190+ /* execute parser */
191+ nparsed = http_parser_execute(parser, &settings, buf, recved);
192+
193+ ...
194+ /* parsed information copied from callback.
195+ can now perform action on data copied into thread-local memory from callbacks.
196+ achieves callback -> thread information flow */
197+ my_data->buffer;
198+ ...
199+ }
200+
201+ ```
202+
140203In case you parse HTTP message in chunks (i.e. ` read() ` request line
141204from socket, parse, read half headers, parse, etc) your data callbacks
142205may be called more than once. Http-parser guarantees that data pointer is only
0 commit comments