From 0e8ad4e003e422de59e79a023e2106cac76674b8 Mon Sep 17 00:00:00 2001 From: Cliff Frey Date: Thu, 27 May 2010 14:29:16 -0700 Subject: [PATCH] reduce size of http_parser object from 104 to 84 bytes by only tracking one field size This does have some slight functional changes in cases where MAX_FIELD_SIZE is hit, specficially if a URL is made up of many components, each of which is smaller than MAX_FIELD_SIZE, but the total together is greater than MAX_FIELD_SIZE, then we now might not call callbacks for any of the components (even the ones that are smaller than 80kb). With the old code, it was possible to get a callback for query_string and never get a callback for the URL (or at least the end of the URL that is past 80kb), if the callback for the URL would have been larger than 80kb. (to be honest, I'm surprised that the MAX_FIELD_SIZE is implemented in http_parser at all, instead of requiring that callers pay attention to it, as it feels like it should be the caller's responsibility) --- http_parser.c | 23 ++++++++++++++--------- http_parser.h | 7 +------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/http_parser.c b/http_parser.c index 6e1198b..495e025 100644 --- a/http_parser.c +++ b/http_parser.c @@ -46,15 +46,20 @@ do { \ #define MARK(FOR) \ do { \ parser->FOR##_mark = p; \ - parser->FOR##_size = 0; \ + parser->current_mark_size = 0; \ +} while (0) + +#define MARK_NOSIZECLEAR(FOR) \ +do { \ + parser->FOR##_mark = p; \ } while (0) #define CALLBACK_NOCLEAR(FOR) \ do { \ if (parser->FOR##_mark) { \ - parser->FOR##_size += p - parser->FOR##_mark; \ - if (parser->FOR##_size > MAX_FIELD_SIZE) return (p - data); \ + parser->current_mark_size += p - parser->FOR##_mark; \ + if (parser->current_mark_size > MAX_FIELD_SIZE) return (p - data); \ if (settings->on_##FOR) { \ if (0 != settings->on_##FOR(parser, \ parser->FOR##_mark, \ @@ -650,7 +655,7 @@ size_t http_parser_execute (http_parser *parser, if (ch == '/') { MARK(url); - MARK(path); + MARK_NOSIZECLEAR(path); state = s_req_path; break; } @@ -700,7 +705,7 @@ size_t http_parser_execute (http_parser *parser, state = s_req_port; break; case '/': - MARK(path); + MARK_NOSIZECLEAR(path); state = s_req_path; break; case ' ': @@ -722,7 +727,7 @@ size_t http_parser_execute (http_parser *parser, if (ch >= '0' && ch <= '9') break; switch (ch) { case '/': - MARK(path); + MARK_NOSIZECLEAR(path); state = s_req_path; break; case ' ': @@ -778,7 +783,7 @@ size_t http_parser_execute (http_parser *parser, case s_req_query_string_start: { if (USUAL(ch)) { - MARK(query_string); + MARK_NOSIZECLEAR(query_string); state = s_req_query_string; break; } @@ -847,7 +852,7 @@ size_t http_parser_execute (http_parser *parser, case s_req_fragment_start: { if (USUAL(ch)) { - MARK(fragment); + MARK_NOSIZECLEAR(fragment); state = s_req_fragment; break; } @@ -868,7 +873,7 @@ size_t http_parser_execute (http_parser *parser, state = s_header_field_start; break; case '?': - MARK(fragment); + MARK_NOSIZECLEAR(fragment); state = s_req_fragment; break; case '#': diff --git a/http_parser.h b/http_parser.h index 4f5a420..de6d66d 100644 --- a/http_parser.h +++ b/http_parser.h @@ -112,18 +112,13 @@ struct http_parser { ssize_t body_read; ssize_t content_length; + size_t current_mark_size; const char *header_field_mark; - size_t header_field_size; const char *header_value_mark; - size_t header_value_size; const char *query_string_mark; - size_t query_string_size; const char *path_mark; - size_t path_size; const char *url_mark; - size_t url_size; const char *fragment_mark; - size_t fragment_size; /** READ-ONLY **/ unsigned short status_code; /* responses only */