diff options
| author | liuwentan <[email protected]> | 2023-12-14 22:13:55 +0800 |
|---|---|---|
| committer | liuwentan <[email protected]> | 2023-12-14 22:13:55 +0800 |
| commit | f29d9e463fc71c7d553a85c519251155882cf2ed (patch) | |
| tree | 73bed7c18593613451d33b20845b64cac1a0d08b | |
| parent | a4254d7b60b1aee385c1531ab8c6f7f69b074b90 (diff) | |
[PATCH]fix pipeline error
| -rw-r--r-- | .gitlab-ci.yml | 5 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder.c | 221 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder.h | 8 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_half.c | 414 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_half.h | 50 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_string.c | 13 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_string.h | 2 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_table.c | 44 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_table.h | 12 | ||||
| -rw-r--r-- | src/stellar_on_sapp/start_loader.inf | 6 | ||||
| -rw-r--r-- | test/http_decoder/CMakeLists.txt | 16 | ||||
| -rw-r--r-- | test/http_decoder/http_decoder_gtest.cpp | 264 | ||||
| -rw-r--r-- | test/http_decoder/http_pcap/simple_http.pcap | bin | 1359 -> 0 bytes | |||
| -rw-r--r-- | test/http_decoder/test_env/spec.toml | 2 | ||||
| -rw-r--r-- | test/http_decoder/test_result_json/proto_identify_http.json | 10 |
15 files changed, 630 insertions, 437 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 74ecd3f..da235f7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,10 @@ variables: BUILD_IMAGE_CENTOS7: "git.mesalab.cn:7443/mesa_platform/build-env:centos7-for-sapp" BUILD_IMAGE_CENTOS8: "git.mesalab.cn:7443/mesa_platform/build-env:rocky8-for-sapp" INSTALL_DEPENDENCY_LIBRARY: sapp sapp-devel framework_env libMESA_prof_load-devel - libcjson-devel zlib-devel brotli-devel + libMESA_htable-devel libMESA_jump_layer + libMESA_handle_logger-devel libMESA_field_stat2-devel + libfieldstat3-devel libbreakpad_mini-devel libcjson-devel + zlib-devel brotli-devel SYMBOL_TARGET: stellar-c TEST_NAME: gtest_stellar-c INSTALL_PREFIX: "/opt/tsg/" diff --git a/src/http_decoder/http_decoder.c b/src/http_decoder/http_decoder.c index ce767fb..dd6850d 100644 --- a/src/http_decoder/http_decoder.c +++ b/src/http_decoder/http_decoder.c @@ -30,12 +30,12 @@ const char *http_decoder_topic = "HTTP_DECODER_MESSAGE"; struct http_decoder_result { - struct session *ref_session; struct http_decoder_half_data *req_data; struct http_decoder_half_data *res_data; }; struct http_decoder_result_queue { + struct session *ref_session; size_t req_index; size_t res_index; size_t del_index; @@ -56,13 +56,19 @@ struct http_decoder { struct http_decoder_half *s2c_half; }; +struct http_event_context { + int topic_id; + struct session *ref_session; + struct http_decoder_result_queue *ref_queue; +}; + struct http_decoder_context { int plugin_id; int topic_id; int ex_data_idx; struct stellar *st; struct http_decoder *decoder; - struct http_decoder_result_queue *ref_queue; + struct http_event_context *http_ev_ctx; }; struct http_decoder_result *http_decoder_result_new() @@ -156,32 +162,40 @@ static void http_decoder_result_queue_gc(struct http_decoder_result_queue *queue static void http_event_handler(enum http_event event, struct http_decoder_half_data **data, - void *cb_args) + void *http_ev_ctx) { - struct http_decoder_context *ctx = (struct http_decoder_context *)cb_args; + struct http_event_context *ctx = (struct http_event_context *)http_ev_ctx; assert(ctx); - printf("ctx->topic_id:%d\n", ctx->topic_id); - assert(ctx->ref_queue); struct http_decoder_result_queue *queue = ctx->ref_queue; + struct http_message *msg = NULL; switch (event) { - case HTTP_EVENT_INIT: - *data = http_decoder_half_data_new(); + case HTTP_EVENT_REQ_INIT: + queue->array[queue->req_index]->req_data = http_decoder_half_data_new(); + *data = queue->array[queue->req_index]->req_data; break; case HTTP_EVENT_REQ_LINE: - if (NULL == queue->array[queue->req_index]) { - http_decoder_result_queue_push(queue, queue->req_index); - } - queue->array[queue->req_index]->req_data = *data; + msg = CALLOC(struct http_message, 1); + msg->type = HTTP_MESSAGE_REQ_LINE; + msg->data = *data; + session_mq_publish_message(ctx->ref_session, ctx->topic_id, msg); break; case HTTP_EVENT_REQ_HDR: break; case HTTP_EVENT_REQ_HDR_END: + msg = CALLOC(struct http_message, 1); + msg->type = HTTP_MESSAGE_REQ_HEADER_END; + msg->data = *data; + session_mq_publish_message(ctx->ref_session, ctx->topic_id, msg); break; case HTTP_EVENT_REQ_BODY_BEGIN: break; case HTTP_EVENT_REQ_BODY_DATA: + msg = CALLOC(struct http_message, 1); + msg->type = HTTP_MESSAGE_REQ_BODY; + msg->data = *data; + session_mq_publish_message(ctx->ref_session, ctx->topic_id, msg); break; case HTTP_EVENT_REQ_BODY_END: break; @@ -189,16 +203,31 @@ static void http_event_handler(enum http_event event, http_decoder_result_queue_inc_req_index(queue); http_decoder_result_queue_gc(queue, queue->req_index); break; + case HTTP_EVENT_RES_INIT: + queue->array[queue->res_index]->res_data = http_decoder_half_data_new(); + *data = queue->array[queue->res_index]->res_data; + break; case HTTP_EVENT_RES_LINE: - queue->array[queue->res_index]->res_data = *data; + msg = CALLOC(struct http_message, 1); + msg->type = HTTP_MESSAGE_RES_LINE; + msg->data = *data; + session_mq_publish_message(ctx->ref_session, ctx->topic_id, msg); break; case HTTP_EVENT_RES_HDR: break; case HTTP_EVENT_RES_HDR_END: + msg = CALLOC(struct http_message, 1); + msg->type = HTTP_MESSAGE_RES_HEADER_END; + msg->data = *data; + session_mq_publish_message(ctx->ref_session, ctx->topic_id, msg); break; case HTTP_EVENT_RES_BODY_BEGIN: break; case HTTP_EVENT_RES_BODY_DATA: + msg = CALLOC(struct http_message, 1); + msg->type = HTTP_MESSAGE_RES_BODY; + msg->data = *data; + session_mq_publish_message(ctx->ref_session, ctx->topic_id, msg); break; case HTTP_EVENT_RES_BODY_END: break; @@ -210,28 +239,35 @@ static void http_event_handler(enum http_event event, } } -static struct http_decoder *http_decoder_new() +static struct http_decoder *http_decoder_new(http_event_cb *ev_cb, int is_cache_line, + int is_cache_header, int is_cache_body) { struct http_decoder *decoder = CALLOC(struct http_decoder, 1); assert(decoder); - decoder->c2s_half = http_decoder_half_new(); - decoder->s2c_half = http_decoder_half_new(); + decoder->c2s_half = http_decoder_half_new(ev_cb, is_cache_line, is_cache_header, is_cache_body); + decoder->s2c_half = http_decoder_half_new(ev_cb, is_cache_line, is_cache_header, is_cache_body); return decoder; } -void http_decoder_reinit(struct http_decoder *decoder, void *args) +void http_decoder_free(struct http_decoder *decoder) { - http_decoder_half_init(decoder->c2s_half, http_event_handler, args, - HTTP_DECODER_IS_CACHE_LINE, - HTTP_DECODER_IS_CACHE_BODY, - HTTP_DECODER_IS_CACHE_HEADER); - - http_decoder_half_init(decoder->s2c_half, http_event_handler, args, - HTTP_DECODER_IS_CACHE_LINE, - HTTP_DECODER_IS_CACHE_BODY, - HTTP_DECODER_IS_CACHE_HEADER); + if (NULL == decoder) { + return; + } + + if (decoder->c2s_half != NULL) { + http_decoder_half_free(decoder->c2s_half); + decoder->c2s_half = NULL; + } + + if (decoder->s2c_half != NULL) { + http_decoder_half_free(decoder->s2c_half); + decoder->s2c_half = NULL; + } + + FREE(decoder); } static struct http_decoder_result_queue *http_decoder_result_queue_new(size_t queue_size) @@ -247,6 +283,10 @@ static struct http_decoder_result_queue *http_decoder_result_queue_new(size_t qu queue->array = CALLOC(struct http_decoder_result *, queue->queue_size); assert(queue->array); + for (size_t i = 0; i < queue->queue_size; i++) { + queue->array[i] = CALLOC(struct http_decoder_result, 1); + } + return queue; } @@ -270,21 +310,6 @@ static void http_decoder_result_queue_free(struct http_decoder_result_queue *que FREE(queue); } -static struct http_decoder_context *http_decoder_context_new() -{ - struct http_decoder_context *ctx = CALLOC(struct http_decoder_context, 1); - assert(ctx); - - return ctx; -} - -static void http_decoder_context_free(struct http_decoder_context *ctx) -{ - if (NULL == ctx) { - return; - } -} - static int http_protocol_identify(const char *data, size_t data_len) { enum llhttp_type type = HTTP_BOTH; @@ -303,32 +328,33 @@ static int http_protocol_identify(const char *data, size_t data_len) return 0; } -int http_decoder_entry(struct session *s, int events, const struct packet *pkt, void *cb_arg) +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; - const char *payload = session_get0_current_payload(s, &payload_len); - size_t http_identify_len = payload_len > HTTP_IDENTIFY_LEN ? HTTP_IDENTIFY_LEN : payload_len; + const char *payload = session_get0_current_payload(sess, &payload_len); + if (NULL == payload || 0 == payload_len) { + return 0; + } - struct http_decoder_result_queue *queue = session_get_ex_data(s, ctx->ex_data_idx); + struct http_decoder_result_queue *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; ret = http_protocol_identify(payload, http_identify_len); - printf("http_protocol_identify ret:%d\n", ret); if (ret < 0) { //ignore this session's event - struct session_event *s_event = session_get_intrinsic_event(s, ctx->plugin_id); - session_event_assign(s_event, ctx->st, s, 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); - session_set_ex_data(s, ctx->ex_data_idx, queue); - } + queue->ref_session = sess; + session_set_ex_data(sess, ctx->ex_data_idx, queue); + } - ctx->ref_queue = queue; - int dir = packet_get_direction(pkt); if (dir < 0) { return -1; @@ -341,30 +367,30 @@ int http_decoder_entry(struct session *s, int events, const struct packet *pkt, // printf("\n-------------------------------------------\n"); if (NULL == ctx->decoder) { - ctx->decoder = http_decoder_new(); - http_decoder_reinit(ctx->decoder, ctx); + ctx->decoder = http_decoder_new(http_event_handler, HTTP_DECODER_IS_CACHE_LINE, + HTTP_DECODER_IS_CACHE_HEADER, HTTP_DECODER_IS_CACHE_BODY); } 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 (dir == PACKET_DIRECTION_C2S) { + cur_half = ctx->decoder->c2s_half; + } else { + cur_half = ctx->decoder->s2c_half; + } - ret = http_decoder_half_parse(cur_half, payload, payload_len); - if (ret < 0) { - if (dir == PACKET_DIRECTION_C2S) { + 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); } } - // struct http_message *msg = CALLOC(struct http_message, 1); - // msg->type = HTTP_MESSAGE_REQ_LINE; - // session_mq_publish_message(s, ctx->topic_id, msg); - return 0; } @@ -389,8 +415,9 @@ void http_message_free(void *msg, void *cb_arg) void *http_decoder_init(struct stellar *st) { - struct http_decoder_context *ctx = http_decoder_context_new(); + struct http_decoder_context *ctx = CALLOC(struct http_decoder_context, 1); + ctx->http_ev_ctx = CALLOC(struct http_event_context, 1); ctx->st = st; ctx->ex_data_idx = stellar_session_get_ex_new_index(st, "HTTP_DECODER", http_decoder_ex_data_free, NULL); @@ -411,13 +438,23 @@ void *http_decoder_init(struct stellar *st) return ctx; } -void http_decoder_exit(void *ctx) +void http_decoder_exit(void *decoder_ctx) { - if (NULL == ctx) { + if (NULL == decoder_ctx) { return; } - FREE(ctx); + struct http_decoder_context *ctx = (struct http_decoder_context *)decoder_ctx; + if (ctx->http_ev_ctx != NULL) { + FREE(ctx->http_ev_ctx); + } + + if (ctx->decoder != NULL) { + http_decoder_free(ctx->decoder); + ctx->decoder = NULL; + } + + FREE(decoder_ctx); } enum http_message_type http_message_type(struct http_message *msg) @@ -454,7 +491,7 @@ int http_message_get_request_header(struct http_message *msg, struct hstring *ke { if (NULL == msg || (msg->type != HTTP_MESSAGE_REQ_HEADER && msg->type != HTTP_MESSAGE_REQ_HEADER_END) || - NULL == header_array || 0 == array_size) { + NULL == key || NULL == header_array || 0 == array_size) { return -1; } @@ -466,7 +503,7 @@ int http_message_get_response_header(struct http_message *msg, struct hstring *k { if (NULL == msg || (msg->type != HTTP_MESSAGE_RES_HEADER && msg->type != HTTP_MESSAGE_RES_HEADER_END) || - NULL == header_array || 0 == array_size) { + NULL == key || NULL == header_array || 0 == array_size) { return -1; } @@ -475,30 +512,58 @@ int http_message_get_response_header(struct http_message *msg, struct hstring *k int http_message_request_header_next(struct http_message *msg, struct http_header *header) { - return 0; + if (NULL == msg || + (msg->type != HTTP_MESSAGE_REQ_HEADER && msg->type != HTTP_MESSAGE_REQ_HEADER_END) || + NULL == header) { + return -1; + } + + return http_decoder_half_data_iter_header(msg->data, header); } int http_message_response_header_next(struct http_message *msg, struct http_header *header) { - return 0; + if (NULL == msg || + (msg->type != HTTP_MESSAGE_RES_HEADER && msg->type != HTTP_MESSAGE_RES_HEADER_END) || + NULL == header) { + return -1; + } + + return http_decoder_half_data_iter_header(msg->data, header); } -void http_message_get_request_raw_body(struct http_message *msg, struct hstring *body) +int http_message_get_request_raw_body(struct http_message *msg, struct hstring *body) { + if (NULL == msg || (msg->type != HTTP_MESSAGE_REQ_BODY) || NULL == body) { + return -1; + } + return http_decoder_half_data_get_raw_body(msg->data, body); } -void http_message_get_response_raw_body(struct http_message *msg, struct hstring *body) +int http_message_get_response_raw_body(struct http_message *msg, struct hstring *body) { + if (NULL == msg || (msg->type != HTTP_MESSAGE_RES_BODY) || NULL == body) { + return -1; + } + return http_decoder_half_data_get_raw_body(msg->data, body); } -void http_message_get_request_decompress_body(struct http_message *msg, struct hstring *body) +int http_message_get_request_decompress_body(struct http_message *msg, struct hstring *body) { + if (NULL == msg || (msg->type != HTTP_MESSAGE_REQ_BODY) || NULL == body) { + return -1; + } + return http_decoder_half_data_get_decompress_body(msg->data, body); } -void http_message_get_response_decompress_body(struct http_message *msg, struct hstring *body) +int http_message_get_response_decompress_body(struct http_message *msg, struct hstring *body) { + if (NULL == msg || (msg->type != HTTP_MESSAGE_RES_BODY) || NULL == body) { + return -1; + } + return http_decoder_half_data_get_decompress_body(msg->data, body); }
\ No newline at end of file diff --git a/src/http_decoder/http_decoder.h b/src/http_decoder/http_decoder.h index ed5724e..68202ba 100644 --- a/src/http_decoder/http_decoder.h +++ b/src/http_decoder/http_decoder.h @@ -78,13 +78,13 @@ int http_message_request_header_next(struct http_message *msg, struct http_heade int http_message_response_header_next(struct http_message *msg, struct http_header *header); -void http_message_get_request_raw_body(struct http_message *msg, struct hstring *body); +int http_message_get_request_raw_body(struct http_message *msg, struct hstring *body); -void http_message_get_response_raw_body(struct http_message *msg, struct hstring *body); +int http_message_get_response_raw_body(struct http_message *msg, struct hstring *body); -void http_message_get_request_decompress_body(struct http_message *msg, struct hstring *body); +int http_message_get_request_decompress_body(struct http_message *msg, struct hstring *body); -void http_message_get_response_decompress_body(struct http_message *msg, struct hstring *body); +int http_message_get_response_decompress_body(struct http_message *msg, struct hstring *body); #ifdef __cplusplus } diff --git a/src/http_decoder/http_decoder_half.c b/src/http_decoder/http_decoder_half.c index c0b195b..5b761e3 100644 --- a/src/http_decoder/http_decoder_half.c +++ b/src/http_decoder/http_decoder_half.c @@ -39,34 +39,12 @@ struct http_decoder_half { int is_cache_header; int is_cache_body; - struct http_decoder_half_data *data; + struct http_decoder_half_data *ref_data; enum http_event event; - http_event_cb *event_cb; - void *cb_args; + http_event_cb *http_ev_cb; + void *http_ev_ctx; }; -struct http_decoder_half *http_decoder_half_new() -{ - struct http_decoder_half *half = CALLOC(struct http_decoder_half, 1); - assert(half); - - return half; -} - -void http_decoder_half_free(struct http_decoder_half *half) -{ - if (NULL == half) { - return; - } - - if (half->data != NULL) { - http_decoder_half_data_free(half->data); - half->data = NULL; - } - - FREE(half); -} - #ifdef HTTP_DECODER_DEBUG static void printf_debug_info(const char *desc, const char *at, size_t length) { @@ -74,7 +52,7 @@ static void printf_debug_info(const char *desc, const char *at, size_t length) { char *temp = safe_dup(at, length); printf("HTTP PARSER STAGE: %s: %s\n", desc, temp); - safe_free(temp); + FREE(temp); } else { @@ -119,13 +97,8 @@ static int on_message_begin(llhttp_t *http) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - assert(half->data == NULL); half->event = HTTP_EVENT_INIT; - if (half->event_cb != NULL) { - half->event_cb(half->event, &half->data, half->cb_args); - } - return 0; } @@ -136,33 +109,74 @@ static int on_message_complete(llhttp_t *http) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - //trigger http_body end - if (half->parser.type == HTTP_REQUEST) { - if (half->event == HTTP_EVENT_REQ_BODY_DATA) { - half->event = HTTP_EVENT_REQ_BODY_END; - if (half->event_cb != NULL) { - half->event_cb(half->event, &half->data, half->cb_args); + // 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->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); + } } } } else { - if (half->event == HTTP_EVENT_RES_BODY_DATA) { - half->event = HTTP_EVENT_RES_BODY_END; - if (half->event_cb != NULL) { - half->event_cb(half->event, &half->data, half->cb_args); + // 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); + } } } } - //trigger req/res end + //trigger req_end/res_end if (half->parser.type == HTTP_REQUEST) { half->event = HTTP_EVENT_REQ_END; - if (half->event_cb != NULL) { - half->event_cb(half->event, &half->data, half->cb_args); + if (half->http_ev_cb != NULL) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } else { half->event = HTTP_EVENT_RES_END; - if (half->event_cb != NULL) { - half->event_cb(half->event, &half->data, half->cb_args); + if (half->http_ev_cb != NULL) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } @@ -183,8 +197,15 @@ static int on_method(llhttp_t *http, const char *at, size_t length) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - http_decoder_table_refer(half->data->table, HTTP_ITEM_METHOD, at, length); + if (half->parser.type == HTTP_REQUEST) { + if (half->event == HTTP_EVENT_INIT) { + half->event = HTTP_EVENT_REQ_INIT; + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); + } + } + + if (half->ref_data != NULL) { + http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_METHOD, at, length); } return 0; @@ -198,11 +219,11 @@ static int on_method_complete(llhttp_t *http) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - // if (http_decoder_table_state(half->data->table, HTTP_ITEM_METHOD) == STRING_STATE_REFER) { - // http_decoder_table_cache(half->data->table, HTTP_ITEM_METHOD); - // } - http_decoder_table_commit(half->data->table, HTTP_ITEM_METHOD); + if (half->ref_data != NULL) { + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_METHOD) == STRING_STATE_REFER) { + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_METHOD); + } + http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_METHOD); } return 0; @@ -216,8 +237,8 @@ static int on_uri(llhttp_t *http, const char *at, size_t length) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - http_decoder_table_refer(half->data->table, HTTP_ITEM_URI, at, length); + if (half->ref_data != NULL) { + http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_URI, at, length); } return 0; @@ -231,12 +252,13 @@ static int on_uri_complete(llhttp_t *http) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - // if (half->is_cache_line && http_decoder_table_state(half->data->table, HTTP_ITEM_URI) == STRING_STATE_REFER) - // { - // http_decoder_table_cache(half->data->table, HTTP_ITEM_URI); - // } - http_decoder_table_commit(half->data->table, HTTP_ITEM_URI); + if (half->ref_data != NULL) { + if (half->is_cache_line && + http_decoder_table_state(half->ref_data->table, HTTP_ITEM_URI) == STRING_STATE_REFER) { + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_URI); + } + + http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_URI); } return 0; @@ -250,8 +272,15 @@ static int on_version(llhttp_t *http, const char *at, size_t length) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - http_decoder_table_refer(half->data->table, HTTP_ITEM_VERSION, at, length); + if (half->parser.type == HTTP_RESPONSE) { + if (half->event == HTTP_EVENT_INIT) { + half->event = HTTP_EVENT_RES_INIT; + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); + } + } + + if (half->ref_data != NULL) { + http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_VERSION, at, length); } return 0; @@ -265,24 +294,24 @@ static int on_version_complete(llhttp_t *http) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data) { - // if (half->is_cache_line && http_decoder_table_state(half->data->table, HTTP_ITERM_VERSION) == STRING_STATE_REFER) - // { - // http_decoder_table_cache(half->data->table, HTTP_ITERM_VERSION); - // } - http_decoder_table_commit(half->data->table, HTTP_ITEM_VERSION); + if (half->ref_data) { + if (half->is_cache_line && + http_decoder_table_state(half->ref_data->table, HTTP_ITEM_VERSION) == STRING_STATE_REFER) { + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_VERSION); + } + http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_VERSION); - half->data->major_version = llhttp_get_http_major(&half->parser); - half->data->minor_version = llhttp_get_http_minor(&half->parser); + half->ref_data->major_version = llhttp_get_http_major(&half->parser); + half->ref_data->minor_version = llhttp_get_http_minor(&half->parser); } if (half->parser.type == HTTP_REQUEST) { - half->event = (enum http_event)HTTP_EVENT_REQ_LINE; - if (half->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); + half->event = HTTP_EVENT_REQ_LINE; + if (half->http_ev_cb) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } - + return 0; } @@ -294,8 +323,8 @@ static int on_status(llhttp_t *http, const char *at, size_t length) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - http_decoder_table_refer(half->data->table, HTTP_ITEM_STATUS, at, length); + if (half->ref_data != NULL) { + http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_STATUS, at, length); } return 0; @@ -309,18 +338,19 @@ static int on_status_complete(llhttp_t *http) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - // if (half->is_cache_line && http_decoder_table_state(half->data->table, HTTP_ITERM_STATUS) == STRING_STATE_REFER) - // { - // http_decoder_table_cache(half->data->table, HTTP_ITERM_STATUS); - // } - http_decoder_table_commit(half->data->table, HTTP_ITEM_STATUS); - half->data->status_code = llhttp_get_status_code(&half->parser); + if (half->ref_data != NULL) { + if (half->is_cache_line && + http_decoder_table_state(half->ref_data->table, HTTP_ITEM_STATUS) == STRING_STATE_REFER) { + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_STATUS); + } + + http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_STATUS); + half->ref_data->status_code = llhttp_get_status_code(&half->parser); } - half->event = (enum http_event)HTTP_EVENT_RES_LINE; - if (half->event_cb != NULL) { - half->event_cb(half->event, &half->data, half->cb_args); + half->event = HTTP_EVENT_RES_LINE; + if (half->http_ev_cb != NULL) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } return 0; @@ -334,8 +364,8 @@ static int on_header_field(llhttp_t *http, const char *at, size_t length) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - http_decoder_table_refer(half->data->table, HTTP_ITEM_HDRKEY, at, length); + if (half->ref_data != NULL) { + http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_HDRKEY, at, length); } return 0; @@ -349,12 +379,13 @@ static int on_header_field_complete(llhttp_t *http) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - // if (half->is_cache_header && http_decoder_table_state(half->data->table, HTTP_ITERM_HDRKEY) == STRING_STATE_REFER) - // { - // http_decoder_table_cache(half->data->table, HTTP_ITERM_HDRKEY); - // } - http_decoder_table_commit(half->data->table, HTTP_ITEM_HDRKEY); + if (half->ref_data != NULL) { + if (half->is_cache_header && + http_decoder_table_state(half->ref_data->table, HTTP_ITEM_HDRKEY) == STRING_STATE_REFER) { + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_HDRKEY); + } + + http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_HDRKEY); } return 0; @@ -368,8 +399,8 @@ static int on_header_value(llhttp_t *http, const char *at, size_t length) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - http_decoder_table_refer(half->data->table, HTTP_ITEM_HDRVAL, at, length); + if (half->ref_data != NULL) { + http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_HDRVAL, at, length); } return 0; @@ -383,36 +414,22 @@ static int on_header_value_complete(llhttp_t *http) struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser); assert(half); - if (half->data != NULL) { - // if (half->is_cache_header && - // http_decoder_table_state(half->data->table, HTTP_ITERM_HDRVAL) == - // STRING_STATE_REFER) { - // http_decoder_table_cache(half->data->table, HTTP_ITERM_HDRVAL); - // } - http_decoder_table_commit(half->data->table, HTTP_ITEM_HDRVAL); - } - - if (half->parser.type == HTTP_REQUEST) { - half->event = HTTP_EVENT_REQ_HDR; - if (half->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); - } - } - - if (half->parser.type == HTTP_RESPONSE) { - half->event = HTTP_EVENT_RES_HDR; - if (half->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); + if (half->ref_data != NULL) { + if (half->is_cache_header && + http_decoder_table_state(half->ref_data->table, HTTP_ITEM_HDRVAL) == + STRING_STATE_REFER) { + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_HDRVAL); } + http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_HDRVAL); } - if (half->data != NULL) { - if (half->data->content_encoding == HTTP_CONTENT_ENCODING_NONE) { + if (half->ref_data != NULL) { + if (half->ref_data->content_encoding == HTTP_CONTENT_ENCODING_NONE) { struct http_header http_hdr = {0}; struct hstring key = {.str = (char *)"Content-Encoding", .str_len = 16}; - if (http_decoder_table_get_header(half->data->table, &key, &http_hdr, 1) == 1) { + if (http_decoder_table_get_header(half->ref_data->table, &key, &http_hdr, 1) == 1) { char *str = safe_dup(http_hdr.val.str, http_hdr.val.str_len); - half->data->content_encoding = http_content_encoding_str2int(str); + half->ref_data->content_encoding = http_content_encoding_str2int(str); FREE(str); } } @@ -458,15 +475,15 @@ static int on_headers_complete(llhttp_t *http) if (half->parser.type == HTTP_REQUEST) { half->event = HTTP_EVENT_REQ_HDR_END; - if (half->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); + if (half->http_ev_cb) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } if (half->parser.type == HTTP_RESPONSE) { half->event = HTTP_EVENT_RES_HDR_END; - if (half->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); + if (half->http_ev_cb) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } @@ -485,57 +502,56 @@ static int on_body(llhttp_t *http, const char *at, size_t length) if (half->parser.type == HTTP_REQUEST) { if (half->event == HTTP_EVENT_REQ_HDR_END) { half->event = HTTP_EVENT_REQ_BODY_BEGIN; - if (half->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); + if (half->http_ev_cb) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } } else { if (half->event == HTTP_EVENT_RES_HDR_END) { half->event = HTTP_EVENT_RES_BODY_BEGIN; - if (half->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); + if (half->http_ev_cb) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } } // 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->data) { - // http_decoder_table_refer(half->data->table, HTTP_ITERM_BODY, at, - // length); - // http_decoder_table_cache(half->data->table, HTTP_ITERM_BODY); - // } - // } else { - if (half->data != NULL) { - if (http_decoder_table_state(half->data->table, HTTP_ITEM_BODY) == STRING_STATE_COMMIT) { - http_decoder_table_reset(half->data->table, HTTP_ITEM_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); + } + } 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->data->table, HTTP_ITEM_BODY, at, length); - http_decoder_table_commit(half->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); - http_decoder_half_data_decompress(half->data); + http_decoder_half_data_decompress(half->ref_data); } if (half->parser.type == HTTP_REQUEST) { half->event = HTTP_EVENT_REQ_BODY_DATA; - if (half->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); + 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->event_cb) { - half->event_cb(half->event, &half->data, half->cb_args); + if (half->http_ev_cb) { + half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); } } - // } + } return 0; } -void http_decoder_half_init(struct http_decoder_half *half, http_event_cb *event_cb, - void *cb_args, int is_cache_line, int is_cache_header, +void http_decoder_half_init(struct http_decoder_half *half, http_event_cb *http_ev_cb, + int is_cache_line, int is_cache_header, int is_cache_body) { if (NULL == half) { @@ -576,22 +592,48 @@ void http_decoder_half_init(struct http_decoder_half *half, http_event_cb *event half->error = HPE_OK; - half->event_cb = event_cb; - half->cb_args = cb_args; //result queue pointer + half->http_ev_cb = http_ev_cb; half->is_cache_line = is_cache_line; half->is_cache_header = is_cache_header; half->is_cache_body = is_cache_body; - half->data = NULL; + half->ref_data = NULL; } -int http_decoder_half_parse(struct http_decoder_half *half, const char *data, - size_t data_len) +struct http_decoder_half * +http_decoder_half_new(http_event_cb *ev_cb, int is_cache_line, + int is_cache_header, int is_cache_body) +{ + struct http_decoder_half *half = CALLOC(struct http_decoder_half, 1); + assert(half); + + http_decoder_half_init(half, ev_cb, is_cache_line, + is_cache_header, is_cache_body); + return half; +} + +void http_decoder_half_free(struct http_decoder_half *half) +{ + if (NULL == half) { + return; + } + + if (half->ref_data != NULL) { + http_decoder_half_data_free(half->ref_data); + half->ref_data = NULL; + } + + FREE(half); +} + +int http_decoder_half_parse(struct http_decoder_half *half, void *http_ev_ctx, + const char *data, size_t data_len) { if (NULL == half || NULL == data || 0 == data_len) { return -1; } + half->http_ev_ctx = http_ev_ctx; half->error = llhttp_execute(&half->parser, data, data_len); if (half->error != HPE_OK) { printf("llhttp_execute parse error: %s %s\n", @@ -599,40 +641,40 @@ int http_decoder_half_parse(struct http_decoder_half *half, const char *data, return -1; } - if (half->data != NULL) { - if (http_decoder_table_state(half->data->table, HTTP_ITEM_URI) == + if (half->ref_data != NULL) { + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_URI) == STRING_STATE_REFER) { - http_decoder_table_cache(half->data->table, HTTP_ITEM_URI); + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_URI); } - if (http_decoder_table_state(half->data->table, HTTP_ITEM_STATUS) == + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_STATUS) == STRING_STATE_REFER) { - http_decoder_table_cache(half->data->table, HTTP_ITEM_STATUS); + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_STATUS); } - if (http_decoder_table_state(half->data->table, HTTP_ITEM_METHOD) == + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_METHOD) == STRING_STATE_REFER) { - http_decoder_table_cache(half->data->table, HTTP_ITEM_METHOD); + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_METHOD); } - if (http_decoder_table_state(half->data->table, HTTP_ITEM_VERSION) == + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_VERSION) == STRING_STATE_REFER) { - http_decoder_table_cache(half->data->table, HTTP_ITEM_VERSION); + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_VERSION); } - if (http_decoder_table_state(half->data->table, HTTP_ITEM_HDRKEY) == + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_HDRKEY) == STRING_STATE_REFER) { - http_decoder_table_cache(half->data->table, HTTP_ITEM_HDRKEY); + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_HDRKEY); } - if (http_decoder_table_state(half->data->table, HTTP_ITEM_HDRVAL) == + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_HDRVAL) == STRING_STATE_REFER) { - http_decoder_table_cache(half->data->table, HTTP_ITEM_HDRVAL); + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_HDRVAL); } - if (http_decoder_table_state(half->data->table, HTTP_ITEM_BODY) == + if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_BODY) == STRING_STATE_REFER) { - http_decoder_table_cache(half->data->table, HTTP_ITEM_BODY); + http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_BODY); } } @@ -715,15 +757,43 @@ int http_decoder_half_data_get_header(struct http_decoder_half_data *data, struct http_header *header_array, size_t array_size) { - http_decoder_table_get_header(data->table, key, header_array, array_size); + if (NULL == data) { + return -1; + } + + return http_decoder_table_get_header(data->table, key, header_array, array_size); } int http_decoder_half_data_iter_header(struct http_decoder_half_data *data, struct http_header *header) { - if (NULL == data || NULL == data->table) { + if (NULL == data || NULL == header) { + return -1; + } + + return http_decoder_table_iter_header(data->table, header); +} + +int http_decoder_half_data_get_raw_body(struct http_decoder_half_data *data, + struct hstring *body) +{ + if (NULL == data || NULL == body) { return -1; } - http_decoder_table_iter_header(data->table, header); + return http_decoder_table_get_body(data->table, body); +} + +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) { + return -1; + } + + 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_half.h b/src/http_decoder/http_decoder_half.h index 5eede43..b09aa5e 100644 --- a/src/http_decoder/http_decoder_half.h +++ b/src/http_decoder/http_decoder_half.h @@ -25,21 +25,23 @@ extern "C" enum http_event { HTTP_EVENT_INIT = 0, - HTTP_EVENT_REQ_LINE = 1 << 1, - HTTP_EVENT_REQ_HDR = 1 << 2, - HTTP_EVENT_REQ_HDR_END = 1 << 3, - HTTP_EVENT_REQ_BODY_BEGIN = 1 << 4, - HTTP_EVENT_REQ_BODY_DATA = 1 << 5, - HTTP_EVENT_REQ_BODY_END = 1 << 6, - HTTP_EVENT_REQ_END = 1 << 7, - - HTTP_EVENT_RES_LINE = 1 << 8, - HTTP_EVENT_RES_HDR = 1 << 9, - HTTP_EVENT_RES_HDR_END = 1 << 10, - HTTP_EVENT_RES_BODY_BEGIN = 1 << 11, - HTTP_EVENT_RES_BODY_DATA = 1 << 12, - HTTP_EVENT_RES_BODY_END = 1 << 13, - HTTP_EVENT_RES_END = 1 << 14, + HTTP_EVENT_REQ_INIT = 1 << 1, + HTTP_EVENT_REQ_LINE = 1 << 2, + HTTP_EVENT_REQ_HDR = 1 << 3, + HTTP_EVENT_REQ_HDR_END = 1 << 4, + HTTP_EVENT_REQ_BODY_BEGIN = 1 << 5, + HTTP_EVENT_REQ_BODY_DATA = 1 << 6, + HTTP_EVENT_REQ_BODY_END = 1 << 7, + HTTP_EVENT_REQ_END = 1 << 8, + + HTTP_EVENT_RES_INIT = 1 << 9, + HTTP_EVENT_RES_LINE = 1 << 10, + HTTP_EVENT_RES_HDR = 1 << 11, + HTTP_EVENT_RES_HDR_END = 1 << 12, + HTTP_EVENT_RES_BODY_BEGIN = 1 << 13, + HTTP_EVENT_RES_BODY_DATA = 1 << 14, + HTTP_EVENT_RES_BODY_END = 1 << 15, + HTTP_EVENT_RES_END = 1 << 16, }; struct http_decoder_half; @@ -47,15 +49,14 @@ struct http_decoder_half_data; typedef void http_event_cb(enum http_event event, struct http_decoder_half_data **data, void *cb_args); -struct http_decoder_half *http_decoder_half_new(); +struct http_decoder_half * +http_decoder_half_new(http_event_cb *event_cb, int is_cache_line, + int is_cache_header, int is_cache_body); void http_decoder_half_free(struct http_decoder_half *half); -void http_decoder_half_init(struct http_decoder_half *half, http_event_cb *event_cb, - void *cb_args, int is_cache_line, int is_cache_header, - int is_cache_body); - -int http_decoder_half_parse(struct http_decoder_half *half, const char *data, size_t len); +int http_decoder_half_parse(struct http_decoder_half *half, void *ev_ctx, + const char *data, size_t len); //http decoder half data API struct http_decoder_half_data *http_decoder_half_data_new(); @@ -75,6 +76,13 @@ int http_decoder_half_data_get_header(struct http_decoder_half_data *data, int http_decoder_half_data_iter_header(struct http_decoder_half_data *data, struct http_header *header); + +int http_decoder_half_data_get_raw_body(struct http_decoder_half_data *data, + struct hstring *body); + +int http_decoder_half_data_get_decompress_body(struct http_decoder_half_data *data, + struct hstring *body); + #ifdef __cplusplus } #endif diff --git a/src/http_decoder/http_decoder_string.c b/src/http_decoder/http_decoder_string.c index 15ff290..bd24253 100644 --- a/src/http_decoder/http_decoder_string.c +++ b/src/http_decoder/http_decoder_string.c @@ -8,8 +8,13 @@ *********************************************************************************************** */ +#include <stdio.h> #include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "stellar/utils.h" +#include "http_decoder_utils.h" #include "http_decoder_string.h" static const char *string_state_to_desc(enum string_state state) @@ -123,7 +128,7 @@ void http_decoder_string_reset(struct http_decoder_string *rstr) case STRING_STATE_REFER: case STRING_STATE_CACHE: case STRING_STATE_COMMIT: - safe_free(rstr->cache.str); + FREE(rstr->cache.str); memset(rstr, 0, sizeof(struct http_decoder_string)); break; default: @@ -139,10 +144,10 @@ enum string_state http_decoder_string_state(struct http_decoder_string *rstr) return rstr->state; } -void http_decoder_string_get(struct http_decoder_string *rstr, struct hstring *out) +int http_decoder_string_get(struct http_decoder_string *rstr, struct hstring *out) { if (NULL == rstr || NULL == out) { - return; + return -1; } if (http_decoder_string_state(rstr) == STRING_STATE_COMMIT) { @@ -152,6 +157,8 @@ void http_decoder_string_get(struct http_decoder_string *rstr, struct hstring *o out->str = NULL; out->str_len = 0; } + + return 0; } void http_decoder_string_dump(struct http_decoder_string *rstr, const char *desc) diff --git a/src/http_decoder/http_decoder_string.h b/src/http_decoder/http_decoder_string.h index 82a812b..363d6af 100644 --- a/src/http_decoder/http_decoder_string.h +++ b/src/http_decoder/http_decoder_string.h @@ -76,7 +76,7 @@ void http_decoder_string_reset(struct http_decoder_string *rstr); enum string_state http_decoder_string_state(struct http_decoder_string *rstr); -void http_decoder_string_get(struct http_decoder_string *rstr, struct hstring *out); +int http_decoder_string_get(struct http_decoder_string *rstr, struct hstring *out); void http_decoder_string_dump(struct http_decoder_string *rstr, const char *desc); diff --git a/src/http_decoder/http_decoder_table.c b/src/http_decoder/http_decoder_table.c index 292c80c..eee993f 100644 --- a/src/http_decoder/http_decoder_table.c +++ b/src/http_decoder/http_decoder_table.c @@ -361,65 +361,65 @@ void http_decoder_table_dump(struct http_decoder_table *table) } } -void http_decoder_table_get_uri(struct http_decoder_table *table, +int http_decoder_table_get_uri(struct http_decoder_table *table, struct hstring *out) { if (NULL == table || NULL == out) { - return; + return -1; } - http_decoder_string_get(&table->uri, out); + return http_decoder_string_get(&table->uri, out); } -void http_decoder_table_get_method(struct http_decoder_table *table, +int http_decoder_table_get_method(struct http_decoder_table *table, struct hstring *out) { if (NULL == table || NULL == out) { - return; + return -1; } - http_decoder_string_get(&table->method, out); + return http_decoder_string_get(&table->method, out); } -void http_decoder_table_get_status(struct http_decoder_table *table, +int http_decoder_table_get_status(struct http_decoder_table *table, struct hstring *out) { if (NULL == table || NULL == out) { - return; + return -1; } - http_decoder_string_get(&table->status, out); + return http_decoder_string_get(&table->status, out); } -void http_decoder_table_get_version(struct http_decoder_table *table, +int http_decoder_table_get_version(struct http_decoder_table *table, struct hstring *out) { if (NULL == table || NULL == out) { - return; + return -1; } - http_decoder_string_get(&table->version, out); + return http_decoder_string_get(&table->version, out); } -void http_decoder_table_get_body(struct http_decoder_table *table, +int http_decoder_table_get_body(struct http_decoder_table *table, struct hstring *out) { if (NULL == table || NULL == out) { - return; + return -1; } - http_decoder_string_get(&table->body, out); + return http_decoder_string_get(&table->body, out); } -size_t http_decoder_table_get_header(struct http_decoder_table *table, struct hstring *key, - struct http_header *header_array, size_t array_size) +int http_decoder_table_get_header(struct http_decoder_table *table, struct hstring *key, + struct http_header *header_array, size_t array_size) { - if (NULL == table || NULL == key || NULL == header_array) { + if (NULL == table || NULL == key->str || 0 == key->str_len) { return 0; } - size_t header_cnt = 0; - for (size_t i = 0; i < table->header_index && header_cnt < array_size; i++) { + int header_cnt = 0; + for (int i = 0; i < table->header_index && header_cnt < array_size; i++) { struct http_decoder_header *header = &table->headers[i]; if (http_decoder_string_state(&header->key) == STRING_STATE_COMMIT && http_decoder_string_state(&header->val) == STRING_STATE_COMMIT) { @@ -438,12 +438,12 @@ size_t http_decoder_table_get_header(struct http_decoder_table *table, struct hs int http_decoder_table_iter_header(struct http_decoder_table *table, struct http_header *header) { - if (NULL == table) { + if (NULL == table || NULL == header) { return -1; } if (table->header_iter >= table->header_index) { - table->header_iter = 0; + return 0; } struct http_decoder_header *tmp_decoder_header = &table->headers[table->header_iter++]; diff --git a/src/http_decoder/http_decoder_table.h b/src/http_decoder/http_decoder_table.h index 53ff61d..41ee12f 100644 --- a/src/http_decoder/http_decoder_table.h +++ b/src/http_decoder/http_decoder_table.h @@ -55,22 +55,22 @@ void http_decoder_table_remove(struct http_decoder_table *table); void http_decoder_table_dump(struct http_decoder_table *table); -void http_decoder_table_get_uri(struct http_decoder_table *table, +int http_decoder_table_get_uri(struct http_decoder_table *table, struct hstring *out); -void http_decoder_table_get_method(struct http_decoder_table *table, +int http_decoder_table_get_method(struct http_decoder_table *table, struct hstring *out); -void http_decoder_table_get_status(struct http_decoder_table *table, +int http_decoder_table_get_status(struct http_decoder_table *table, struct hstring *out); -void http_decoder_table_get_version(struct http_decoder_table *table, +int http_decoder_table_get_version(struct http_decoder_table *table, struct hstring *out); -void http_decoder_table_get_body(struct http_decoder_table *table, +int http_decoder_table_get_body(struct http_decoder_table *table, struct hstring *out); -size_t http_decoder_table_get_header(struct http_decoder_table *table, struct hstring *key, +int http_decoder_table_get_header(struct http_decoder_table *table, struct hstring *key, struct http_header *header_array, size_t array_size); int http_decoder_table_iter_header(struct http_decoder_table *table, diff --git a/src/stellar_on_sapp/start_loader.inf b/src/stellar_on_sapp/start_loader.inf index 89b2f94..f3726ff 100644 --- a/src/stellar_on_sapp/start_loader.inf +++ b/src/stellar_on_sapp/start_loader.inf @@ -12,6 +12,6 @@ DESTROY_FUNC=STELLAR_START_LOADER_EXIT FUNC_FLAG=ALL FUNC_NAME=stellar_on_sapp_tcp_entry -[UDP] -FUNC_FLAG=ALL -FUNC_NAME=stellar_on_sapp_udp_entry
\ No newline at end of file +#[UDP] +#FUNC_FLAG=ALL +#FUNC_NAME=stellar_on_sapp_udp_entry
\ No newline at end of file diff --git a/test/http_decoder/CMakeLists.txt b/test/http_decoder/CMakeLists.txt index 4ef959c..eee60e1 100644 --- a/test/http_decoder/CMakeLists.txt +++ b/test/http_decoder/CMakeLists.txt @@ -1,9 +1,9 @@ set(DECODER_NAME http_decoder) -add_library(${DECODER_NAME}_test_plug SHARED http_decoder_gtest.cpp) -add_dependencies(${DECODER_NAME}_test_plug ${DECODER_NAME}) -target_link_libraries(${DECODER_NAME}_test_plug MESA_prof_load cjson) -set_target_properties(${DECODER_NAME}_test_plug PROPERTIES PREFIX "") +add_library(${DECODER_NAME}_test SHARED http_decoder_gtest.cpp) +add_dependencies(${DECODER_NAME}_test ${DECODER_NAME}) +target_link_libraries(${DECODER_NAME}_test MESA_prof_load cjson) +set_target_properties(${DECODER_NAME}_test PROPERTIES PREFIX "") set(TEST_RUN_DIR ${CMAKE_CURRENT_BINARY_DIR}/sapp) set(TEST_MAIN ${TEST_RUN_DIR}/plugin_test_main) @@ -26,7 +26,7 @@ add_test(NAME UPDATE_SAPP_REORDER COMMAND bash -c "sed -i 's/reorder_pkt_max=32/ # update plugin to be tested add_test(NAME UPDATE_STELLAR_ON_SAPP_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/src/stellar_on_sapp/stellar_on_sapp.so ${TEST_RUN_DIR}/plug/stellar_on_sapp/stellar_on_sapp.so") add_test(NAME UPDATE_PLUG_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/src/${DECODER_NAME}/${DECODER_NAME}.so ${TEST_RUN_DIR}/stellar_plugin/${DECODER_NAME}.so") -add_test(NAME UPDATE_TEST_SO COMMAND sh -c "cp ${CMAKE_CURRENT_BINARY_DIR}/${DECODER_NAME}_test_plug.so ${TEST_RUN_DIR}/stellar_plugin/${DECODER_NAME}_test_plug.so") +add_test(NAME UPDATE_TEST_SO COMMAND sh -c "cp ${CMAKE_CURRENT_BINARY_DIR}/${DECODER_NAME}_test.so ${TEST_RUN_DIR}/stellar_plugin/${DECODER_NAME}_test.so") set_tests_properties(INSTALL_TEST_MAIN COPY_TEST_MAIN COPY_CONF COPY_SPEC COPY_CONFLIST COPY_INF UPDATE_SAPP_LOG UPDATE_SAPP_SYN_MODE UPDATE_SAPP_REORDER @@ -34,7 +34,7 @@ set_tests_properties(INSTALL_TEST_MAIN COPY_TEST_MAIN COPY_CONF COPY_SPEC COPY_C PROPERTIES FIXTURES_SETUP TestFixture) # run tests -# add_test(NAME RUN_HTTP_SIMPLE_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/proto_identify_http.json -# -f "find ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/ -name *.pcap|sort -V" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME RUN_HTTP_SIMPLE_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_simple_result.json + -f "find ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/ -name *.pcap|sort -V" WORKING_DIRECTORY ${TEST_RUN_DIR}) -# set_tests_properties(RUN_HTTP_SIMPLE_TEST PROPERTIES FIXTURES_REQUIRED TestFixture)
\ No newline at end of file +set_tests_properties(RUN_HTTP_SIMPLE_TEST PROPERTIES FIXTURES_REQUIRED TestFixture)
\ 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 9ebaddd..75ad985 100644 --- a/test/http_decoder/http_decoder_gtest.cpp +++ b/test/http_decoder/http_decoder_gtest.cpp @@ -33,134 +33,184 @@ int commit_test_result_json(cJSON *node, const char *name); #include "MESA/stream.h" static int g_result_count = 1; -int g_test_exdata_idx = 0; -int g_l7_exdata_idx = 0; -int g_test_app_plugin_id = 0; -int g_stellar_session_bridge_id = -1; - -#define MAX_PROTO_ID_NUM 10000 -static char *g_proto_id2name[MAX_PROTO_ID_NUM]; - -struct http_decoder_test_context { - int topic_id; - int plugin_id; -}; - -// static int load_l7_protocol_mapper(const char *filename) { -// int ret = 0, proto_id = 0; -// char line[1024] = {0}; -// char type_name[32] = {0}; -// char proto_name[32] = {0}; - -// memset(g_proto_id2name, 0, sizeof(g_proto_id2name)); -// FILE *fp = fopen(filename, "r"); -// if (NULL == fp) { -// printf("Open %s failed ...", filename); -// return -1; -// } - -// memset(line, 0, sizeof(line)); - -// while ((fgets(line, sizeof(line), fp)) != NULL) { -// if (line[0] == '#' || line[0] == '\n' || -// line[0] == '\r' || line[0] == '\0') { -// continue; -// } - -// ret = sscanf(line, "%30s %30s %d", type_name, proto_name, &proto_id); -// assert(ret == 3 && proto_id < MAX_PROTO_ID_NUM); - -// g_proto_id2name[proto_id] = (char *)calloc(strlen(proto_name)+1, 1); -// strcpy(g_proto_id2name[proto_id], proto_name); -// memset(line, 0, sizeof(line)); -// } - -// fclose(fp); -// fp = NULL; - -// return ret; -// } - -static void commit_test_result(cJSON *ctx, struct session *sess) +int g_req_exdata_idx = 0; +int g_res_exdata_idx = 0; + +void output_http_req_line(struct http_request_line *req_line) { - assert(g_l7_exdata_idx >= 0 && ctx != NULL); - struct http_request_line *label = (struct http_request_line *)session_get_ex_data(sess, g_l7_exdata_idx);; - // if(label != NULL) - // { - // int proto_ids[8]; - // const char* proto_names[8]; - // for(int i = 0; i < label->protocol_id_num; i++) - // { - // proto_ids[i] = (int)(label->protocol_id[i]); - // proto_names[i] = g_proto_id2name[proto_ids[i]]; - - // } - // cJSON *label_ids = cJSON_CreateIntArray(proto_ids, label->protocol_id_num); - // cJSON_AddItemToObject(ctx, "l7_label_id", label_ids); - // cJSON *label_names = cJSON_CreateStringArray(proto_names, label->protocol_id_num); - // cJSON_AddItemToObject(ctx, "l7_label_name", label_names); - // } - // else - // { - // cJSON_AddStringToObject(ctx, "l7_label_id", "UNKNOWN"); - // } - // unsigned char dir_flag; - // int is_symmetric=session_is_symmetric(sess, &dir_flag); - // if(is_symmetric) - // { - // cJSON_AddStringToObject(ctx, "STREAM_DIR", "DOUBLE"); - // } - // else if(dir_flag == SESSION_SEEN_C2S_FLOW) - // { - // cJSON_AddStringToObject(ctx, "STREAM_DIR", "C2S"); - // } - // else if(dir_flag == SESSION_SEEN_S2C_FLOW) - // { - // cJSON_AddStringToObject(ctx, "STREAM_DIR", "S2C"); - // } - // else - // { - // assert(0); - // } - // if (ctx) - // { - // char result_name[128] = ""; - // sprintf(result_name, "APP_PROTO_IDENTIFY_RESULT_%d", g_result_count); - // commit_test_result_json(ctx, result_name); - // g_result_count += 1; - // } - return; + char tmp_str[2048] = {0}; + snprintf(tmp_str, req_line->method.str_len + 1, "%s", req_line->method.str); + printf("req_method:%s\n", tmp_str); + + memset(tmp_str, 0, sizeof(tmp_str)); + snprintf(tmp_str, req_line->uri.str_len + 1, "%s", req_line->uri.str); + printf("req_uri:%s\n", tmp_str); + + memset(tmp_str, 0, sizeof(tmp_str)); + snprintf(tmp_str, req_line->version.str_len + 1, "%s", req_line->version.str); + printf("req_version:%s\n", tmp_str); +} + +void output_http_res_line(struct http_response_line *res_line) +{ + char tmp_str[2048] = {0}; + snprintf(tmp_str, res_line->version.str_len + 1, "%s", res_line->version.str); + printf("res_version:%s\n", tmp_str); + + memset(tmp_str, 0, sizeof(tmp_str)); + snprintf(tmp_str, res_line->status.str_len + 1, "%s", res_line->status.str); + printf("res_status:%s\n", tmp_str); +} + +void output_http_header(struct http_header *header) +{ + printf("<%s:%s>\n", header->key.str, header->val.str); +} + +void output_http_req_body(struct hstring *body) +{ + +} + +void output_http_res_body(struct hstring *body) +{ + +} + + +int http_field_add_to_json(cJSON *object, const char *name, char *value, char length) +{ + if (value != NULL && length > 0) { + char *tmp = (char *)calloc(1, length + 1); + memcpy(tmp, value, length); + cJSON_AddStringToObject(object, name, tmp); + free(tmp); + tmp = NULL; + } + + return 0; +} + +void req_line_to_json(cJSON *ctx, struct http_request_line *req_line) +{ + http_field_add_to_json(ctx, "method", req_line->method.str, + req_line->method.str_len); + http_field_add_to_json(ctx, "uri", req_line->uri.str, + req_line->uri.str_len); + http_field_add_to_json(ctx, "req_version", req_line->version.str, + req_line->version.str_len); + cJSON_AddNumberToObject(ctx, "major_version", req_line->major_version); + cJSON_AddNumberToObject(ctx, "minor_version", req_line->minor_version); +} + +void res_line_to_json(cJSON *ctx, struct http_response_line *res_line) +{ + http_field_add_to_json(ctx, "res_version", res_line->version.str, + res_line->version.str_len); + http_field_add_to_json(ctx, "res_status", res_line->status.str, + res_line->status.str_len); + cJSON_AddNumberToObject(ctx, "major_version", res_line->major_version); + cJSON_AddNumberToObject(ctx, "minor_version", res_line->minor_version); + cJSON_AddNumberToObject(ctx, "status_code", res_line->status_code); +} + +void http_header_to_json(cJSON *ctx, struct http_header *header) +{ + char key[256] = {0}; + snprintf(key, header->key.str_len + 1, "%s", header->key.str); + + http_field_add_to_json(ctx, key, header->val.str, header->val.str_len); } static int http_decoder_test_entry(struct session *sess, int topic_id, const void *data, void *cb_arg) { struct http_message *msg = (struct http_message *)data; - - printf("................http_decoder_test_entry................\n"); - struct http_request_line line; - memset(&line, 0, sizeof(line)); + struct http_request_line req_line = {0}; + struct http_response_line res_line = {0}; + struct http_header header = {0}; + struct hstring body = {0}; + int exdata_idx = 0; 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) { + exdata_idx = g_req_exdata_idx; + } else { + exdata_idx = g_res_exdata_idx; + } + + cJSON *ctx = (cJSON *)session_get_ex_data(sess, exdata_idx); + if (NULL == ctx) { + ctx = cJSON_CreateObject(); + cJSON_AddStringToObject(ctx, "Tuple4", session_get0_readable_addr(sess)); + session_set_ex_data(sess, exdata_idx, ctx); + } + switch (msg_type) { case HTTP_MESSAGE_REQ_LINE: - http_message_get_request_line(msg, &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: + while (http_message_request_header_next(msg, &header) > 0) { + http_header_to_json(ctx, &header); + } + break; + case HTTP_MESSAGE_REQ_BODY: + http_message_get_request_raw_body(msg, &body); + output_http_req_body(&body); + break; + case HTTP_MESSAGE_RES_LINE: + http_message_get_response_line(msg, &res_line); + res_line_to_json(ctx, &res_line); + break; + case HTTP_MESSAGE_RES_HEADER_END: + while (http_message_response_header_next(msg, &header) > 0) { + http_header_to_json(ctx, &header); + } + break; + case HTTP_MESSAGE_RES_BODY: + http_message_get_response_raw_body(msg, &body); + output_http_res_body(&body); break; default: break; } + char result_name[128] = {0}; + if (msg_type == HTTP_MESSAGE_REQ_HEADER_END) { + sprintf(result_name, "HTTP_DECODER_RESULT_%d", g_result_count); + commit_test_result_json(ctx, result_name); + session_set_ex_data(sess, exdata_idx, NULL); + g_result_count++; + } + + if (msg_type == HTTP_MESSAGE_RES_HEADER_END) { + sprintf(result_name, "HTTP_DECODER_RESULT_%d", g_result_count); + commit_test_result_json(ctx, result_name); + session_set_ex_data(sess, exdata_idx, NULL); + g_result_count++; + } + return 0; } extern "C" void *http_decoder_test_init(struct stellar *st) { - char l7_label_name[256] = ""; - char l7_bridge_name[256] = ""; - char l7_proto_name[256] = ""; + g_req_exdata_idx = stellar_session_get_ex_new_index(st, "HTTP_DECODER_REQ_TEST", NULL, NULL); + if (g_req_exdata_idx < 0) { + printf("http_decoder_test_init: can't get http_decoder req exdata index !!!\n"); + exit(-1); + } - MESA_load_profile_string_def("./tsgconf/main.conf", "SYSTEM", "L7_LABEL_NAME", l7_label_name, sizeof(l7_label_name), "L7_PROTOCOL_LABEL"); - MESA_load_profile_string_def("./tsgconf/main.conf", "SYSTEM", "APP_BRIDGE_NAME", l7_bridge_name, sizeof(l7_bridge_name), "APP_BRIDGE"); - MESA_load_profile_string_def("./tsgconf/main.conf", "SYSTEM", "L7_PROTOCOL_FILE", l7_proto_name, sizeof(l7_proto_name), "./tsgconf/tsg_l7_protocol.conf"); + g_res_exdata_idx = stellar_session_get_ex_new_index(st, "HTTP_DECODER_RES_TEST", NULL, NULL); + if (g_res_exdata_idx < 0) { + printf("http_decoder_test_init: can't get http_decoder res exdata index !!!\n"); + exit(-1); + } int topic_id = session_mq_get_topic_id(st, "HTTP_DECODER_MESSAGE"); if (topic_id < 0) { diff --git a/test/http_decoder/http_pcap/simple_http.pcap b/test/http_decoder/http_pcap/simple_http.pcap Binary files differdeleted file mode 100644 index a4b6bea..0000000 --- a/test/http_decoder/http_pcap/simple_http.pcap +++ /dev/null diff --git a/test/http_decoder/test_env/spec.toml b/test/http_decoder/test_env/spec.toml index 0bfa214..626f85b 100644 --- a/test/http_decoder/test_env/spec.toml +++ b/test/http_decoder/test_env/spec.toml @@ -6,6 +6,6 @@ init = "http_decoder_init" exit = "http_decoder_exit" [[plugin]] -path = "./stellar_plugin/http_decoder_test_plug.so" +path = "./stellar_plugin/http_decoder_test.so" init = "http_decoder_test_init" exit = "http_decoder_test_exit" diff --git a/test/http_decoder/test_result_json/proto_identify_http.json b/test/http_decoder/test_result_json/proto_identify_http.json deleted file mode 100644 index 757d9e2..0000000 --- a/test/http_decoder/test_result_json/proto_identify_http.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "Tuple4": "192.168.38.73.50806>192.168.40.137.80", - "STREAM_TYPE": "TCP", - "l7_label_id": [32], - "l7_label_name": ["HTTP"], - "STREAM_DIR": "C2S", - "name": "APP_PROTO_IDENTIFY_RESULT_1" - } -] |
