diff options
| author | liuwentan <[email protected]> | 2024-01-23 10:05:55 +0800 |
|---|---|---|
| committer | liuwentan <[email protected]> | 2024-01-23 10:05:55 +0800 |
| commit | ae450151a47f4fc9ab34263b55a12d6133642037 (patch) | |
| tree | 07b0f6666c7edc74242806b8e6f8cd50104dffec | |
| parent | 31b8a758b4416f547f1e693dcf1a341249b086b8 (diff) | |
[HTTP_DECODER]bugfix for gzip decompress
| -rw-r--r-- | src/http_decoder/http_content_decompress.c | 65 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_half.c | 148 | ||||
| -rw-r--r-- | test/http_decoder/http_decoder_gtest.cpp | 24 |
3 files changed, 88 insertions, 149 deletions
diff --git a/src/http_decoder/http_content_decompress.c b/src/http_decoder/http_content_decompress.c index f57d4cf..b887487 100644 --- a/src/http_decoder/http_content_decompress.c +++ b/src/http_decoder/http_content_decompress.c @@ -148,15 +148,14 @@ http_content_decompress_write_zlib(struct http_content_decompress *decompress, z_stream *z_stream_ptr = decompress->z_stream_ptr; z_stream_ptr->avail_in = (unsigned int)indata_len; z_stream_ptr->next_in = (unsigned char *)indata; + z_stream_ptr->avail_out = (unsigned int)decompress->buffer_size; + z_stream_ptr->next_out = (unsigned char *)decompress->buffer; *outdata = NULL; *outdata_len = 0; int ret = 0; do { - z_stream_ptr->avail_out = (unsigned int)decompress->buffer_size; - z_stream_ptr->next_out = (unsigned char *)decompress->buffer; - ret = inflate(z_stream_ptr, Z_NO_FLUSH); if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { @@ -166,23 +165,24 @@ http_content_decompress_write_zlib(struct http_content_decompress *decompress, size_t have = decompress->buffer_size - z_stream_ptr->avail_out; if (have > 0) { - if (NULL == *outdata) { - // http_decoder_log(DEBUG, "%s alloc outbuffer %zu bytes", - // http_content_encoding_int2str(decompress->encoding), - // have); - *outdata = safe_dup(decompress->buffer, have); - *outdata_len = have; - } else { - // http_decoder_log(DEBUG, "%s realloc outbuffer %zu bytes", - // http_content_encoding_int2str(decompress->encoding), - // *outdata_len + have + 1); - *outdata = REALLOC(char, *outdata, *outdata_len + have + 1); - memcpy(*outdata + *outdata_len, decompress->buffer, have); + if (0 == z_stream_ptr->avail_out) { + decompress->buffer_size += have; + decompress->buffer = REALLOC(char, decompress->buffer, + decompress->buffer_size); + *outdata = decompress->buffer; *outdata_len = *outdata_len + have; - memset(*outdata + *outdata_len, 0, 1); + http_decoder_log(DEBUG, "%s realloc outbuffer %zu bytes", + http_content_encoding_int2str(decompress->encoding), + decompress->buffer_size); + z_stream_ptr->avail_out = have; + z_stream_ptr->next_out = (unsigned char *)decompress->buffer + + (decompress->buffer_size - have); + } else { + *outdata = decompress->buffer; + *outdata_len = have; } } - } while (0 == z_stream_ptr->avail_out); + } while (z_stream_ptr->avail_in != 0); return 0; } @@ -192,37 +192,32 @@ http_content_decompress_write_br(struct http_content_decompress *decompress, const char *indata, size_t indata_len, char **outdata, size_t *outdata_len) { - size_t available_out; size_t available_in = indata_len; const unsigned char *next_in = (const unsigned char *)indata; - unsigned char *next_out; + size_t available_out = decompress->buffer_size; + unsigned char *next_out = (unsigned char *)decompress->buffer; *outdata = NULL; *outdata_len = 0; int ret; for (;;) { - available_out = decompress->buffer_size; - next_out = (unsigned char *)decompress->buffer; - ret = BrotliDecoderDecompressStream(decompress->br_state, &available_in, &next_in, &available_out, &next_out, 0); size_t have = decompress->buffer_size - available_out; if (have > 0) { - if (NULL == *outdata) { - // http_decoder_log(DEBUG, "%s alloc outbuffer %zu bytes", - // http_content_encoding_int2str(decompress->encoding), - // have); - *outdata = safe_dup(decompress->buffer, have); - *outdata_len = have; - } else { - // http_decoder_log(DEBUG, "%s realloc outbuffer %zu bytes", - // http_content_encoding_int2str(decompress->encoding), - // *outdata_len + have + 1); - *outdata = REALLOC(char, *outdata, *outdata_len + have + 1); - memcpy(*outdata + *outdata_len, decompress->buffer, have); + if (0 == available_out) { + decompress->buffer_size += have; + decompress->buffer = REALLOC(char, decompress->buffer, + decompress->buffer_size); + *outdata = decompress->buffer; *outdata_len = *outdata_len + have; - memset(*outdata + *outdata_len, 0, 1); + available_out = have; + next_out = (unsigned char *)decompress->buffer + + (decompress->buffer_size - have); + } else { + *outdata = decompress->buffer; + *outdata_len = have; } } diff --git a/src/http_decoder/http_decoder_half.c b/src/http_decoder/http_decoder_half.c index 40e5d01..d97cd25 100644 --- a/src/http_decoder/http_decoder_half.c +++ b/src/http_decoder/http_decoder_half.c @@ -26,7 +26,8 @@ struct http_decoder_half_data { int status_code; enum http_content_encoding content_encoding; - char *decompress_body; + struct http_content_decompress *decompress; + char *ref_decompress_body; size_t decompress_body_len; }; @@ -44,7 +45,7 @@ struct http_decoder_half { long long trans_counter; }; -//#define HTTP_DECODER_DEBUG +// #define HTTP_DECODER_DEBUG #ifdef HTTP_DECODER_DEBUG static void printf_debug_info(const char *desc, const char *at, size_t length) { @@ -68,9 +69,6 @@ http_decoder_half_data_decompress(struct http_decoder_half_data *data) { assert(data); - FREE(data->decompress_body); - data->decompress_body_len = 0; - if (data->content_encoding == HTTP_CONTENT_ENCODING_NONE) { return; } @@ -81,15 +79,19 @@ http_decoder_half_data_decompress(struct http_decoder_half_data *data) return; } - struct http_content_decompress *decompress = - http_content_decompress_create(data->content_encoding); - assert(decompress); - if (http_content_decompress_write(decompress, raw_body.str, raw_body.str_len, - &data->decompress_body, + if (NULL == data->decompress) { + data->decompress = http_content_decompress_create(data->content_encoding); + } + + assert(data->decompress); + if (http_content_decompress_write(data->decompress, raw_body.str, + raw_body.str_len, + &data->ref_decompress_body, &data->decompress_body_len) == -1) { // log error + http_content_decompress_destroy(data->decompress); + data->decompress = NULL; } - http_content_decompress_destroy(decompress); } /* Possible return values 0, -1, `HPE_PAUSED` */ @@ -125,62 +127,20 @@ static int on_message_complete(llhttp_t *http) container_of(http, struct http_decoder_half, parser); assert(half); - // if enable cache_body, trigger body_data/body_end event - // if disable cache_body, trigger body_end event - if (half->is_cache_body - || (half->ref_data->content_encoding != HTTP_CONTENT_ENCODING_NONE)) { - if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_BODY) - == STRING_STATE_CACHE) { - http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_BODY); - http_decoder_half_data_decompress(half->ref_data); - } - - if (half->parser.type == HTTP_REQUEST) { - if (half->event == HTTP_EVENT_REQ_BODY_BEGIN) { - half->event = HTTP_EVENT_REQ_BODY_DATA; - if (half->http_ev_cb != NULL) { - half->http_ev_cb(half->event, &half->ref_data, - half->http_ev_ctx); - } - - half->event = HTTP_EVENT_REQ_BODY_END; - if (half->http_ev_cb != NULL) { - half->http_ev_cb(half->event, &half->ref_data, - half->http_ev_ctx); - } - } - } else { - if (half->event == HTTP_EVENT_RES_BODY_BEGIN) { - half->event = HTTP_EVENT_RES_BODY_DATA; - if (half->http_ev_cb != NULL) { - half->http_ev_cb(half->event, &half->ref_data, - half->http_ev_ctx); - } - - half->event = HTTP_EVENT_RES_BODY_END; - if (half->http_ev_cb != NULL) { - half->http_ev_cb(half->event, &half->ref_data, - half->http_ev_ctx); - } + if (half->parser.type == HTTP_REQUEST) { + if (half->event == HTTP_EVENT_REQ_BODY_DATA) { + half->event = HTTP_EVENT_REQ_BODY_END; + if (half->http_ev_cb != NULL) { + half->http_ev_cb(half->event, &half->ref_data, + half->http_ev_ctx); } } } else { - // no cache body - if (half->parser.type == HTTP_REQUEST) { - if (half->event == HTTP_EVENT_REQ_BODY_DATA) { - half->event = HTTP_EVENT_REQ_BODY_END; - if (half->http_ev_cb != NULL) { - half->http_ev_cb(half->event, &half->ref_data, - half->http_ev_ctx); - } - } - } else { - if (half->event == HTTP_EVENT_RES_BODY_DATA) { - half->event = HTTP_EVENT_RES_BODY_END; - if (half->http_ev_cb != NULL) { - half->http_ev_cb(half->event, &half->ref_data, - half->http_ev_ctx); - } + if (half->event == HTTP_EVENT_RES_BODY_DATA) { + half->event = HTTP_EVENT_RES_BODY_END; + if (half->http_ev_cb != NULL) { + half->http_ev_cb(half->event, &half->ref_data, + half->http_ev_ctx); } } } @@ -510,37 +470,30 @@ static int on_body(llhttp_t *http, const char *at, size_t length) } } - // if enable cache_body, trigger body_data event on_message_complete - // if disable cache_body, trigger body_data event on_body - if (half->is_cache_body || - (half->ref_data->content_encoding != HTTP_CONTENT_ENCODING_NONE)) { - http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_BODY, - at, length); - http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_BODY); - } else { - if (half->ref_data != NULL) { - if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_BODY) - == STRING_STATE_COMMIT) { - http_decoder_table_reset(half->ref_data->table, HTTP_ITEM_BODY); - } - - http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_BODY, - at, length); - http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_BODY); + if (half->ref_data != NULL) { + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_BODY) == + STRING_STATE_COMMIT) { + http_decoder_table_reset(half->ref_data->table, HTTP_ITEM_BODY); } - if (half->parser.type == HTTP_REQUEST) { - half->event = HTTP_EVENT_REQ_BODY_DATA; - if (half->http_ev_cb) { - half->http_ev_cb(half->event, &half->ref_data, - half->http_ev_ctx); - } - } else { - half->event = HTTP_EVENT_RES_BODY_DATA; - if (half->http_ev_cb) { - half->http_ev_cb(half->event, &half->ref_data, - half->http_ev_ctx); - } + http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_BODY, at, + length); + http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_BODY); + } + + if (half->ref_data->content_encoding != HTTP_CONTENT_ENCODING_NONE) { + http_decoder_half_data_decompress(half->ref_data); + } + + if (half->parser.type == HTTP_REQUEST) { + half->event = HTTP_EVENT_REQ_BODY_DATA; + if (half->http_ev_cb) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); + } + } else { + half->event = HTTP_EVENT_RES_BODY_DATA; + if (half->http_ev_cb) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } @@ -733,7 +686,7 @@ struct http_decoder_half_data *http_decoder_half_data_new() data->status_code = -1; data->content_encoding = HTTP_CONTENT_ENCODING_NONE; - data->decompress_body = NULL; + data->ref_decompress_body = NULL; data->decompress_body_len = 0; return data; @@ -750,8 +703,9 @@ void http_decoder_half_data_free(struct http_decoder_half_data *data) data->table = NULL; } - if (data->decompress_body != NULL) { - FREE(data->decompress_body); + if (data->decompress != NULL) { + http_content_decompress_destroy(data->decompress); + data->decompress = NULL; } FREE(data); @@ -834,7 +788,7 @@ int http_decoder_half_data_get_decompress_body(struct http_decoder_half_data *da } - body->str = data->decompress_body; + body->str = data->ref_decompress_body; body->str_len = data->decompress_body_len; return 0; } diff --git a/test/http_decoder/http_decoder_gtest.cpp b/test/http_decoder/http_decoder_gtest.cpp index 725f42d..852844e 100644 --- a/test/http_decoder/http_decoder_gtest.cpp +++ b/test/http_decoder/http_decoder_gtest.cpp @@ -40,7 +40,7 @@ int g_res_exdata_idx = 0; int g_topic_id = 0; -#if 0 +#if 1 void output_http_req_line(struct http_request_line *req_line) { char tmp_str[MAX_KEY_STR_LEN] = {0}; @@ -74,28 +74,16 @@ void output_http_header(struct http_header *header) #endif void -output_http_header(struct http_header *header, int res) -{ - char key[MAX_KEY_STR_LEN] = {0}; - - snprintf(key, header->key.str_len + 1, "%s", header->key.str); - if (0 == res) { - printf("<ouput_http_req_header> header:%s\n", key); - } else { - printf("<ouput_http_res_header> header:%s\n", key); - } - -} - -void output_http_body(struct hstring *body, int decompress_flag) { int counter = 0; if (1 == decompress_flag) { - printf("\n\n----------------decompress body---------------\n"); + printf("\n\n----------------decompress body len:%zu---------------\n", + body->str_len); } else { - printf("\n\n----------------raw body---------------\n"); + printf("\n\n----------------raw body len:%zu---------------\n", + body->str_len); } for (size_t i = 0; i < body->str_len; i++) { @@ -207,6 +195,7 @@ next: case HTTP_MESSAGE_REQ_HEADER: while (http_message_request_header_next(msg, &header) > 0) { http_header_to_json(json, &header); + // output_http_header(&header); } g_header_count = 1; break; @@ -224,6 +213,7 @@ next: case HTTP_MESSAGE_RES_HEADER: while (http_message_response_header_next(msg, &header) > 0) { http_header_to_json(json, &header); + // output_http_header(&header); } g_header_count = 1; break; |
