summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuwentan <[email protected]>2023-12-28 18:31:44 +0800
committerliuwentan <[email protected]>2023-12-28 18:31:44 +0800
commita9afd24fafcf867b6fa272e6651c41dac5407567 (patch)
tree5d83d3480b55cf2358f99005e452c7a9259102a0
parent9354f4ca90570739aab9a0d61a91cb8822565440 (diff)
[PATCH]bugfix for compressed body
-rw-r--r--src/http_decoder/http_decoder.c129
-rw-r--r--src/http_decoder/http_decoder.h3
-rw-r--r--src/http_decoder/http_decoder_half.c40
-rw-r--r--src/http_decoder/http_decoder_table.c10
-rw-r--r--src/stellar_on_sapp/defer_loader.inf14
-rw-r--r--test/http_decoder/http_decoder_gtest.cpp52
6 files changed, 144 insertions, 104 deletions
diff --git a/src/http_decoder/http_decoder.c b/src/http_decoder/http_decoder.c
index 584d53e..c2d1c55 100644
--- a/src/http_decoder/http_decoder.c
+++ b/src/http_decoder/http_decoder.c
@@ -23,9 +23,9 @@
#define HTTP_IDENTIFY_LEN 16
#define HTTP_DECODER_RESULT_QUEUE_SIZE 16
-#define HTTP_DECODER_IS_CACHE_LINE 1
-#define HTTP_DECODER_IS_CACHE_BODY 1
-#define HTTP_DECODER_IS_CACHE_HEADER 1
+#define HD_IS_CACHE_LINE 1
+#define HD_IS_CACHE_BODY 1
+#define HD_IS_CACHE_HEADER 1
const char *http_decoder_topic = "HTTP_DECODER_MESSAGE";
@@ -330,78 +330,89 @@ static int http_protocol_identify(const char *data, size_t data_len)
int http_decoder_entry(struct session *sess, int events, const struct packet *pkt, void *cb_arg)
{
- int ret = 0;
- size_t payload_len = 0;
struct http_decoder_context *ctx = (struct http_decoder_context *)cb_arg;
- struct http_decoder_result_queue *queue = NULL;
+ size_t payload_len = 0;
+ uint64_t inner_flag = 0;
+
+ int ret = session_is_inner_most(sess, &inner_flag);
+ if (0 == ret) {
+ return 0;
+ }
+
+ struct http_decoder_result_queue *queue = session_get_ex_data(sess, ctx->ex_data_idx);;
+
+ const char *tmp_payload = session_get0_current_payload(sess, &payload_len);
+
+ if (events & SESS_EV_CLOSING) {
+ if (queue != NULL) {
+ http_decoder_result_queue_free(queue);
+ session_set_ex_data(sess, ctx->ex_data_idx, NULL);
+ }
- if (events & SESS_EV_TCP) {
- const char *payload = session_get0_current_payload(sess, &payload_len);
- if (NULL == payload || 0 == payload_len) {
- return 0;
+ return 0;
+ }
+
+ const char *payload = session_get0_current_payload(sess, &payload_len);
+ if (events & SESS_EV_OPENING) {
+ if (queue != NULL) {
+ fprintf(stderr, "http_decoder_result_queue should be null for new session\n");
+ return -1;
}
- queue = session_get_ex_data(sess, ctx->ex_data_idx);
- if (NULL == queue) {
- size_t http_identify_len = payload_len > HTTP_IDENTIFY_LEN
- ? HTTP_IDENTIFY_LEN
- : payload_len;
+ //If not http, ignore this session
+ if (payload_len > 0) {
+ size_t http_identify_len = payload_len > HTTP_IDENTIFY_LEN ? HTTP_IDENTIFY_LEN : payload_len;
ret = http_protocol_identify(payload, http_identify_len);
if (ret < 0) {
// ignore this session's event
- struct session_event *s_event =
- session_get_intrinsic_event(sess, ctx->plugin_id);
- session_event_assign(s_event, ctx->st, sess, 0,
- http_decoder_entry, ctx);
+ struct session_event *s_event = session_get_intrinsic_event(sess, ctx->plugin_id);
+ session_event_assign(s_event, ctx->st, sess, 0, http_decoder_entry, ctx);
return 0;
}
-
- queue = http_decoder_result_queue_new(HTTP_DECODER_RESULT_QUEUE_SIZE);
- queue->ref_session = sess;
- session_set_ex_data(sess, ctx->ex_data_idx, queue);
}
- int dir = packet_get_direction(pkt);
- if (dir < 0) {
- return -1;
- }
+ queue = http_decoder_result_queue_new(HTTP_DECODER_RESULT_QUEUE_SIZE);
+ queue->ref_session = sess;
+ session_set_ex_data(sess, ctx->ex_data_idx, queue);
+ }
- // printf("\n-------------------------------------------\n");
- // for (size_t i = 0; i < payload_len; i++) {
- // printf(" %x", payload[i]);
- // }
- // printf("\n-------------------------------------------\n");
+ if (0 == payload_len) {
+ return 0;
+ }
- if (NULL == ctx->decoder) {
- ctx->decoder = http_decoder_new(http_event_handler, HTTP_DECODER_IS_CACHE_LINE,
- HTTP_DECODER_IS_CACHE_HEADER, HTTP_DECODER_IS_CACHE_BODY);
- }
+ int dir = packet_get_direction(pkt);
+ if (dir < 0) {
+ return -1;
+ }
- struct http_decoder_half *cur_half = NULL;
- if (dir == PACKET_DIRECTION_C2S) {
- cur_half = ctx->decoder->c2s_half;
- } else {
- cur_half = ctx->decoder->s2c_half;
- }
+ // printf("\n-------------------------------------------\n");
+ // for (size_t i = 0; i < payload_len; i++) {
+ // printf(" %x", payload[i]);
+ // }
+ // printf("\n-------------------------------------------\n");
- ctx->http_ev_ctx->topic_id = ctx->topic_id;
- ctx->http_ev_ctx->ref_queue = queue;
- ctx->http_ev_ctx->ref_session = sess;
+ if (NULL == ctx->decoder) {
+ ctx->decoder = http_decoder_new(http_event_handler, HD_IS_CACHE_LINE,
+ HD_IS_CACHE_HEADER, 0);
+ }
- ret = http_decoder_half_parse(cur_half, ctx->http_ev_ctx, payload, payload_len);
- if (ret < 0) {
- if (dir == PACKET_DIRECTION_C2S) {
- http_decoder_result_queue_pop(queue, queue->req_index);
- } else {
- http_decoder_result_queue_pop(queue, queue->res_index);
- }
- }
+ struct http_decoder_half *cur_half = NULL;
+ if (dir == PACKET_DIRECTION_C2S) {
+ cur_half = ctx->decoder->c2s_half;
+ } else {
+ cur_half = ctx->decoder->s2c_half;
}
- if (events & SESS_EV_CLOSING) {
- if (queue != NULL) {
- http_decoder_result_queue_free(queue);
- session_set_ex_data(sess, ctx->ex_data_idx, NULL);
+ ctx->http_ev_ctx->topic_id = ctx->topic_id;
+ ctx->http_ev_ctx->ref_queue = queue;
+ ctx->http_ev_ctx->ref_session = sess;
+
+ ret = http_decoder_half_parse(cur_half, ctx->http_ev_ctx, payload, payload_len);
+ if (ret < 0) {
+ if (dir == PACKET_DIRECTION_C2S) {
+ http_decoder_result_queue_pop(queue, queue->req_index);
+ } else {
+ http_decoder_result_queue_pop(queue, queue->res_index);
}
}
@@ -468,6 +479,10 @@ void http_decoder_exit(void *decoder_ctx)
ctx->decoder = NULL;
}
+ if (ctx->topic_id >= 0) {
+ session_mq_destroy_topic(ctx->st, ctx->topic_id);
+ }
+
FREE(decoder_ctx);
}
diff --git a/src/http_decoder/http_decoder.h b/src/http_decoder/http_decoder.h
index 68202ba..430ea16 100644
--- a/src/http_decoder/http_decoder.h
+++ b/src/http_decoder/http_decoder.h
@@ -82,6 +82,9 @@ int http_message_get_request_raw_body(struct http_message *msg, struct hstring *
int http_message_get_response_raw_body(struct http_message *msg, struct hstring *body);
+/**
+ * @brief If the body hasn't been compressed, return raw body
+*/
int http_message_get_request_decompress_body(struct http_message *msg, struct hstring *body);
int http_message_get_response_decompress_body(struct http_message *msg, struct hstring *body);
diff --git a/src/http_decoder/http_decoder_half.c b/src/http_decoder/http_decoder_half.c
index 60c2f58..e2e25f1 100644
--- a/src/http_decoder/http_decoder_half.c
+++ b/src/http_decoder/http_decoder_half.c
@@ -111,16 +111,11 @@ static int on_message_complete(llhttp_t *http)
// if enable cache_body, trigger body_data/body_end event
// if disable cache_body, trigger body_end event
- if (half->is_cache_body) {
- if (half->ref_data) {
- 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->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) {
@@ -517,11 +512,10 @@ 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) {
- if (half->ref_data) {
- http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_BODY, at, length);
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_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) {
@@ -530,8 +524,6 @@ static int on_body(llhttp_t *http, const char *at, size_t length)
http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_BODY, at, length);
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) {
@@ -618,11 +610,6 @@ void http_decoder_half_free(struct http_decoder_half *half)
return;
}
- if (half->ref_data != NULL) {
- http_decoder_half_data_free(half->ref_data);
- half->ref_data = NULL;
- }
-
FREE(half);
}
@@ -799,13 +786,16 @@ int http_decoder_half_data_get_raw_body(struct http_decoder_half_data *data,
int http_decoder_half_data_get_decompress_body(struct http_decoder_half_data *data,
struct hstring *body)
{
- if (NULL == data || NULL == data->decompress_body ||
- 0 == data->decompress_body_len || NULL == body) {
+ if (NULL == data || NULL == body) {
return -1;
}
+ if (HTTP_CONTENT_ENCODING_NONE == data->content_encoding) {
+ return http_decoder_table_get_body(data->table, body);
+ }
+
+
body->str = data->decompress_body;
body->str_len = data->decompress_body_len;
-
return 0;
} \ No newline at end of file
diff --git a/src/http_decoder/http_decoder_table.c b/src/http_decoder/http_decoder_table.c
index eee993f..615c193 100644
--- a/src/http_decoder/http_decoder_table.c
+++ b/src/http_decoder/http_decoder_table.c
@@ -76,6 +76,16 @@ void http_decoder_table_free(struct http_decoder_table *table)
}
if (table->headers != NULL) {
+ for (size_t i = 0; i < table->header_size; i++) {
+ if (table->headers[i].key.cache.str != NULL) {
+ FREE(table->headers[i].key.cache.str);
+ }
+
+ if (table->headers[i].val.cache.str != NULL) {
+ FREE(table->headers[i].val.cache.str);
+ }
+ }
+
FREE(table->headers);
}
diff --git a/src/stellar_on_sapp/defer_loader.inf b/src/stellar_on_sapp/defer_loader.inf
index f823103..403473d 100644
--- a/src/stellar_on_sapp/defer_loader.inf
+++ b/src/stellar_on_sapp/defer_loader.inf
@@ -4,14 +4,14 @@ SO_PATH=./plug/stellar_on_sapp/stellar_on_sapp.so
INIT_FUNC=STELLAR_DEFER_LOADER_INIT
DESTROY_FUNC=STELLAR_DEFER_LOADER_EXIT
-[TCP_ALL]
-FUNC_FLAG=ALL
-FUNC_NAME=stellar_on_sapp_defer_entry
-
-#[TCP]
+#[TCP_ALL]
#FUNC_FLAG=ALL
#FUNC_NAME=stellar_on_sapp_defer_entry
-[UDP]
+[TCP]
FUNC_FLAG=ALL
-FUNC_NAME=stellar_on_sapp_defer_entry \ No newline at end of file
+FUNC_NAME=stellar_on_sapp_defer_entry
+
+#[UDP]
+#FUNC_FLAG=ALL
+#FUNC_NAME=stellar_on_sapp_defer_entry \ No newline at end of file
diff --git a/test/http_decoder/http_decoder_gtest.cpp b/test/http_decoder/http_decoder_gtest.cpp
index f8f33d2..17f45ab 100644
--- a/test/http_decoder/http_decoder_gtest.cpp
+++ b/test/http_decoder/http_decoder_gtest.cpp
@@ -37,7 +37,9 @@ static int g_result_count = 1;
int g_header_count = 1;
int g_req_exdata_idx = 0;
int g_res_exdata_idx = 0;
+int g_topic_id = 0;
+#if 0
void output_http_req_line(struct http_request_line *req_line)
{
char tmp_str[MAX_KEY_STR_LEN] = {0};
@@ -68,18 +70,28 @@ void output_http_header(struct http_header *header)
{
printf("<%s:%s>\n", header->key.str, header->val.str);
}
+#endif
-void output_http_req_body(struct hstring *body)
+void output_http_body(struct hstring *body, int decompress_flag)
{
+ int counter = 0;
-}
-
-void output_http_res_body(struct hstring *body)
-{
+ if (1 == decompress_flag) {
+ printf("\n\n----------------decompress body---------------\n");
+ } else {
+ printf("\n\n----------------raw body---------------\n");
+ }
+ for (size_t i = 0; i < body->str_len; i++) {
+ if (counter % 16 == 0) {
+ printf("\n");
+ }
+ printf("%02x ", (unsigned char)body->str[i]);
+ counter++;
+ }
+ printf("\n");
}
-
int http_field_to_json(cJSON *object, const char *key, char *val, size_t val_len)
{
if (NULL == object || NULL == key || NULL == val || 0 == val_len) {
@@ -141,24 +153,28 @@ static int http_decoder_test_entry(struct session *sess, int topic_id, const voi
enum http_message_type msg_type = http_message_type(msg);
if (msg_type == HTTP_MESSAGE_REQ_LINE ||
- msg_type == HTTP_MESSAGE_REQ_HEADER_END ||
- msg_type == HTTP_MESSAGE_REQ_BODY) {
+ msg_type == HTTP_MESSAGE_REQ_HEADER_END) {
exdata_idx = g_req_exdata_idx;
} else {
exdata_idx = g_res_exdata_idx;
}
-
cJSON *ctx = (cJSON *)session_get_ex_data(sess, exdata_idx);
+
+ if (msg_type == HTTP_MESSAGE_REQ_BODY ||
+ msg_type == HTTP_MESSAGE_RES_BODY) {
+ goto next;
+ }
+
if (NULL == ctx) {
ctx = cJSON_CreateObject();
cJSON_AddStringToObject(ctx, "Tuple4", session_get0_readable_addr(sess));
session_set_ex_data(sess, exdata_idx, ctx);
}
+next:
switch (msg_type) {
case HTTP_MESSAGE_REQ_LINE:
http_message_get_request_line(msg, &req_line);
- //output_http_req_line(&req_line);
req_line_to_json(ctx, &req_line);
break;
case HTTP_MESSAGE_REQ_HEADER_END:
@@ -169,7 +185,10 @@ static int http_decoder_test_entry(struct session *sess, int topic_id, const voi
break;
case HTTP_MESSAGE_REQ_BODY:
http_message_get_request_raw_body(msg, &body);
- output_http_req_body(&body);
+ //output_http_body(&body, 0);
+
+ http_message_get_request_decompress_body(msg, &body);
+ //output_http_body(&body, 1);
break;
case HTTP_MESSAGE_RES_LINE:
http_message_get_response_line(msg, &res_line);
@@ -183,7 +202,10 @@ static int http_decoder_test_entry(struct session *sess, int topic_id, const voi
break;
case HTTP_MESSAGE_RES_BODY:
http_message_get_response_raw_body(msg, &body);
- output_http_res_body(&body);
+ //output_http_body(&body, 0);
+
+ http_message_get_response_decompress_body(msg, &body);
+ //output_http_body(&body, 1);
break;
default:
break;
@@ -223,13 +245,13 @@ extern "C" void *http_decoder_test_init(struct stellar *st)
exit(-1);
}
- int topic_id = session_mq_get_topic_id(st, "HTTP_DECODER_MESSAGE");
- if (topic_id < 0) {
+ g_topic_id = session_mq_get_topic_id(st, "HTTP_DECODER_MESSAGE");
+ if (g_topic_id < 0) {
printf("http_decoder_test_init: can't get http_decoder topic id !!!\n");
exit(-1);
}
- session_mq_subscribe_topic(st, topic_id, http_decoder_test_entry, NULL);
+ session_mq_subscribe_topic(st, g_topic_id, http_decoder_test_entry, NULL);
printf("http_decoder_test_init OK!\n");
return NULL;