Upgrade to 1.46.0
[platform/upstream/nghttp2.git] / third-party / llhttp / src / api.c
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
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);
50 extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
51 extern int wasm_on_message_complete(llhttp_t * p);
52
53 const llhttp_settings_t wasm_settings = {
54   wasm_on_message_begin,
55   wasm_on_url,
56   wasm_on_status,
57   wasm_on_header_field,
58   wasm_on_header_value,
59   wasm_on_headers_complete,
60   wasm_on_body,
61   wasm_on_message_complete,
62   NULL,
63   NULL,
64 };
65
66
67 llhttp_t* llhttp_alloc(llhttp_type_t type) {
68   llhttp_t* parser = malloc(sizeof(llhttp_t));
69   llhttp_init(parser, type, &wasm_settings);
70   return parser;
71 }
72
73 void llhttp_free(llhttp_t* parser) {
74   free(parser);
75 }
76
77 /* Some getters required to get stuff from the parser */
78
79 uint8_t llhttp_get_type(llhttp_t* parser) {
80   return parser->type;
81 }
82
83 uint8_t llhttp_get_http_major(llhttp_t* parser) {
84   return parser->http_major;
85 }
86
87 uint8_t llhttp_get_http_minor(llhttp_t* parser) {
88   return parser->http_minor;
89 }
90
91 uint8_t llhttp_get_method(llhttp_t* parser) {
92   return parser->method;
93 }
94
95 int llhttp_get_status_code(llhttp_t* parser) {
96   return parser->status_code;
97 }
98
99 uint8_t llhttp_get_upgrade(llhttp_t* parser) {
100   return parser->upgrade;
101 }
102
103 #endif  // defined(__wasm__)
104
105
106 void llhttp_reset(llhttp_t* parser) {
107   llhttp_type_t type = parser->type;
108   const llhttp_settings_t* settings = parser->settings;
109   void* data = parser->data;
110   uint8_t lenient_flags = parser->lenient_flags;
111
112   llhttp__internal_init(parser);
113
114   parser->type = type;
115   parser->settings = (void*) settings;
116   parser->data = data;
117   parser->lenient_flags = lenient_flags;
118 }
119
120
121 llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
122   return llhttp__internal_execute(parser, data, data + len);
123 }
124
125
126 void llhttp_settings_init(llhttp_settings_t* settings) {
127   memset(settings, 0, sizeof(*settings));
128 }
129
130
131 llhttp_errno_t llhttp_finish(llhttp_t* parser) {
132   int err;
133
134   /* We're in an error state. Don't bother doing anything. */
135   if (parser->error != 0) {
136     return 0;
137   }
138
139   switch (parser->finish) {
140     case HTTP_FINISH_SAFE_WITH_CB:
141       CALLBACK_MAYBE(parser, on_message_complete);
142       if (err != HPE_OK) return err;
143
144     /* FALLTHROUGH */
145     case HTTP_FINISH_SAFE:
146       return HPE_OK;
147     case HTTP_FINISH_UNSAFE:
148       parser->reason = "Invalid EOF state";
149       return HPE_INVALID_EOF_STATE;
150     default:
151       abort();
152   }
153 }
154
155
156 void llhttp_pause(llhttp_t* parser) {
157   if (parser->error != HPE_OK) {
158     return;
159   }
160
161   parser->error = HPE_PAUSED;
162   parser->reason = "Paused";
163 }
164
165
166 void llhttp_resume(llhttp_t* parser) {
167   if (parser->error != HPE_PAUSED) {
168     return;
169   }
170
171   parser->error = 0;
172 }
173
174
175 void llhttp_resume_after_upgrade(llhttp_t* parser) {
176   if (parser->error != HPE_PAUSED_UPGRADE) {
177     return;
178   }
179
180   parser->error = 0;
181 }
182
183
184 llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
185   return parser->error;
186 }
187
188
189 const char* llhttp_get_error_reason(const llhttp_t* parser) {
190   return parser->reason;
191 }
192
193
194 void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
195   parser->reason = reason;
196 }
197
198
199 const char* llhttp_get_error_pos(const llhttp_t* parser) {
200   return parser->error_pos;
201 }
202
203
204 const char* llhttp_errno_name(llhttp_errno_t err) {
205 #define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME;
206   switch (err) {
207     HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
208     default: abort();
209   }
210 #undef HTTP_ERRNO_GEN
211 }
212
213
214 const char* llhttp_method_name(llhttp_method_t method) {
215 #define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
216   switch (method) {
217     HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN)
218     default: abort();
219   }
220 #undef HTTP_METHOD_GEN
221 }
222
223
224 void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
225   if (enabled) {
226     parser->lenient_flags |= LENIENT_HEADERS;
227   } else {
228     parser->lenient_flags &= ~LENIENT_HEADERS;
229   }
230 }
231
232
233 void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
234   if (enabled) {
235     parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
236   } else {
237     parser->lenient_flags &= ~LENIENT_CHUNKED_LENGTH;
238   }
239 }
240
241
242 void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
243   if (enabled) {
244     parser->lenient_flags |= LENIENT_KEEP_ALIVE;
245   } else {
246     parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
247   }
248 }
249
250 /* Callbacks */
251
252
253 int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
254   int err;
255   CALLBACK_MAYBE(s, on_message_begin);
256   return err;
257 }
258
259
260 int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
261   int err;
262   SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);
263   return err;
264 }
265
266
267 int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
268   int err;
269   CALLBACK_MAYBE(s, on_url_complete);
270   return err;
271 }
272
273
274 int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
275   int err;
276   SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p);
277   return err;
278 }
279
280
281 int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
282   int err;
283   CALLBACK_MAYBE(s, on_status_complete);
284   return err;
285 }
286
287
288 int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
289   int err;
290   SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p);
291   return err;
292 }
293
294
295 int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
296   int err;
297   CALLBACK_MAYBE(s, on_header_field_complete);
298   return err;
299 }
300
301
302 int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
303   int err;
304   SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p);
305   return err;
306 }
307
308
309 int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
310   int err;
311   CALLBACK_MAYBE(s, on_header_value_complete);
312   return err;
313 }
314
315
316 int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
317   int err;
318   CALLBACK_MAYBE(s, on_headers_complete);
319   return err;
320 }
321
322
323 int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
324   int err;
325   CALLBACK_MAYBE(s, on_message_complete);
326   return err;
327 }
328
329
330 int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
331   int err;
332   SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p);
333   return err;
334 }
335
336
337 int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
338   int err;
339   CALLBACK_MAYBE(s, on_chunk_header);
340   return err;
341 }
342
343
344 int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
345   int err;
346   CALLBACK_MAYBE(s, on_chunk_complete);
347   return err;
348 }
349
350
351 /* Private */
352
353
354 void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
355                    const char* msg) {
356   if (p == endp) {
357     fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type,
358             s->flags, msg);
359   } else {
360     fprintf(stderr, "p=%p type=%d flags=%02x next=%02x   debug=%s\n", s,
361             s->type, s->flags, *p, msg);
362   }
363 }