summaryrefslogtreecommitdiff
path: root/src/http_decoder_half.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/http_decoder_half.cpp')
-rw-r--r--src/http_decoder_half.cpp111
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