summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuwentan <[email protected]>2024-01-23 10:05:55 +0800
committerliuwentan <[email protected]>2024-01-23 10:05:55 +0800
commitae450151a47f4fc9ab34263b55a12d6133642037 (patch)
tree07b0f6666c7edc74242806b8e6f8cd50104dffec
parent31b8a758b4416f547f1e693dcf1a341249b086b8 (diff)
[HTTP_DECODER]bugfix for gzip decompress
-rw-r--r--src/http_decoder/http_content_decompress.c65
-rw-r--r--src/http_decoder/http_decoder_half.c148
-rw-r--r--test/http_decoder/http_decoder_gtest.cpp24
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;