diff options
Diffstat (limited to 'src/http_decoder_half.cpp')
| -rw-r--r-- | src/http_decoder_half.cpp | 111 |
1 files changed, 103 insertions, 8 deletions
diff --git a/src/http_decoder_half.cpp b/src/http_decoder_half.cpp index c4356fd..f766e66 100644 --- a/src/http_decoder_half.cpp +++ b/src/http_decoder_half.cpp @@ -4,6 +4,14 @@ #include <arpa/inet.h> #include "http_decoder_inc.h" #include "llhttp.h" +#include "uthash/utlist.h" + +struct http_decompress_buffer +{ + struct iovec iov; + char is_commit; + struct http_decompress_buffer *next, *prev; +}; struct http_decoder_half_data { @@ -17,9 +25,12 @@ struct http_decoder_half_data enum http_content_encoding content_encoding; struct http_content_decompress *decompress; +#if 0 char *ref_decompress_body; size_t decompress_body_len; - +#else + struct http_decompress_buffer *decompress_buffer_list; +#endif int joint_url_complete; int url_is_encoded; hstring joint_url; // http://<host>[:<port>]/<path>?<searchpart> @@ -69,6 +80,48 @@ static void printf_debug_info(const char *desc, const char *at, size_t length) #define printf_debug_info(desc, at, length) #endif +void http_half_decompress_buffer_free(struct http_decoder_half_data *data, hstring *decompress_body) +{ + struct http_decompress_buffer *el, *tmp; + DL_FOREACH_SAFE(data->decompress_buffer_list, el, tmp) + { + if (el->iov.iov_base == decompress_body->iov_base + && el->iov.iov_len == decompress_body->iov_len) + { + DL_DELETE(data->decompress_buffer_list, el); + if (el->iov.iov_base) + { + FREE(el->iov.iov_base); + } + FREE(el); + break; + } + } +} + +void http_half_get_lastest_decompress_buffer(struct http_decoder_half_data *data, hstring *decompress_body) +{ + if (data->content_encoding == HTTP_CONTENT_ENCODING_NONE) + { + return; + } + if (data->decompress_buffer_list == NULL) + { + decompress_body->iov_base = NULL; + decompress_body->iov_len = 0; + return; + } + if (data->decompress_buffer_list->prev->is_commit == 1) + { + decompress_body->iov_base = NULL; + decompress_body->iov_len = 0; + return; + } + decompress_body->iov_base = data->decompress_buffer_list->prev->iov.iov_base; + decompress_body->iov_len = data->decompress_buffer_list->prev->iov.iov_len; + data->decompress_buffer_list->prev->is_commit = 1; +} + static void http_decoder_half_data_decompress(struct http_decoder_half_data *data) { assert(data); @@ -91,14 +144,26 @@ static void http_decoder_half_data_decompress(struct http_decoder_half_data *dat } assert(data->decompress); + char *local_outdata = NULL; + size_t local_outdata_len = 0; if (http_content_decompress_write(data->decompress, (char *)raw_body.iov_base, raw_body.iov_len, - &data->ref_decompress_body, - &data->decompress_body_len) == -1) + &local_outdata, + &local_outdata_len) == -1) { // log error http_content_decompress_destroy(data->decompress); data->decompress = NULL; + return; + } + + if(local_outdata!= NULL && local_outdata_len > 0) + { + struct http_decompress_buffer *decompress_buffer = CALLOC(struct http_decompress_buffer, 1); + assert(decompress_buffer); + decompress_buffer->iov.iov_base = local_outdata; + decompress_buffer->iov.iov_len = local_outdata_len; + DL_APPEND(data->decompress_buffer_list, decompress_buffer); } } @@ -618,7 +683,7 @@ void http_decoder_half_reinit(struct http_decoder_half *half, if (half->ref_data != NULL) { http_decoder_table_reinit(half->ref_data->table); - } + } half->http_ev_ctx->ref_mempool = mempool; half->http_ev_ctx->ref_session = sess; half->http_ev_ctx->ref_queue = queue; @@ -790,12 +855,31 @@ http_decoder_half_data_new(nmx_pool_t *mempool) data->status_code = -1; data->content_encoding = HTTP_CONTENT_ENCODING_NONE; - data->ref_decompress_body = NULL; - data->decompress_body_len = 0; - + // data->ref_decompress_body = NULL; + // data->decompress_body_len = 0; + data->decompress_buffer_list = NULL; return data; } +static void http_decoder_half_decompress_buf_free(struct http_decoder_half_data *ref_data) +{ + if (ref_data == NULL) + { + return; + } + struct http_decompress_buffer *el, *tmp; + DL_FOREACH_SAFE(ref_data->decompress_buffer_list, el, tmp) + { + DL_DELETE(ref_data->decompress_buffer_list, el); + if (el->iov.iov_base != NULL) + { + FREE(el->iov.iov_base); + } + FREE(el); + } + ref_data->decompress_buffer_list = NULL; +} + void http_decoder_half_data_free(nmx_pool_t *mempool, struct http_decoder_half_data *data) { if (NULL == data) @@ -821,6 +905,7 @@ void http_decoder_half_data_free(nmx_pool_t *mempool, struct http_decoder_half_d data->joint_url.iov_base = NULL; data->joint_url_complete = 0; } + http_decoder_half_decompress_buf_free(data); MEMPOOL_FREE(mempool, data); } @@ -889,7 +974,7 @@ int http_decoder_half_data_get_raw_body(const struct http_decoder_half_data *dat } return http_decoder_table_get_body(data->table, body); } - +#if 0 int http_decoder_half_data_get_decompress_body(const struct http_decoder_half_data *data, hstring *body) { if (HTTP_CONTENT_ENCODING_NONE == data->content_encoding) @@ -901,6 +986,7 @@ int http_decoder_half_data_get_decompress_body(const struct http_decoder_half_da body->iov_len = data->decompress_body_len; return 0; } +#endif void http_decoder_half_data_dump(struct http_decoder_half *half) { @@ -1121,4 +1207,13 @@ void http_half_get_max_transaction_seq(struct http_decoder_exdata *exdata, long assert(exdata && max_req_seq && max_res_seq); *max_req_seq = exdata->decoder->c2s_half->transaction_seq; *max_res_seq = exdata->decoder->s2c_half->transaction_seq; +} + +enum http_content_encoding http_half_data_get_content_encoding(struct http_decoder_half_data *hf_data) +{ + if(NULL == hf_data) + { + return HTTP_CONTENT_ENCODING_NONE; + } + return hf_data->content_encoding; }
\ No newline at end of file |
