Skip to content

Commit 8c6e951

Browse files
committed
release: 5.1.0
1 parent a74a904 commit 8c6e951

3 files changed

Lines changed: 219 additions & 24 deletions

File tree

include/llhttp.h

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef INCLUDE_LLHTTP_H_
22
#define INCLUDE_LLHTTP_H_
33

4-
#define LLHTTP_VERSION_MAJOR 4
4+
#define LLHTTP_VERSION_MAJOR 5
55
#define LLHTTP_VERSION_MINOR 1
66
#define LLHTTP_VERSION_PATCH 0
77

@@ -99,7 +99,8 @@ typedef enum llhttp_flags llhttp_flags_t;
9999

100100
enum llhttp_lenient_flags {
101101
LENIENT_HEADERS = 0x1,
102-
LENIENT_CHUNKED_LENGTH = 0x2
102+
LENIENT_CHUNKED_LENGTH = 0x2,
103+
LENIENT_KEEP_ALIVE = 0x4
103104
};
104105
typedef enum llhttp_lenient_flags llhttp_lenient_flags_t;
105106

@@ -257,6 +258,12 @@ extern "C" {
257258
#endif
258259
#include <stddef.h>
259260

261+
#if defined(__wasm__)
262+
#define LLHTTP_EXPORT __attribute__((visibility("default")))
263+
#else
264+
#define LLHTTP_EXPORT
265+
#endif
266+
260267
typedef llhttp__internal_t llhttp_t;
261268
typedef struct llhttp_settings_s llhttp_settings_t;
262269

@@ -307,15 +314,46 @@ struct llhttp_settings_s {
307314
* the `parser` here. In practice, `settings` has to be either a static
308315
* variable or be allocated with `malloc`, `new`, etc.
309316
*/
317+
LLHTTP_EXPORT
310318
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
311319
const llhttp_settings_t* settings);
312320

321+
#if defined(__wasm__)
322+
323+
LLHTTP_EXPORT
324+
llhttp_t* llhttp_alloc(llhttp_type_t type);
325+
326+
LLHTTP_EXPORT
327+
void llhttp_free(llhttp_t* parser);
328+
329+
LLHTTP_EXPORT
330+
uint8_t llhttp_get_type(llhttp_t* parser);
331+
332+
LLHTTP_EXPORT
333+
uint8_t llhttp_get_http_major(llhttp_t* parser);
334+
335+
LLHTTP_EXPORT
336+
uint8_t llhttp_get_http_minor(llhttp_t* parser);
337+
338+
LLHTTP_EXPORT
339+
uint8_t llhttp_get_method(llhttp_t* parser);
340+
341+
LLHTTP_EXPORT
342+
int llhttp_get_status_code(llhttp_t* parser);
343+
344+
LLHTTP_EXPORT
345+
uint8_t llhttp_get_upgrade(llhttp_t* parser);
346+
347+
#endif // defined(__wasm__)
348+
313349
/* Reset an already initialized parser back to the start state, preserving the
314350
* existing parser type, callback settings, user data, and lenient flags.
315351
*/
352+
LLHTTP_EXPORT
316353
void llhttp_reset(llhttp_t* parser);
317354

318355
/* Initialize the settings object */
356+
LLHTTP_EXPORT
319357
void llhttp_settings_init(llhttp_settings_t* settings);
320358

321359
/* Parse full or partial request/response, invoking user callbacks along the
@@ -334,6 +372,7 @@ void llhttp_settings_init(llhttp_settings_t* settings);
334372
* to return the same error upon each successive call up until `llhttp_init()`
335373
* is called.
336374
*/
375+
LLHTTP_EXPORT
337376
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
338377

339378
/* This method should be called when the other side has no further bytes to
@@ -344,16 +383,19 @@ llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
344383
* connection. This method will invoke `on_message_complete()` callback if the
345384
* request was terminated safely. Otherwise a error code would be returned.
346385
*/
386+
LLHTTP_EXPORT
347387
llhttp_errno_t llhttp_finish(llhttp_t* parser);
348388

349389
/* Returns `1` if the incoming message is parsed until the last byte, and has
350390
* to be completed by calling `llhttp_finish()` on EOF
351391
*/
392+
LLHTTP_EXPORT
352393
int llhttp_message_needs_eof(const llhttp_t* parser);
353394

354395
/* Returns `1` if there might be any other messages following the last that was
355396
* successfully parsed.
356397
*/
398+
LLHTTP_EXPORT
357399
int llhttp_should_keep_alive(const llhttp_t* parser);
358400

359401
/* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set
@@ -362,50 +404,59 @@ int llhttp_should_keep_alive(const llhttp_t* parser);
362404
* Important: do not call this from user callbacks! User callbacks must return
363405
* `HPE_PAUSED` if pausing is required.
364406
*/
407+
LLHTTP_EXPORT
365408
void llhttp_pause(llhttp_t* parser);
366409

367410
/* Might be called to resume the execution after the pause in user's callback.
368411
* See `llhttp_execute()` above for details.
369412
*
370413
* Call this only if `llhttp_execute()` returns `HPE_PAUSED`.
371414
*/
415+
LLHTTP_EXPORT
372416
void llhttp_resume(llhttp_t* parser);
373417

374418
/* Might be called to resume the execution after the pause in user's callback.
375419
* See `llhttp_execute()` above for details.
376420
*
377421
* Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`
378422
*/
423+
LLHTTP_EXPORT
379424
void llhttp_resume_after_upgrade(llhttp_t* parser);
380425

381426
/* Returns the latest return error */
427+
LLHTTP_EXPORT
382428
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
383429

384430
/* Returns the verbal explanation of the latest returned error.
385431
*
386432
* Note: User callback should set error reason when returning the error. See
387433
* `llhttp_set_error_reason()` for details.
388434
*/
435+
LLHTTP_EXPORT
389436
const char* llhttp_get_error_reason(const llhttp_t* parser);
390437

391438
/* Assign verbal description to the returned error. Must be called in user
392439
* callbacks right before returning the errno.
393440
*
394441
* Note: `HPE_USER` error code might be useful in user callbacks.
395442
*/
443+
LLHTTP_EXPORT
396444
void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
397445

398446
/* Returns the pointer to the last parsed byte before the returned error. The
399447
* pointer is relative to the `data` argument of `llhttp_execute()`.
400448
*
401449
* Note: this method might be useful for counting the number of parsed bytes.
402450
*/
451+
LLHTTP_EXPORT
403452
const char* llhttp_get_error_pos(const llhttp_t* parser);
404453

405454
/* Returns textual name of error code */
455+
LLHTTP_EXPORT
406456
const char* llhttp_errno_name(llhttp_errno_t err);
407457

408458
/* Returns textual name of HTTP method */
459+
LLHTTP_EXPORT
409460
const char* llhttp_method_name(llhttp_method_t method);
410461

411462

@@ -418,6 +469,7 @@ const char* llhttp_method_name(llhttp_method_t method);
418469
*
419470
* **(USE AT YOUR OWN RISK)**
420471
*/
472+
LLHTTP_EXPORT
421473
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
422474

423475

@@ -431,8 +483,23 @@ void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
431483
*
432484
* **(USE AT YOUR OWN RISK)**
433485
*/
486+
LLHTTP_EXPORT
434487
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
435488

489+
490+
/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0
491+
* requests responses.
492+
*
493+
* Normally `llhttp` would error on (in strict mode) or discard (in loose mode)
494+
* the HTTP request/response after the request/response with `Connection: close`
495+
* and `Content-Length`. This is important to prevent cache poisoning attacks,
496+
* but might interact badly with outdated and insecure clients. With this flag
497+
* the extra request/response will be parsed normally.
498+
*
499+
* **(USE AT YOUR OWN RISK)**
500+
*/
501+
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled);
502+
436503
#ifdef __cplusplus
437504
} /* extern "C" */
438505
#endif

src/api.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,70 @@ void llhttp_init(llhttp_t* parser, llhttp_type_t type,
2424
}
2525

2626

27+
#if defined(__wasm__)
28+
29+
extern int wasm_on_message_begin(llhttp_t * p);
30+
extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
31+
extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
32+
extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
33+
extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
34+
extern int wasm_on_headers_complete(llhttp_t * p);
35+
extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
36+
extern int wasm_on_message_complete(llhttp_t * p);
37+
38+
const llhttp_settings_t wasm_settings = {
39+
wasm_on_message_begin,
40+
wasm_on_url,
41+
wasm_on_status,
42+
wasm_on_header_field,
43+
wasm_on_header_value,
44+
wasm_on_headers_complete,
45+
wasm_on_body,
46+
wasm_on_message_complete,
47+
NULL,
48+
NULL,
49+
};
50+
51+
52+
llhttp_t* llhttp_alloc(llhttp_type_t type) {
53+
llhttp_t* parser = malloc(sizeof(llhttp_t));
54+
llhttp_init(parser, type, &wasm_settings);
55+
return parser;
56+
}
57+
58+
void llhttp_free(llhttp_t* parser) {
59+
free(parser);
60+
}
61+
62+
/* Some getters required to get stuff from the parser */
63+
64+
uint8_t llhttp_get_type(llhttp_t* parser) {
65+
return parser->type;
66+
}
67+
68+
uint8_t llhttp_get_http_major(llhttp_t* parser) {
69+
return parser->http_major;
70+
}
71+
72+
uint8_t llhttp_get_http_minor(llhttp_t* parser) {
73+
return parser->http_minor;
74+
}
75+
76+
uint8_t llhttp_get_method(llhttp_t* parser) {
77+
return parser->method;
78+
}
79+
80+
int llhttp_get_status_code(llhttp_t* parser) {
81+
return parser->status_code;
82+
}
83+
84+
uint8_t llhttp_get_upgrade(llhttp_t* parser) {
85+
return parser->upgrade;
86+
}
87+
88+
#endif // defined(__wasm__)
89+
90+
2791
void llhttp_reset(llhttp_t* parser) {
2892
llhttp_type_t type = parser->type;
2993
const llhttp_settings_t* settings = parser->settings;
@@ -150,6 +214,7 @@ void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
150214
}
151215
}
152216

217+
153218
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
154219
if (enabled) {
155220
parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
@@ -159,6 +224,14 @@ void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
159224
}
160225

161226

227+
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
228+
if (enabled) {
229+
parser->lenient_flags |= LENIENT_KEEP_ALIVE;
230+
} else {
231+
parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
232+
}
233+
}
234+
162235
/* Callbacks */
163236

164237

0 commit comments

Comments
 (0)