From 59bea2ad5c7e66f48874cf31d23b84f591e73225 Mon Sep 17 00:00:00 2001 From: Jianhui Zhao Date: Sun, 12 Nov 2017 17:55:39 +0800 Subject: [PATCH] Optimizing HTTP parsing process Signed-off-by: Jianhui Zhao --- src/uhttp.c | 39 +++++++++++++++++++++------------------ src/uhttp_internal.h | 1 + 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/uhttp.c b/src/uhttp.c index 5348c1b..b8d5832 100755 --- a/src/uhttp.c +++ b/src/uhttp.c @@ -76,9 +76,6 @@ static void connection_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents static int on_message_begin(http_parser *parser) { struct uh_connection *con = container_of(parser, struct uh_connection, parser); - - uh_buf_init(&con->read_buf, UH_BUFFER_SIZE); - uh_buf_init(&con->write_buf, UH_BUFFER_SIZE); memset(&con->req, 0, sizeof(struct uh_request)); @@ -89,10 +86,9 @@ static int on_url(http_parser *parser, const char *at, size_t len) { struct uh_connection *con = container_of(parser, struct uh_connection, parser); - if (!con->req.url.at) - con->req.url.at = at; - - con->req.url.len += len; + con->req.url.at = at; + con->req.url.len = len; + return 0; } @@ -101,10 +97,8 @@ static int on_header_field(http_parser *parser, const char *at, size_t len) struct uh_connection *con = container_of(parser, struct uh_connection, parser); struct uh_header *header = con->req.header; - if (!header[con->req.header_num].field.at) { - header[con->req.header_num].field.at = at; - } - header[con->req.header_num].field.len += len; + header[con->req.header_num].field.at = at; + header[con->req.header_num].field.len = len; return 0; } @@ -113,12 +107,10 @@ static int on_header_value(http_parser *parser, const char *at, size_t len) { struct uh_connection *con = container_of(parser, struct uh_connection, parser); struct uh_header *header = con->req.header; - - con->req.header_num += 1; - if (!header[con->req.header_num - 1].value.at) - header[con->req.header_num - 1].value.at = at; - header[con->req.header_num - 1].value.len += len; + header[con->req.header_num].value.at = at; + header[con->req.header_num].value.len = len; + con->req.header_num += 1; return 0; } @@ -221,13 +213,24 @@ handshake_done: uh_log_debug("read:[%.*s]\n", len, base); #endif + if (!(con->flags & UH_CON_PARSERING)) { + if (!memmem(buf->base, len, "\r\n\r\n", 4)) + return; + + con->flags |= UH_CON_PARSERING; + + base = buf->base; + len = buf->len; + } + + printf("len:%d\n", len); parsered = http_parser_execute(&con->parser, &parser_settings, base, len); if (unlikely(parsered != len)){ uh_log_err("http parser failed:%s", http_errno_description(HTTP_PARSER_ERRNO(&con->parser))); uh_send_error(con, 400, NULL); + } else { + ev_timer_mode(loop, &con->timer_watcher, UH_CONNECTION_TIMEOUT, 0); } - - ev_timer_mode(loop, &con->timer_watcher, UH_CONNECTION_TIMEOUT, 0); } static void connection_write_cb(struct ev_loop *loop, ev_io *w, int revents) diff --git a/src/uhttp_internal.h b/src/uhttp_internal.h index 1cf5c81..199e745 100755 --- a/src/uhttp_internal.h +++ b/src/uhttp_internal.h @@ -12,6 +12,7 @@ #define UH_CON_CLOSE (1 << 0) #define UH_CON_SSL_HANDSHAKE_DONE (1 << 1) /* SSL hanshake has completed */ +#define UH_CON_PARSERING (1 << 2) /* Whether executed http_parser_execute() */ #define likely(x) (__builtin_expect(!!(x), 1)) #define unlikely(x) (__builtin_expect(!!(x), 0))