1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 
5 #include "llhttp.h"
6 
7 #define CALLBACK_MAYBE(PARSER, NAME)                                          \
8   do {                                                                        \
9     const llhttp_settings_t* settings;                                        \
10     settings = (const llhttp_settings_t*) (PARSER)->settings;                 \
11     if (settings == NULL || settings->NAME == NULL) {                         \
12       err = 0;                                                                \
13       break;                                                                  \
14     }                                                                         \
15     err = settings->NAME((PARSER));                                           \
16   } while (0)
17 
18 #define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN)                         \
19   do {                                                                        \
20     const llhttp_settings_t* settings;                                        \
21     settings = (const llhttp_settings_t*) (PARSER)->settings;                 \
22     if (settings == NULL || settings->NAME == NULL) {                         \
23       err = 0;                                                                \
24       break;                                                                  \
25     }                                                                         \
26     err = settings->NAME((PARSER), (START), (LEN));                           \
27     if (err == -1) {                                                          \
28       err = HPE_USER;                                                         \
29       llhttp_set_error_reason((PARSER), "Span callback error in " #NAME);     \
30     }                                                                         \
31   } while (0)
32 
llhttp_init(llhttp_t* parser, llhttp_type_t type, const llhttp_settings_t* settings)33 void llhttp_init(llhttp_t* parser, llhttp_type_t type,
34                  const llhttp_settings_t* settings) {
35   llhttp__internal_init(parser);
36 
37   parser->type = type;
38   parser->settings = (void*) settings;
39 }
40 
41 
42 #if defined(__wasm__)
43 
44 extern int wasm_on_message_begin(llhttp_t * p);
45 extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
46 extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
47 extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
48 extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
49 extern int wasm_on_headers_complete(llhttp_t * p, int status_code,
50                                     uint8_t upgrade, int should_keep_alive);
51 extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
52 extern int wasm_on_message_complete(llhttp_t * p);
53 
wasm_on_headers_complete_wrap(llhttp_t* p)54 static int wasm_on_headers_complete_wrap(llhttp_t* p) {
55   return wasm_on_headers_complete(p, p->status_code, p->upgrade,
56                                   llhttp_should_keep_alive(p));
57 }
58 
59 const llhttp_settings_t wasm_settings = {
60   wasm_on_message_begin,
61   wasm_on_url,
62   wasm_on_status,
63   NULL,
64   NULL,
65   wasm_on_header_field,
66   wasm_on_header_value,
67   NULL,
68   NULL,
69   wasm_on_headers_complete_wrap,
70   wasm_on_body,
71   wasm_on_message_complete,
72   NULL,
73   NULL,
74   NULL,
75   NULL,
76   NULL,
77   NULL,
78   NULL,
79   NULL,
80   NULL,
81   NULL,
82   NULL,
83 };
84 
85 
llhttp_alloc(llhttp_type_t type)86 llhttp_t* llhttp_alloc(llhttp_type_t type) {
87   llhttp_t* parser = malloc(sizeof(llhttp_t));
88   llhttp_init(parser, type, &wasm_settings);
89   return parser;
90 }
91 
llhttp_free(llhttp_t* parser)92 void llhttp_free(llhttp_t* parser) {
93   free(parser);
94 }
95 
96 #endif  // defined(__wasm__)
97 
98 /* Some getters required to get stuff from the parser */
99 
llhttp_get_type(llhttp_t* parser)100 uint8_t llhttp_get_type(llhttp_t* parser) {
101   return parser->type;
102 }
103 
llhttp_get_http_major(llhttp_t* parser)104 uint8_t llhttp_get_http_major(llhttp_t* parser) {
105   return parser->http_major;
106 }
107 
llhttp_get_http_minor(llhttp_t* parser)108 uint8_t llhttp_get_http_minor(llhttp_t* parser) {
109   return parser->http_minor;
110 }
111 
llhttp_get_method(llhttp_t* parser)112 uint8_t llhttp_get_method(llhttp_t* parser) {
113   return parser->method;
114 }
115 
llhttp_get_status_code(llhttp_t* parser)116 int llhttp_get_status_code(llhttp_t* parser) {
117   return parser->status_code;
118 }
119 
llhttp_get_upgrade(llhttp_t* parser)120 uint8_t llhttp_get_upgrade(llhttp_t* parser) {
121   return parser->upgrade;
122 }
123 
124 
llhttp_reset(llhttp_t* parser)125 void llhttp_reset(llhttp_t* parser) {
126   llhttp_type_t type = parser->type;
127   const llhttp_settings_t* settings = parser->settings;
128   void* data = parser->data;
129   uint8_t lenient_flags = parser->lenient_flags;
130 
131   llhttp__internal_init(parser);
132 
133   parser->type = type;
134   parser->settings = (void*) settings;
135   parser->data = data;
136   parser->lenient_flags = lenient_flags;
137 }
138 
139 
llhttp_execute(llhttp_t* parser, const char* data, size_t len)140 llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
141   return llhttp__internal_execute(parser, data, data + len);
142 }
143 
144 
llhttp_settings_init(llhttp_settings_t* settings)145 void llhttp_settings_init(llhttp_settings_t* settings) {
146   memset(settings, 0, sizeof(*settings));
147 }
148 
149 
llhttp_finish(llhttp_t* parser)150 llhttp_errno_t llhttp_finish(llhttp_t* parser) {
151   int err;
152 
153   /* We're in an error state. Don't bother doing anything. */
154   if (parser->error != 0) {
155     return 0;
156   }
157 
158   switch (parser->finish) {
159     case HTTP_FINISH_SAFE_WITH_CB:
160       CALLBACK_MAYBE(parser, on_message_complete);
161       if (err != HPE_OK) return err;
162 
163     /* FALLTHROUGH */
164     case HTTP_FINISH_SAFE:
165       return HPE_OK;
166     case HTTP_FINISH_UNSAFE:
167       parser->reason = "Invalid EOF state";
168       return HPE_INVALID_EOF_STATE;
169     default:
170       abort();
171   }
172 }
173 
174 
llhttp_pause(llhttp_t* parser)175 void llhttp_pause(llhttp_t* parser) {
176   if (parser->error != HPE_OK) {
177     return;
178   }
179 
180   parser->error = HPE_PAUSED;
181   parser->reason = "Paused";
182 }
183 
184 
llhttp_resume(llhttp_t* parser)185 void llhttp_resume(llhttp_t* parser) {
186   if (parser->error != HPE_PAUSED) {
187     return;
188   }
189 
190   parser->error = 0;
191 }
192 
193 
llhttp_resume_after_upgrade(llhttp_t* parser)194 void llhttp_resume_after_upgrade(llhttp_t* parser) {
195   if (parser->error != HPE_PAUSED_UPGRADE) {
196     return;
197   }
198 
199   parser->error = 0;
200 }
201 
202 
llhttp_get_errno(const llhttp_t* parser)203 llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
204   return parser->error;
205 }
206 
207 
llhttp_get_error_reason(const llhttp_t* parser)208 const char* llhttp_get_error_reason(const llhttp_t* parser) {
209   return parser->reason;
210 }
211 
212 
llhttp_set_error_reason(llhttp_t* parser, const char* reason)213 void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
214   parser->reason = reason;
215 }
216 
217 
llhttp_get_error_pos(const llhttp_t* parser)218 const char* llhttp_get_error_pos(const llhttp_t* parser) {
219   return parser->error_pos;
220 }
221 
222 
llhttp_errno_name(llhttp_errno_t err)223 const char* llhttp_errno_name(llhttp_errno_t err) {
224 #define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME;
225   switch (err) {
226     HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
227     default: abort();
228   }
229 #undef HTTP_ERRNO_GEN
230 }
231 
232 
llhttp_method_name(llhttp_method_t method)233 const char* llhttp_method_name(llhttp_method_t method) {
234 #define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
235   switch (method) {
236     HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN)
237     default: abort();
238   }
239 #undef HTTP_METHOD_GEN
240 }
241 
llhttp_status_name(llhttp_status_t status)242 const char* llhttp_status_name(llhttp_status_t status) {
243 #define HTTP_STATUS_GEN(NUM, NAME, STRING) case HTTP_STATUS_##NAME: return #STRING;
244   switch (status) {
245     HTTP_STATUS_MAP(HTTP_STATUS_GEN)
246     default: abort();
247   }
248 #undef HTTP_STATUS_GEN
249 }
250 
251 
llhttp_set_lenient_headers(llhttp_t* parser, int enabled)252 void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
253   if (enabled) {
254     parser->lenient_flags |= LENIENT_HEADERS;
255   } else {
256     parser->lenient_flags &= ~LENIENT_HEADERS;
257   }
258 }
259 
260 
llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled)261 void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
262   if (enabled) {
263     parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
264   } else {
265     parser->lenient_flags &= ~LENIENT_CHUNKED_LENGTH;
266   }
267 }
268 
269 
llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled)270 void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
271   if (enabled) {
272     parser->lenient_flags |= LENIENT_KEEP_ALIVE;
273   } else {
274     parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
275   }
276 }
277 
llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled)278 void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled) {
279   if (enabled) {
280     parser->lenient_flags |= LENIENT_TRANSFER_ENCODING;
281   } else {
282     parser->lenient_flags &= ~LENIENT_TRANSFER_ENCODING;
283   }
284 }
285 
llhttp_set_lenient_version(llhttp_t* parser, int enabled)286 void llhttp_set_lenient_version(llhttp_t* parser, int enabled) {
287   if (enabled) {
288     parser->lenient_flags |= LENIENT_VERSION;
289   } else {
290     parser->lenient_flags &= ~LENIENT_VERSION;
291   }
292 }
293 
llhttp_set_lenient_data_after_close(llhttp_t* parser, int enabled)294 void llhttp_set_lenient_data_after_close(llhttp_t* parser, int enabled) {
295   if (enabled) {
296     parser->lenient_flags |= LENIENT_DATA_AFTER_CLOSE;
297   } else {
298     parser->lenient_flags &= ~LENIENT_DATA_AFTER_CLOSE;
299   }
300 }
301 
llhttp_set_lenient_optional_lf_after_cr(llhttp_t* parser, int enabled)302 void llhttp_set_lenient_optional_lf_after_cr(llhttp_t* parser, int enabled) {
303   if (enabled) {
304     parser->lenient_flags |= LENIENT_OPTIONAL_LF_AFTER_CR;
305   } else {
306     parser->lenient_flags &= ~LENIENT_OPTIONAL_LF_AFTER_CR;
307   }
308 }
309 
llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int enabled)310 void llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int enabled) {
311   if (enabled) {
312     parser->lenient_flags |= LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
313   } else {
314     parser->lenient_flags &= ~LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
315   }
316 }
317 
318 /* Callbacks */
319 
320 
llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp)321 int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
322   int err;
323   CALLBACK_MAYBE(s, on_message_begin);
324   return err;
325 }
326 
327 
llhttp__on_url(llhttp_t* s, const char* p, const char* endp)328 int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
329   int err;
330   SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);
331   return err;
332 }
333 
334 
llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp)335 int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
336   int err;
337   CALLBACK_MAYBE(s, on_url_complete);
338   return err;
339 }
340 
341 
llhttp__on_status(llhttp_t* s, const char* p, const char* endp)342 int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
343   int err;
344   SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p);
345   return err;
346 }
347 
348 
llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp)349 int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
350   int err;
351   CALLBACK_MAYBE(s, on_status_complete);
352   return err;
353 }
354 
355 
llhttp__on_method(llhttp_t* s, const char* p, const char* endp)356 int llhttp__on_method(llhttp_t* s, const char* p, const char* endp) {
357   int err;
358   SPAN_CALLBACK_MAYBE(s, on_method, p, endp - p);
359   return err;
360 }
361 
362 
llhttp__on_method_complete(llhttp_t* s, const char* p, const char* endp)363 int llhttp__on_method_complete(llhttp_t* s, const char* p, const char* endp) {
364   int err;
365   CALLBACK_MAYBE(s, on_method_complete);
366   return err;
367 }
368 
369 
llhttp__on_version(llhttp_t* s, const char* p, const char* endp)370 int llhttp__on_version(llhttp_t* s, const char* p, const char* endp) {
371   int err;
372   SPAN_CALLBACK_MAYBE(s, on_version, p, endp - p);
373   return err;
374 }
375 
376 
llhttp__on_version_complete(llhttp_t* s, const char* p, const char* endp)377 int llhttp__on_version_complete(llhttp_t* s, const char* p, const char* endp) {
378   int err;
379   CALLBACK_MAYBE(s, on_version_complete);
380   return err;
381 }
382 
383 
llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp)384 int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
385   int err;
386   SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p);
387   return err;
388 }
389 
390 
llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp)391 int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
392   int err;
393   CALLBACK_MAYBE(s, on_header_field_complete);
394   return err;
395 }
396 
397 
llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp)398 int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
399   int err;
400   SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p);
401   return err;
402 }
403 
404 
llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp)405 int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
406   int err;
407   CALLBACK_MAYBE(s, on_header_value_complete);
408   return err;
409 }
410 
411 
llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp)412 int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
413   int err;
414   CALLBACK_MAYBE(s, on_headers_complete);
415   return err;
416 }
417 
418 
llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp)419 int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
420   int err;
421   CALLBACK_MAYBE(s, on_message_complete);
422   return err;
423 }
424 
425 
llhttp__on_body(llhttp_t* s, const char* p, const char* endp)426 int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
427   int err;
428   SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p);
429   return err;
430 }
431 
432 
llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp)433 int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
434   int err;
435   CALLBACK_MAYBE(s, on_chunk_header);
436   return err;
437 }
438 
439 
llhttp__on_chunk_extension_name(llhttp_t* s, const char* p, const char* endp)440 int llhttp__on_chunk_extension_name(llhttp_t* s, const char* p, const char* endp) {
441   int err;
442   SPAN_CALLBACK_MAYBE(s, on_chunk_extension_name, p, endp - p);
443   return err;
444 }
445 
446 
llhttp__on_chunk_extension_name_complete(llhttp_t* s, const char* p, const char* endp)447 int llhttp__on_chunk_extension_name_complete(llhttp_t* s, const char* p, const char* endp) {
448   int err;
449   CALLBACK_MAYBE(s, on_chunk_extension_name_complete);
450   return err;
451 }
452 
453 
llhttp__on_chunk_extension_value(llhttp_t* s, const char* p, const char* endp)454 int llhttp__on_chunk_extension_value(llhttp_t* s, const char* p, const char* endp) {
455   int err;
456   SPAN_CALLBACK_MAYBE(s, on_chunk_extension_value, p, endp - p);
457   return err;
458 }
459 
460 
llhttp__on_chunk_extension_value_complete(llhttp_t* s, const char* p, const char* endp)461 int llhttp__on_chunk_extension_value_complete(llhttp_t* s, const char* p, const char* endp) {
462   int err;
463   CALLBACK_MAYBE(s, on_chunk_extension_value_complete);
464   return err;
465 }
466 
467 
llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp)468 int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
469   int err;
470   CALLBACK_MAYBE(s, on_chunk_complete);
471   return err;
472 }
473 
474 
llhttp__on_reset(llhttp_t* s, const char* p, const char* endp)475 int llhttp__on_reset(llhttp_t* s, const char* p, const char* endp) {
476   int err;
477   CALLBACK_MAYBE(s, on_reset);
478   return err;
479 }
480 
481 
482 /* Private */
483 
484 
llhttp__debug(llhttp_t* s, const char* p, const char* endp, const char* msg)485 void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
486                    const char* msg) {
487   if (p == endp) {
488     fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type,
489             s->flags, msg);
490   } else {
491     fprintf(stderr, "p=%p type=%d flags=%02x next=%02x   debug=%s\n", s,
492             s->type, s->flags, *p, msg);
493   }
494 }
495