7 #define CALLBACK_MAYBE(PARSER, NAME) \
9 const llhttp_settings_t* settings; \
10 settings = (const llhttp_settings_t*) (PARSER)->settings; \
11 if (settings == NULL || settings->NAME == NULL) { \
15 err = settings->NAME((PARSER)); \
18 #define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \
20 const llhttp_settings_t* settings; \
21 settings = (const llhttp_settings_t*) (PARSER)->settings; \
22 if (settings == NULL || settings->NAME == NULL) { \
26 err = settings->NAME((PARSER), (START), (LEN)); \
29 llhttp_set_error_reason((PARSER), "Span callback error in " #NAME); \
33 void llhttp_init(llhttp_t* parser, llhttp_type_t type,
34 const llhttp_settings_t* settings) {
35 llhttp__internal_init(parser);
38 parser->settings = (void*) settings;
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);
53 const llhttp_settings_t wasm_settings = {
54 wasm_on_message_begin,
59 wasm_on_headers_complete,
61 wasm_on_message_complete,
67 llhttp_t* llhttp_alloc(llhttp_type_t type) {
68 llhttp_t* parser = malloc(sizeof(llhttp_t));
69 llhttp_init(parser, type, &wasm_settings);
73 void llhttp_free(llhttp_t* parser) {
77 /* Some getters required to get stuff from the parser */
79 uint8_t llhttp_get_type(llhttp_t* parser) {
83 uint8_t llhttp_get_http_major(llhttp_t* parser) {
84 return parser->http_major;
87 uint8_t llhttp_get_http_minor(llhttp_t* parser) {
88 return parser->http_minor;
91 uint8_t llhttp_get_method(llhttp_t* parser) {
92 return parser->method;
95 int llhttp_get_status_code(llhttp_t* parser) {
96 return parser->status_code;
99 uint8_t llhttp_get_upgrade(llhttp_t* parser) {
100 return parser->upgrade;
103 #endif // defined(__wasm__)
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;
112 llhttp__internal_init(parser);
115 parser->settings = (void*) settings;
117 parser->lenient_flags = lenient_flags;
121 llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
122 return llhttp__internal_execute(parser, data, data + len);
126 void llhttp_settings_init(llhttp_settings_t* settings) {
127 memset(settings, 0, sizeof(*settings));
131 llhttp_errno_t llhttp_finish(llhttp_t* parser) {
134 /* We're in an error state. Don't bother doing anything. */
135 if (parser->error != 0) {
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;
145 case HTTP_FINISH_SAFE:
147 case HTTP_FINISH_UNSAFE:
148 parser->reason = "Invalid EOF state";
149 return HPE_INVALID_EOF_STATE;
156 void llhttp_pause(llhttp_t* parser) {
157 if (parser->error != HPE_OK) {
161 parser->error = HPE_PAUSED;
162 parser->reason = "Paused";
166 void llhttp_resume(llhttp_t* parser) {
167 if (parser->error != HPE_PAUSED) {
175 void llhttp_resume_after_upgrade(llhttp_t* parser) {
176 if (parser->error != HPE_PAUSED_UPGRADE) {
184 llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
185 return parser->error;
189 const char* llhttp_get_error_reason(const llhttp_t* parser) {
190 return parser->reason;
194 void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
195 parser->reason = reason;
199 const char* llhttp_get_error_pos(const llhttp_t* parser) {
200 return parser->error_pos;
204 const char* llhttp_errno_name(llhttp_errno_t err) {
205 #define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME;
207 HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
210 #undef HTTP_ERRNO_GEN
214 const char* llhttp_method_name(llhttp_method_t method) {
215 #define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
217 HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN)
220 #undef HTTP_METHOD_GEN
224 void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
226 parser->lenient_flags |= LENIENT_HEADERS;
228 parser->lenient_flags &= ~LENIENT_HEADERS;
233 void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
235 parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
237 parser->lenient_flags &= ~LENIENT_CHUNKED_LENGTH;
242 void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
244 parser->lenient_flags |= LENIENT_KEEP_ALIVE;
246 parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
253 int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
255 CALLBACK_MAYBE(s, on_message_begin);
260 int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
262 SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);
267 int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
269 CALLBACK_MAYBE(s, on_url_complete);
274 int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
276 SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p);
281 int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
283 CALLBACK_MAYBE(s, on_status_complete);
288 int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
290 SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p);
295 int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
297 CALLBACK_MAYBE(s, on_header_field_complete);
302 int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
304 SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p);
309 int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
311 CALLBACK_MAYBE(s, on_header_value_complete);
316 int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
318 CALLBACK_MAYBE(s, on_headers_complete);
323 int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
325 CALLBACK_MAYBE(s, on_message_complete);
330 int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
332 SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p);
337 int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
339 CALLBACK_MAYBE(s, on_chunk_header);
344 int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
346 CALLBACK_MAYBE(s, on_chunk_complete);
354 void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
357 fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type,
360 fprintf(stderr, "p=%p type=%d flags=%02x next=%02x debug=%s\n", s,
361 s->type, s->flags, *p, msg);