llhttp_api.c 13 KB

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