diff options
| author | liuwentan <[email protected]> | 2023-12-28 18:31:44 +0800 |
|---|---|---|
| committer | liuwentan <[email protected]> | 2023-12-28 18:31:44 +0800 |
| commit | a9afd24fafcf867b6fa272e6651c41dac5407567 (patch) | |
| tree | 5d83d3480b55cf2358f99005e452c7a9259102a0 | |
| parent | 9354f4ca90570739aab9a0d61a91cb8822565440 (diff) | |
[PATCH]bugfix for compressed body
| -rw-r--r-- | src/http_decoder/http_decoder.c | 129 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder.h | 3 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_half.c | 40 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_table.c | 10 | ||||
| -rw-r--r-- | src/stellar_on_sapp/defer_loader.inf | 14 | ||||
| -rw-r--r-- | test/http_decoder/http_decoder_gtest.cpp | 52 |
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; |
