summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlijia <[email protected]>2024-09-02 19:16:34 +0800
committerlijia <[email protected]>2024-09-05 15:53:54 +0800
commit28bc857231d14f67e46e1fd0433916064a8e9dbc (patch)
tree660c33b024152fe61bb2492171e67b69a6361c67
parente05b3b13d531006f2c7801988dea436aa613a44e (diff)
http push line and all headers togetherdev-http-push-headers-together
-rw-r--r--decoders/http/CMakeLists.txt3
-rw-r--r--decoders/http/http_decoder.c354
-rw-r--r--decoders/http/http_decoder_half.c1045
-rw-r--r--decoders/http/http_decoder_half.h25
-rw-r--r--decoders/http/http_decoder_private.h1
-rw-r--r--decoders/http/http_decoder_result_queue.c18
-rw-r--r--decoders/http/http_decoder_string.c289
-rw-r--r--decoders/http/http_decoder_string.h73
-rw-r--r--decoders/http/http_decoder_table.c579
-rw-r--r--decoders/http/http_decoder_table.h79
-rw-r--r--decoders/http/http_decoder_tunnel.c13
-rw-r--r--decoders/http/http_decoder_utils.c153
-rw-r--r--decoders/http/http_decoder_utils.h22
-rw-r--r--decoders/http/version.map1
-rw-r--r--include/stellar/http.h71
-rw-r--r--include/stellar/utils.h2
-rw-r--r--test/decoders/http/CMakeLists.txt2
-rw-r--r--test/decoders/http/benchmarks/json/http_get_encoded_uri.json6
-rw-r--r--test/decoders/http/benchmarks/json/http_get_req_pipeline.json3
-rw-r--r--test/decoders/http/benchmarks/json/http_get_single_trans.json3
-rw-r--r--test/decoders/http/benchmarks/json/http_hdrs_exceed_maximum.json3
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state.json22
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state_c2s.json12
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state_exception_c2s.json10
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state_exception_s2c.json14
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state_pipeline.json82
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state_s2c.json12
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state_tunnel.json6
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_c2s.json2
-rw-r--r--test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_s2c.json2
-rw-r--r--test/decoders/http/benchmarks/json/http_multi_parse_error.json8
-rw-r--r--test/decoders/http/benchmarks/json/http_no_content_length.json3
-rw-r--r--test/decoders/http/benchmarks/json/http_out_of_order.json3
-rw-r--r--test/decoders/http/benchmarks/json/http_over_pppoe.json3
-rw-r--r--test/decoders/http/benchmarks/json/http_pipeline_header_splitting.json6
-rw-r--r--test/decoders/http/benchmarks/json/http_post_multipart_form_data.json12
-rw-r--r--test/decoders/http/benchmarks/json/http_req_1byte_sliding_window.json3
-rw-r--r--test/decoders/http/benchmarks/json/http_res_1byte_sliding_window.json3
-rw-r--r--test/decoders/http/benchmarks/json/http_trans_pipeline.json59
-rw-r--r--test/decoders/http/benchmarks/json/http_url_test_without_host.json3
-rw-r--r--test/decoders/http/http_gtest.cpp27
-rw-r--r--test/decoders/http/http_test_plug.cpp81
42 files changed, 978 insertions, 2140 deletions
diff --git a/decoders/http/CMakeLists.txt b/decoders/http/CMakeLists.txt
index c242afe..0c7511e 100644
--- a/decoders/http/CMakeLists.txt
+++ b/decoders/http/CMakeLists.txt
@@ -1,7 +1,6 @@
include_directories(${CMAKE_SOURCE_DIR}/deps)
-set(HTTP_SRC http_decoder.c http_decoder_utils.c http_decoder_half.c
- http_decoder_table.c http_decoder_string.c http_content_decompress.c
+set(HTTP_SRC http_decoder.c http_decoder_utils.c http_decoder_half.c http_content_decompress.c
http_decoder_result_queue.c http_decoder_stat.c http_decoder_tunnel.c)
add_library(http STATIC ${HTTP_SRC})
diff --git a/decoders/http/http_decoder.c b/decoders/http/http_decoder.c
index 5e2db72..a812f80 100644
--- a/decoders/http/http_decoder.c
+++ b/decoders/http/http_decoder.c
@@ -39,7 +39,7 @@ struct http_message *http_body_message_new(enum http_message_type type, struct h
return msg;
}
-static void http_message_decompress_buffer_free(struct http_message *msg)
+static void http_msg_decompress_buffer_free(struct http_message *msg)
{
struct http_decoder_half_data *ref_data = NULL;
if (HTTP_MESSAGE_REQ_BODY_START == msg->type || HTTP_MESSAGE_REQ_BODY == msg->type || HTTP_MESSAGE_REQ_BODY_END == msg->type)
@@ -56,11 +56,29 @@ static void http_message_decompress_buffer_free(struct http_message *msg)
}
}
+static void http_msg_line_headers_free(struct http_message *msg)
+{
+ struct http_decoder_half_data *ref_data = NULL;
+ if (HTTP_MESSAGE_REQ_LINE_HEADERS == msg->type)
+ {
+ ref_data = msg->ref_queue->array[msg->queue_index].req_data;
+ }
+ else if (HTTP_MESSAGE_RES_LINE_HEADERS == msg->type)
+ {
+ ref_data = msg->ref_queue->array[msg->queue_index].res_data;
+ }
+ if (ref_data != NULL)
+ {
+ http_half_line_headers_free(ref_data);
+ }
+}
+
static void http_message_free(void *http_msg, void *cb_arg)
{
if (http_msg)
{
- http_message_decompress_buffer_free((struct http_message *)http_msg);
+ http_msg_decompress_buffer_free((struct http_message *)http_msg);
+ http_msg_line_headers_free((struct http_message *)http_msg);
FREE(http_msg);
}
}
@@ -110,11 +128,10 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
half_data = NULL;
}
- half_data = http_decoder_half_data_new(mempool);
+ half_data = http_decoder_half_data_new(mempool, FLOW_TYPE_C2S);
ret = http_decoder_result_queue_push_req(queue, half_data);
if (ret < 0)
{
- fprintf(stderr, "http_decoder_result_queue_push req failed.");
http_decoder_half_data_free(mempool, half_data);
half_data = NULL;
}
@@ -125,38 +142,17 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_TRANSACTION_NEW, 1);
break;
- case HTTP_EVENT_REQ_LINE:
- msg = http_message_new(HTTP_MESSAGE_REQ_LINE, queue, queue_idx, HTTP_REQUEST);
- session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
- if (httpd_tunnel_identify(httpd_env, FLOW_TYPE_C2S, half_data))
- {
- exdata->tunnel_state = HTTP_TUN_C2S_HDR_START;
- // http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TUNNEL, 1);
- }
- if (httpd_is_tunnel_session(httpd_env, exdata))
- {
- http_decoder_get_url(half_data, mempool);
- }
- break;
- case HTTP_EVENT_REQ_HDR:
- msg = http_message_new(HTTP_MESSAGE_REQ_HEADER, queue, queue_idx, HTTP_REQUEST);
- session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
- break;
+
case HTTP_EVENT_REQ_HDR_END:
+
{
- http_decoder_join_url_finally(ev_ctx, half_data, mempool);
+ http_parse_headers_finally(ev_ctx, half_data, mempool);
/* maybe some parsed headers in buffer, but has not pushed to plugins yet */
-
- if (http_decoder_half_data_has_parsed_header(half_data))
{
- msg = http_message_new(HTTP_MESSAGE_REQ_HEADER, queue, queue_idx, HTTP_REQUEST);
+ msg = http_message_new(HTTP_MESSAGE_REQ_LINE_HEADERS, queue, queue_idx, HTTP_REQUEST);
session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
}
- http_half_data_update_commit_index(half_data);
- msg = http_message_new(HTTP_MESSAGE_REQ_HEADER_END, queue, queue_idx, HTTP_REQUEST);
- session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
-
- int tot_c2s_headers = http_half_data_get_total_parsed_header_count(half_data);
+ int tot_c2s_headers = http_half_get_header_count(half_data);
http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_HEADERS, tot_c2s_headers);
const char *tmp_url = NULL;
@@ -171,15 +167,14 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
break;
case HTTP_EVENT_REQ_BODY_DATA:
{
- hstring raw_body = {};
+ hstring *raw_body = http_half_get_raw_body(half_data);
hstring decompress_body = {};
- http_decoder_half_data_get_raw_body(half_data, (const char **)&raw_body.iov_base, &raw_body.iov_len);
http_half_get_lastest_decompress_buffer(half_data, &decompress_body);
- msg = http_body_message_new(HTTP_MESSAGE_REQ_BODY, queue, queue_idx, HTTP_REQUEST, &raw_body, &decompress_body);
+ msg = http_body_message_new(HTTP_MESSAGE_REQ_BODY, queue, queue_idx, HTTP_REQUEST, raw_body, &decompress_body);
session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
if (decompress_body.iov_base != NULL)
{
- http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_ZIP_BYTES, raw_body.iov_len);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_ZIP_BYTES, raw_body->iov_len);
http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_UNZIP_BYTES, decompress_body.iov_len);
}
}
@@ -237,11 +232,10 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
half_data = NULL;
}
- half_data = http_decoder_half_data_new(mempool);
+ half_data = http_decoder_half_data_new(mempool, FLOW_TYPE_S2C);
ret = http_decoder_result_queue_push_res(queue, half_data);
if (ret < 0)
{
- fprintf(stderr, "http_decoder_result_queue_push res failed.");
http_decoder_half_data_free(mempool, half_data);
half_data = NULL;
}
@@ -256,37 +250,18 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
}
}
break;
- case HTTP_EVENT_RES_LINE:
- msg = http_message_new(HTTP_MESSAGE_RES_LINE, queue, queue_idx, HTTP_RESPONSE);
- session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
- if (httpd_tunnel_identify(httpd_env, FLOW_TYPE_S2C, half_data))
- {
- exdata->tunnel_state = HTTP_TUN_S2C_START;
- }
- else
- {
- // connect response fail, reset tunnel_state
- exdata->tunnel_state = HTTP_TUN_NON;
- }
- break;
- case HTTP_EVENT_RES_HDR:
- msg = http_message_new(HTTP_MESSAGE_RES_HEADER, queue, queue_idx, HTTP_RESPONSE);
- session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
- break;
+
case HTTP_EVENT_RES_HDR_END:
+
{
+ http_parse_headers_finally(ev_ctx, half_data, mempool);
/* maybe some header in table buffer but has not pushed to plugins */
half_data = http_decoder_result_queue_peek_res(queue);
- if (http_decoder_half_data_has_parsed_header(half_data))
{
- msg = http_message_new(HTTP_MESSAGE_RES_HEADER, queue, queue_idx, HTTP_RESPONSE);
+ msg = http_message_new(HTTP_MESSAGE_RES_LINE_HEADERS, queue, queue_idx, HTTP_RESPONSE);
session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
}
- http_half_data_update_commit_index(half_data);
- msg = http_message_new(HTTP_MESSAGE_RES_HEADER_END, queue, queue_idx, HTTP_RESPONSE);
- session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
-
- int tot_s2c_headers = http_half_data_get_total_parsed_header_count(half_data);
+ int tot_s2c_headers = http_half_get_header_count(half_data);
http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_HEADERS, tot_s2c_headers);
if (httpd_is_tunnel_session(httpd_env, exdata))
@@ -303,15 +278,14 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
break;
case HTTP_EVENT_RES_BODY_DATA:
{
- hstring raw_body = {};
- http_decoder_half_data_get_raw_body(half_data, (const char **)&raw_body.iov_base, &raw_body.iov_len);
+ hstring *raw_body = http_half_get_raw_body(half_data);
hstring decompress_body = {};
http_half_get_lastest_decompress_buffer(half_data, &decompress_body);
- msg = http_body_message_new(HTTP_MESSAGE_RES_BODY, queue, queue_idx, HTTP_RESPONSE, &raw_body, &decompress_body);
+ msg = http_body_message_new(HTTP_MESSAGE_RES_BODY, queue, queue_idx, HTTP_RESPONSE, raw_body, &decompress_body);
session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg);
if (decompress_body.iov_base != NULL)
{
- http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_ZIP_BYTES, raw_body.iov_len);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_ZIP_BYTES, raw_body->iov_len);
http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_UNZIP_BYTES, decompress_body.iov_len);
}
}
@@ -457,8 +431,7 @@ static int load_http_decoder_config(const char *cfg_path,
FILE *fp = fopen(cfg_path, "r");
if (NULL == fp)
{
- fprintf(stderr, "[%s:%d]Can't open config file:%s",
- __FUNCTION__, __LINE__, cfg_path);
+ fprintf(stderr, "[%s]Can't open config file:%s", __FUNCTION__, cfg_path);
return -1;
}
@@ -471,8 +444,7 @@ static int load_http_decoder_config(const char *cfg_path,
toml_table_t *basic_sec_tbl = toml_table_in(root, "basic");
if (NULL == basic_sec_tbl)
{
- fprintf(stderr, "[%s:%d]config file:%s has no key: [basic]",
- __FUNCTION__, __LINE__, cfg_path);
+ fprintf(stderr, "[%s]config file:%s has no key: [basic]", __FUNCTION__, cfg_path);
toml_free(root);
return -1;
}
@@ -537,67 +509,6 @@ static int load_http_decoder_config(const char *cfg_path,
return ret;
}
-static int http_msg_get_request_header(const struct http_message *msg, const char *name, size_t name_len,
- struct http_header_field *hdr_result)
-{
- const struct http_decoder_half_data *req_data =
- msg->ref_queue->array[msg->queue_index].req_data;
- return http_decoder_half_data_get_header(req_data, name, name_len, hdr_result);
-}
-
-static int http_msg_get_response_header(const struct http_message *msg, const char *name, size_t name_len,
- struct http_header_field *hdr_result)
-{
- const struct http_decoder_half_data *res_data =
- msg->ref_queue->array[msg->queue_index].res_data;
- return http_decoder_half_data_get_header(res_data, name, name_len, hdr_result);
-}
-
-static int http_msg_request_header_next(const struct http_message *msg,
- struct http_header_field *hdr)
-{
- const struct http_decoder_half_data *req_data =
- msg->ref_queue->array[msg->queue_index].req_data;
- return http_decoder_half_data_iter_header((struct http_decoder_half_data *)req_data, hdr);
-}
-
-static int http_msg_response_header_next(const struct http_message *msg, struct http_header_field *hdr)
-{
- const struct http_decoder_half_data *res_data =
- msg->ref_queue->array[msg->queue_index].res_data;
- return http_decoder_half_data_iter_header((struct http_decoder_half_data *)res_data, hdr);
-}
-
-#if 0
-static int http_msg_get_request_raw_body(const struct http_message *msg, hstring *body)
-{
- const struct http_decoder_half_data *req_data =
- msg->ref_queue->array[msg->queue_index].req_data;
- return http_decoder_half_data_get_raw_body(req_data, body);
-}
-
-static int http_msg_get_response_raw_body(const struct http_message *msg, hstring *body)
-{
- const struct http_decoder_half_data *res_data =
- msg->ref_queue->array[msg->queue_index].res_data;
- return http_decoder_half_data_get_raw_body(res_data, body);
-}
-
-static int http_msg_get_request_decompress_body(const struct http_message *msg, hstring *body)
-{
- const struct http_decoder_half_data *req_data =
- msg->ref_queue->array[msg->queue_index].req_data;
- return http_decoder_half_data_get_decompress_body(req_data, body);
-}
-
-static int http_msg_get_response_decompress_body(const struct http_message *msg, hstring *body)
-{
- const struct http_decoder_half_data *res_data =
- msg->ref_queue->array[msg->queue_index].res_data;
- return http_decoder_half_data_get_decompress_body(res_data, body);
-}
-#endif
-
static struct http_decoder_exdata *httpd_session_exdata_new(struct session *sess, struct http_decoder_env *httpd_env,
long long req_start_seq, long long res_start_seq)
{
@@ -688,6 +599,7 @@ extern "C"
{
http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_STAT_PARSE_ERR, 1);
stellar_session_plugin_dettach_current_session(sess);
+ return;
}
}
@@ -920,132 +832,84 @@ extern "C"
return msg->type;
}
- void http_message_get0_request_line(const struct http_message *msg,
- struct http_request_line *line)
+ const struct http_request_line *http_message_get0_request_line(const struct http_message *msg)
{
- if (unlikely(NULL == msg || msg->type != HTTP_MESSAGE_REQ_LINE))
+ if (unlikely(NULL == msg || (msg->type != HTTP_MESSAGE_REQ_LINE_HEADERS)))
{
- if (line)
- {
- line->method = NULL;
- line->uri = NULL;
- line->version = NULL;
- }
- return;
+ return NULL;
}
assert(msg->ref_queue);
assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- struct http_decoder_half_data *req_data =
- msg->ref_queue->array[msg->queue_index].req_data;
+ struct http_decoder_half_data *req_data = msg->ref_queue->array[msg->queue_index].req_data;
- http_decoder_half_data_get_request_line(req_data, line);
+ return http_decoder_half_data_get_request_line(req_data);
}
- void http_message_get0_response_line(const struct http_message *msg,
- struct http_response_line *line)
+ const struct http_response_line *http_message_get0_response_line(const struct http_message *msg)
{
- if (unlikely(NULL == msg || msg->type != HTTP_MESSAGE_RES_LINE))
+ if (unlikely(NULL == msg || (msg->type != HTTP_MESSAGE_RES_LINE_HEADERS)))
{
- if (line)
- {
- line->version = NULL;
- line->status = NULL;
- }
- return;
+ return NULL;
}
assert(msg->ref_queue);
assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- struct http_decoder_half_data *res_data =
- msg->ref_queue->array[msg->queue_index].res_data;
-
- http_decoder_half_data_get_response_line(res_data, line);
+ struct http_decoder_half_data *res_data = msg->ref_queue->array[msg->queue_index].res_data;
+ return http_decoder_half_data_get_response_line(res_data);
}
- void http_message_get0_header(const struct http_message *msg, const char *name, size_t name_len,
- struct http_header_field *hdr_result)
+ const struct http_header_field *http_message_get0_header(const struct http_message *msg, const char *field_name, size_t field_name_len)
+ // void http_message_get0_header(const struct http_message *msg, const char *name, size_t name_len, struct http_header_field *hdr_result)
{
- int ret = -1;
- if (unlikely(NULL == msg || NULL == name || 0 == name_len))
+ if (unlikely(NULL == msg || NULL == field_name || 0 == field_name_len))
{
- goto fail;
+ return NULL;
}
assert(msg->ref_queue);
assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- if (HTTP_MESSAGE_REQ_HEADER == msg->type)
+ const struct http_decoder_half_data *half_data = NULL;
+ const struct http_header_field *expect_header = NULL;
+ if (HTTP_MESSAGE_REQ_LINE_HEADERS == msg->type)
{
- ret = http_msg_get_request_header(msg, name, name_len, hdr_result);
+ half_data = msg->ref_queue->array[msg->queue_index].req_data;
+ expect_header = http_half_get_header_field(half_data, field_name, field_name_len);
}
- else if (HTTP_MESSAGE_RES_HEADER == msg->type)
+ else if (HTTP_MESSAGE_RES_LINE_HEADERS == msg->type)
{
- ret = http_msg_get_response_header(msg, name, name_len, hdr_result);
+ half_data = msg->ref_queue->array[msg->queue_index].res_data;
+ expect_header = http_half_get_header_field(half_data, field_name, field_name_len);
}
- if (ret >= 0)
- {
- return;
- }
- fail:
- if (hdr_result)
- {
- hdr_result->name = NULL;
- hdr_result->value = NULL;
- }
- return;
- }
- int http_message_get0_next_header(const struct http_message *msg, struct http_header_field *header)
- {
- int ret = 1;
- if (unlikely(NULL == msg))
- {
- goto fail;
- }
- assert(msg->ref_queue);
- assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- if (HTTP_MESSAGE_REQ_HEADER == msg->type)
- {
- ret = http_msg_request_header_next(msg, header);
- }
- else if (HTTP_MESSAGE_RES_HEADER == msg->type)
- {
- ret = http_msg_response_header_next(msg, header);
- }
- if (ret < 0)
- {
- goto fail;
- }
- return 0;
- fail:
- if (header)
- {
- header->name = NULL;
- header->value = NULL;
- }
- return -1;
+ return expect_header;
}
- int http_message_reset_header_iter(struct http_message *msg)
+ const struct http_header_field *http_message_get0_next_header(const struct http_message *msg, const struct http_header_field *cur_header)
+ // int http_message_get0_next_header(const struct http_message *msg, struct http_header_field *header)
{
if (unlikely(NULL == msg))
{
- return -1;
+ return NULL;
}
assert(msg->ref_queue);
assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- if (HTTP_MESSAGE_REQ_HEADER == msg->type)
+ const struct http_decoder_half_data *half_data = NULL;
+ const struct http_header_field *next_header = NULL;
+
+ if (HTTP_MESSAGE_REQ_LINE_HEADERS == msg->type)
{
- struct http_decoder_half_data *req_data =
- msg->ref_queue->array[msg->queue_index].req_data;
- return http_decoder_half_data_reset_header_iter(req_data);
+ half_data = msg->ref_queue->array[msg->queue_index].req_data;
+ // ret = http_msg_request_header_next(msg, header);
+ next_header = http_half_get_next_header_field(half_data, cur_header);
}
- else if (HTTP_MESSAGE_RES_HEADER == msg->type)
+ else if (HTTP_MESSAGE_RES_LINE_HEADERS == msg->type)
{
- struct http_decoder_half_data *res_data =
- msg->ref_queue->array[msg->queue_index].res_data;
- return http_decoder_half_data_reset_header_iter(res_data);
+ half_data = msg->ref_queue->array[msg->queue_index].res_data;
+ next_header = http_half_get_next_header_field(half_data, cur_header);
+ // ret = http_msg_response_header_next(msg, header);
}
- return -1;
+
+ return next_header;
}
void http_message_get0_uncompressed_body(const struct http_message *msg, const char **body_ptr, size_t *body_len)
@@ -1073,8 +937,6 @@ extern "C"
void http_message_get0_decompressed_body(const struct http_message *msg, const char **dec_body_ptr, size_t *dec_body_len)
{
- enum http_content_encoding ecode = HTTP_CONTENT_ENCODING_NONE;
- struct http_decoder_half_data *ref_data = NULL;
if (unlikely(NULL == msg))
{
goto fail;
@@ -1087,31 +949,7 @@ extern "C"
*dec_body_len = msg->decompress_payload.iov_len;
return;
}
- /**
- * @brief If the body hasn't been compressed, same as http_message_get0_uncompressed_body().
- *
- */
-
- if (HTTP_MESSAGE_REQ_BODY_START == msg->type || HTTP_MESSAGE_REQ_BODY == msg->type || HTTP_MESSAGE_REQ_BODY_END == msg->type)
- {
- ref_data = msg->ref_queue->array[msg->queue_index].req_data;
- }
- else if (HTTP_MESSAGE_RES_BODY_START == msg->type || HTTP_MESSAGE_RES_BODY == msg->type || HTTP_MESSAGE_RES_BODY_END == msg->type)
- {
- ref_data = msg->ref_queue->array[msg->queue_index].res_data;
- }
- ecode = http_half_data_get_content_encoding(ref_data);
- if (ref_data != NULL && HTTP_CONTENT_ENCODING_NONE != ecode)
- {
- goto fail;
- }
- if (msg->raw_payload.iov_base != NULL && msg->raw_payload.iov_len != 0)
- {
- *dec_body_ptr = msg->raw_payload.iov_base;
- *dec_body_len = msg->raw_payload.iov_len;
- }
- return;
fail:
if (dec_body_ptr)
{
@@ -1147,39 +985,7 @@ extern "C"
}
return;
}
-#if 0
- void http_message_decoded_url_get0(const struct http_message *msg, struct iovec *url)
- {
- if (unlikely(NULL == msg))
- {
- if (url)
- {
- url->iov_base = NULL;
- url->iov_len = 0;
- }
- return;
- }
- assert(msg->ref_queue);
- assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- struct http_decoder_half_data *req_data =
- msg->ref_queue->array[msg->queue_index].req_data;
-
- if (http_half_data_get_decode_url(req_data, url) < 0)
- {
- goto fail;
- }
- return;
-
- fail:
- if (url)
- {
- url->iov_base = NULL;
- url->iov_len = 0;
- }
- return;
- }
-#endif
int http_message_get_transaction_seq(const struct http_message *msg)
{
if (unlikely(NULL == msg))
diff --git a/decoders/http/http_decoder_half.c b/decoders/http/http_decoder_half.c
index 70991c6..562dbdc 100644
--- a/decoders/http/http_decoder_half.c
+++ b/decoders/http/http_decoder_half.c
@@ -4,6 +4,7 @@
#include <arpa/inet.h>
#include "http_decoder_private.h"
#include "llhttp.h"
+#include "stellar/session.h"
#include "uthash/utlist.h"
struct http_decompress_buffer
@@ -13,30 +14,56 @@ struct http_decompress_buffer
struct http_decompress_buffer *next, *prev;
};
-struct http_decoder_half_data
+struct http_header_field_inner
{
- struct http_decoder_table *table;
+ struct http_header_field field;
+ uint8_t name_is_dup;
+ uint8_t value_is_dup;
+ uint8_t is_completed; /* on_header_value_complete() */
+ struct http_header_field_inner *next, *prev;
+};
- int major_version;
- int minor_version;
- int status_code;
+struct http_request_line_inner
+{
+ struct http_request_line req_line;
+ uint8_t method_is_dup;
+ uint8_t uri_is_dup;
+ uint8_t version_is_dup;
+ uint8_t is_completed; // Including method, uri and version
+};
- enum http_event state;
+struct http_response_line_inner
+{
+ struct http_response_line res_line;
+ uint8_t version_is_dup;
+ uint8_t status_is_dup;
+ uint8_t is_completed; // Including version and status
+};
+struct http_decoder_half_data
+{
+ enum flow_type flow_dir;
+ enum http_event state;
enum http_content_encoding content_encoding;
struct http_content_decompress *decompress;
-#if 0
- char *ref_decompress_body;
- size_t decompress_body_len;
-#else
+ hstring raw_body;
struct http_decompress_buffer *decompress_buffer_list;
-#endif
- int joint_url_complete;
- int url_is_encoded;
// http://<host>[:<port>]/<path>?<searchpart>
hstring joint_url;
- hstring decoded_url;
long long transaction_index;
+ union
+ {
+ struct http_request_line_inner req_line_inner;
+ struct http_response_line_inner res_line_inner;
+ };
+ struct http_header_field_inner *filed_list;
+
+ struct http_header_field_inner *tmp_parsing_header; // in In processing but not completed
+ union
+ {
+ struct http_request_line_inner req_line_inner;
+ struct http_response_line_inner res_line_inner;
+ } tmp_parsing_line; // in In processing but not completed
};
struct http_decoder_half
@@ -46,40 +73,232 @@ struct http_decoder_half
enum llhttp_errno error;
int decompress_switch;
struct http_decoder_env *httpd_env;
-
- // uint8_t is_request_flow;
enum http_event event;
http_event_cb *http_ev_cb;
struct http_event_context *http_ev_ctx;
-
- struct http_decoder_half_data *ref_data;
-
+ struct http_decoder_half_data *ref_data; /* pointer to current half_data on_message_begin */
long long trans_counter;
long long err_counter;
long long transaction_seq; // accumulated
-
const char *data;
int data_len;
};
-// #define HTTP_DECODER_DEBUG
-#ifdef HTTP_DECODER_DEBUG
-static void printf_debug_info(const char *desc, const char *at, size_t length)
+hstring *http_half_get_raw_body(struct http_decoder_half_data *data)
+{
+ return &data->raw_body;
+}
+
+static void http_half_append_string(const char *at, size_t length, char **old_str, size_t *old_str_len, int old_str_is_dup)
+{
+ size_t raw_len = *old_str_len;
+ char *append_str = CALLOC(char, raw_len + length);
+ memcpy(append_str, *old_str, raw_len);
+ memcpy(append_str + raw_len, at, length);
+
+ if (old_str_is_dup)
+ {
+ FREE(*old_str);
+ }
+ *old_str = append_str;
+ *old_str_len = raw_len + length;
+}
+
+static void http_half_append_req_method(struct http_decoder_half_data *data, const char *at, size_t length)
+{
+ /* first time use reference to raw packet */
+ if (NULL == data->tmp_parsing_line.req_line_inner.req_line.method)
+ {
+ data->tmp_parsing_line.req_line_inner.req_line.method = at;
+ data->tmp_parsing_line.req_line_inner.req_line.method_len = length;
+ data->tmp_parsing_line.req_line_inner.method_is_dup = 0;
+ }
+ else
+ {
+ http_half_append_string(at, length, (char **)&data->tmp_parsing_line.req_line_inner.req_line.method,
+ &data->tmp_parsing_line.req_line_inner.req_line.method_len, data->tmp_parsing_line.req_line_inner.method_is_dup);
+ data->tmp_parsing_line.req_line_inner.method_is_dup = 1;
+ }
+}
+
+static void http_half_append_req_uri(struct http_decoder_half_data *data, const char *at, size_t length)
+{
+ /* first time use reference to raw packet */
+ if (NULL == data->tmp_parsing_line.req_line_inner.req_line.uri)
+ {
+ data->tmp_parsing_line.req_line_inner.req_line.uri = at;
+ data->tmp_parsing_line.req_line_inner.req_line.uri_len = length;
+ data->tmp_parsing_line.req_line_inner.uri_is_dup = 0;
+ }
+ else
+ {
+ http_half_append_string(at, length, (char **)&data->tmp_parsing_line.req_line_inner.req_line.uri,
+ &data->tmp_parsing_line.req_line_inner.req_line.uri_len, data->tmp_parsing_line.req_line_inner.uri_is_dup);
+ data->tmp_parsing_line.req_line_inner.uri_is_dup = 1;
+ }
+}
+
+static void http_half_append_req_version(struct http_request_line_inner *req_line_inner, const char *at, size_t length)
+{
+ if (NULL == req_line_inner->req_line.version)
+ {
+ req_line_inner->req_line.version = at;
+ req_line_inner->req_line.version_len = length;
+ req_line_inner->version_is_dup = 0;
+ }
+ else
+ {
+ http_half_append_string(at, length, (char **)&req_line_inner->req_line.version,
+ &req_line_inner->req_line.version_len, req_line_inner->version_is_dup);
+ req_line_inner->version_is_dup = 1;
+ }
+}
+
+static void http_half_append_res_version(struct http_response_line_inner *res_line_inner, const char *at, size_t length)
+{
+ if (NULL == res_line_inner->res_line.version)
+ {
+ res_line_inner->res_line.version = at;
+ res_line_inner->res_line.version_len = length;
+ res_line_inner->version_is_dup = 0;
+ }
+ else
+ {
+ http_half_append_string(at, length, (char **)&res_line_inner->res_line.version,
+ &res_line_inner->res_line.version_len, res_line_inner->version_is_dup);
+ res_line_inner->version_is_dup = 1;
+ }
+}
+
+static void http_half_append_version(struct http_decoder_half_data *data, const char *at, size_t length)
{
- if (at)
+ if (FLOW_TYPE_C2S == data->flow_dir)
{
- char *temp = http_safe_dup(at, length);
- printf("HTTP PARSER STAGE: %s: %s\n", desc, temp);
- FREE(temp);
+ http_half_append_req_version(&data->tmp_parsing_line.req_line_inner, at, length);
}
else
{
- printf("HTTP PARSER STAGE: %s\n", desc);
+ http_half_append_res_version(&data->tmp_parsing_line.res_line_inner, at, length);
}
}
-#else
-#define printf_debug_info(desc, at, length)
-#endif
+
+static void http_half_append_version_integer(struct http_decoder_half_data *data, int major, int minor)
+{
+ if (FLOW_TYPE_C2S == data->flow_dir)
+ {
+ data->tmp_parsing_line.req_line_inner.req_line.major_version = major;
+ data->tmp_parsing_line.req_line_inner.req_line.minor_version = minor;
+ }
+ else
+ {
+ data->tmp_parsing_line.res_line_inner.res_line.major_version = major;
+ data->tmp_parsing_line.res_line_inner.res_line.minor_version = minor;
+ }
+}
+
+static void http_half_append_res_status(struct http_decoder_half_data *data, const char *at, size_t length)
+{
+ struct http_response_line_inner *res_line_inner = &data->tmp_parsing_line.res_line_inner;
+ if (NULL == res_line_inner->res_line.status)
+ {
+ res_line_inner->res_line.status = at;
+ res_line_inner->res_line.status_len = length;
+ res_line_inner->status_is_dup = 0;
+ }
+ else
+ {
+ http_half_append_string(at, length, (char **)&res_line_inner->res_line.status,
+ &res_line_inner->res_line.status_len, res_line_inner->status_is_dup);
+ res_line_inner->status_is_dup = 1;
+ }
+}
+
+static void http_half_append_header_name(struct http_decoder_half_data *data, const char *at, size_t length)
+{
+ if (data->tmp_parsing_header == NULL)
+ {
+ data->tmp_parsing_header = CALLOC(struct http_header_field_inner, 1);
+ }
+ /* first time use reference to raw packet */
+ if (NULL == data->tmp_parsing_header->field.name || 0 == data->tmp_parsing_header->field.name_len)
+ {
+ data->tmp_parsing_header->field.name = at;
+ data->tmp_parsing_header->field.name_len = length;
+ data->tmp_parsing_header->name_is_dup = 0;
+ }
+ else
+ {
+ http_half_append_string(at, length, (char **)&data->tmp_parsing_header->field.name,
+ &data->tmp_parsing_header->field.name_len, data->tmp_parsing_header->name_is_dup);
+ data->tmp_parsing_header->name_is_dup = 1;
+ }
+}
+
+static void http_half_append_header_value(struct http_decoder_half_data *data, const char *at, size_t length)
+{
+ assert(data->tmp_parsing_header);
+ /* first time use reference to raw packet */
+ if (NULL == data->tmp_parsing_header->field.value || 0 == data->tmp_parsing_header->field.value_len)
+ {
+ data->tmp_parsing_header->field.value = at;
+ data->tmp_parsing_header->field.value_len = length;
+ data->tmp_parsing_header->value_is_dup = 0;
+ }
+ else
+ {
+ http_half_append_string(at, length, (char **)&data->tmp_parsing_header->field.value,
+ &data->tmp_parsing_header->field.value_len, data->tmp_parsing_header->value_is_dup);
+ data->tmp_parsing_header->value_is_dup = 1;
+ }
+}
+
+static void http_half_set_complete_headers(struct http_decoder_half_data *data)
+{
+ /* move ownership to field_list */
+ DL_APPEND(data->filed_list, data->tmp_parsing_header);
+ data->tmp_parsing_header = NULL;
+}
+
+static void http_half_set_completed_req_line(struct http_decoder_half_data *data)
+{
+ memcpy(&data->req_line_inner, &data->tmp_parsing_line.req_line_inner, sizeof(struct http_request_line_inner));
+ data->req_line_inner.is_completed = 1;
+ memset(&data->tmp_parsing_line.req_line_inner, 0, sizeof(struct http_request_line_inner));
+}
+
+static void http_half_set_completed_res_line(struct http_decoder_half_data *data)
+{
+ memcpy(&data->res_line_inner, &data->tmp_parsing_line.res_line_inner, sizeof(struct http_response_line_inner));
+ data->res_line_inner.is_completed = 1;
+ memset(&data->tmp_parsing_line.res_line_inner, 0, sizeof(struct http_response_line_inner));
+}
+
+const struct http_header_field *http_half_get_next_header_field(const struct http_decoder_half_data *half_data, const struct http_header_field *current_header)
+{
+ if (NULL == current_header)
+ { // first time
+ return &half_data->filed_list->field;
+ }
+ const struct http_header_field_inner *inner_fidld = container_of(current_header, struct http_header_field_inner, field);
+ if (inner_fidld->next == half_data->filed_list)
+ { // the last item
+ return NULL;
+ }
+ return &inner_fidld->next->field;
+}
+
+const struct http_header_field *http_half_get_header_field(const struct http_decoder_half_data *half_data, const char *field_name, size_t field_name_len)
+{
+ struct http_header_field_inner *el;
+ DL_FOREACH(half_data->filed_list, el)
+ {
+ if (http_strncasecmp_safe(el->field.name, field_name, el->field.name_len, field_name_len) == 0)
+ {
+ return &el->field;
+ }
+ }
+ return NULL;
+}
void http_half_decompress_buffer_free(struct http_decoder_half_data *data, hstring *decompress_body)
{
@@ -125,19 +344,15 @@ void http_half_get_lastest_decompress_buffer(struct http_decoder_half_data *data
static void http_decoder_half_data_decompress(struct http_decoder_half_data *data)
{
assert(data);
-
if (data->content_encoding == HTTP_CONTENT_ENCODING_NONE)
{
return;
}
-
- hstring raw_body = {};
- http_decoder_table_get_body(data->table, (char **)&raw_body.iov_base, &raw_body.iov_len);
- if (raw_body.iov_base == NULL || raw_body.iov_len == 0)
+ hstring *raw_body = &data->raw_body;
+ if (raw_body->iov_base == NULL || raw_body->iov_len == 0)
{
return;
}
-
if (NULL == data->decompress)
{
data->decompress = http_content_decompress_create(data->content_encoding);
@@ -146,12 +361,9 @@ 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,
- &local_outdata,
- &local_outdata_len) == -1)
+ if (http_content_decompress_write(data->decompress, (char *)raw_body->iov_base,
+ raw_body->iov_len, &local_outdata, &local_outdata_len) == -1)
{
- // log error
http_content_decompress_destroy(data->decompress);
data->decompress = NULL;
return;
@@ -171,8 +383,6 @@ static void http_decoder_half_data_decompress(struct http_decoder_half_data *dat
/* Possible return values 0, -1, `HPE_PAUSED` */
static int on_message_begin(llhttp_t *http)
{
- printf_debug_info("on_message_begin", NULL, 0);
-
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
@@ -186,7 +396,6 @@ static int on_message_begin(llhttp_t *http)
}
half->ref_data = NULL;
-
assert(half->http_ev_cb != NULL);
half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env); // http_event_handler()
@@ -197,8 +406,6 @@ static int on_message_begin(llhttp_t *http)
static int on_message_complete(llhttp_t *http)
{
- printf_debug_info("on_message_complete", NULL, 0);
-
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
@@ -234,224 +441,125 @@ static int on_message_complete(llhttp_t *http)
return 0;
}
-static int on_reset(llhttp_t *http __attribute__((unused)))
-{
- printf_debug_info("on_reset", NULL, 0);
-
- return 0;
-}
-
-static inline int is_line_crlf(struct http_decoder_half *half)
+static int on_method(llhttp_t *http, const char *at, size_t length)
{
- const char *chr_r = (char *)memrchr(half->data, '\r', half->data_len);
- const char *chr_n = (char *)memrchr(half->data, '\n', half->data_len);
- if (chr_r && chr_n && (chr_r + 1 == chr_n))
+ if (0 == length)
{
- return 1;
+ return 0;
}
- return 0;
-}
-
-static int on_method(llhttp_t *http, const char *at, size_t length)
-{
- printf_debug_info("on_method", at, length);
-
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
-
- http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_METHOD, at, length);
+ http_half_append_req_method(half->ref_data, at, length);
return 0;
}
-/* Information-only callbacks, return value is ignored */
static int on_method_complete(llhttp_t *http)
{
- printf_debug_info("on_method_complete", NULL, 0);
-
- struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
- assert(half);
-
- if (is_line_crlf(half) == 0)
- {
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_METHOD);
- }
-
- http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_METHOD);
-
+ (void)http;
return 0;
}
/* Possible return values 0, -1, HPE_USER */
static int on_uri(llhttp_t *http, const char *at, size_t length)
{
- printf_debug_info("on_uri", at, length);
-
+ if (0 == length)
+ {
+ return 0;
+ }
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
- http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_URI, at, length);
+ http_half_append_req_uri(half->ref_data, at, length);
return 0;
}
-static void http_decoder_cached_portion_url(struct http_decoder_half *half, const hstring *uri_result)
-{
- struct http_decoder_half_data *ref_data = half->ref_data;
- int uri_skip_len = 0;
-
- if ((uri_result->iov_len) > 7 && (strncasecmp("http://", (char *)uri_result->iov_base, 7) == 0)) // absolute URI
- {
- uri_skip_len = strlen("http://");
- ref_data->joint_url_complete = 1;
- }
- else
- {
- ref_data->joint_url_complete = 0;
- }
-
- ref_data->joint_url.iov_len = uri_result->iov_len - uri_skip_len;
- ref_data->joint_url.iov_base = MEMPOOL_CALLOC(half->http_ev_ctx->ref_mempool, char, ref_data->joint_url.iov_len);
- memcpy(ref_data->joint_url.iov_base, (char *)uri_result->iov_base + uri_skip_len, ref_data->joint_url.iov_len);
-}
-
/* Information-only callbacks, return value is ignored */
static int on_uri_complete(llhttp_t *http)
{
- printf_debug_info("on_uri_complete", NULL, 0);
-
- struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
- assert(half);
-
- if (is_line_crlf(half) == 0)
- {
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_URI);
- }
-
- http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_URI);
-
- hstring uri_result = {};
- http_decoder_table_get_uri(half->ref_data->table, (char **)&uri_result.iov_base, &uri_result.iov_len);
- assert(uri_result.iov_base);
- http_decoder_cached_portion_url(half, &uri_result);
-
+ (void)http;
return 0;
}
/* Possible return values 0, -1, HPE_USER */
static int on_version(llhttp_t *http, const char *at, size_t length)
{
- printf_debug_info("on_version", at, length);
-
+ if (0 == length)
+ {
+ return 0;
+ }
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
+ http_half_append_version(half->ref_data, at, length);
- http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_VERSION, at, length);
return 0;
}
/* Information-only callbacks, return value is ignored */
static int on_version_complete(llhttp_t *http)
{
- printf_debug_info("on_version_complete", NULL, 0);
-
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
- if (is_line_crlf(half) == 0)
- {
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_VERSION);
- }
-
- http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_VERSION);
-
- half->ref_data->major_version = llhttp_get_http_major(&half->parser);
- half->ref_data->minor_version = llhttp_get_http_minor(&half->parser);
+ http_half_append_version_integer(half->ref_data, llhttp_get_http_major(&half->parser), llhttp_get_http_minor(&half->parser));
if (half->parser.type == HTTP_REQUEST)
{
- half->event = HTTP_EVENT_REQ_LINE;
- if (half->http_ev_cb) // http_event_handler()
- {
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
- }
+ http_half_set_completed_req_line(half->ref_data);
}
-
return 0;
}
/* Possible return values 0, -1, HPE_USER */
static int on_status(llhttp_t *http, const char *at, size_t length)
{
- printf_debug_info("on_status", at, length);
-
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
-
- http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_STATUS, at, length);
+ http_half_append_res_status(half->ref_data, at, length);
return 0;
}
/* Information-only callbacks, return value is ignored */
static int on_status_complete(llhttp_t *http)
{
- printf_debug_info("on_status_complete", NULL, 0);
-
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
- if (is_line_crlf(half) == 0)
- {
- 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);
-
- if (half->parser.type == HTTP_RESPONSE)
- {
- half->event = HTTP_EVENT_RES_LINE;
- if (half->http_ev_cb != NULL) // http_event_handler()
- {
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
- }
- }
-
+ half->ref_data->tmp_parsing_line.res_line_inner.res_line.status_code = llhttp_get_status_code(&half->parser);
+ http_half_set_completed_res_line(half->ref_data);
return 0;
}
/* Possible return values 0, -1, HPE_USER */
static int on_header_field(llhttp_t *http, const char *at, size_t length)
{
- printf_debug_info("on_header_field", at, length);
-
+ if (0 == length)
+ {
+ return 0;
+ }
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
-
- http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_HDRKEY, at, length);
+ http_half_append_header_name(half->ref_data, at, length);
return 0;
}
/* Information-only callbacks, return value is ignored */
static int on_header_field_complete(llhttp_t *http)
{
- printf_debug_info("on_header_field_complete", NULL, 0);
-
- struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
- assert(half);
-
- http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_HDRKEY);
-
+ (void)http;
return 0;
}
/* Possible return values 0, -1, HPE_USER */
static int on_header_value(llhttp_t *http, const char *at, size_t length)
{
- printf_debug_info("on_header_value", at, length);
-
+ if (0 == length)
+ {
+ return 0;
+ }
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
-
- http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_HDRVAL, at, length);
+ http_half_append_header_value(half->ref_data, at, length);
+ // http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_HDRVAL, at, length);
return 0;
}
@@ -459,33 +567,9 @@ static int on_header_value(llhttp_t *http, const char *at, size_t length)
/* Information-only callbacks, return value is ignored */
static int on_header_value_complete(llhttp_t *http)
{
- printf_debug_info("on_header_value_complete", NULL, 0);
-
+ (void)http;
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
- assert(half);
-
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_HDRKEY) ==
- STRING_STATE_CACHE)
- {
- http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_HDRKEY);
- }
-
- http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_HDRVAL);
-
- if (half->ref_data->content_encoding == HTTP_CONTENT_ENCODING_NONE)
- {
- struct http_header_field http_hdr = {};
-
- if (http_decoder_table_get_header(half->ref_data->table, (char *)"Content-Encoding", 16, &http_hdr) == 0)
- {
- half->ref_data->content_encoding = http_content_encoding_str2int(http_hdr.value, http_hdr.value_len);
- }
- }
-
- if (http->type == HTTP_REQUEST)
- {
- http_decoder_get_host_feed_url(half);
- }
+ http_half_set_complete_headers(half->ref_data);
return 0;
}
@@ -495,8 +579,6 @@ static int on_header_value_complete(llhttp_t *http)
*/
static int on_chunk_header(llhttp_t *http __attribute__((unused)))
{
- printf_debug_info("on_chunk_header", NULL, 0);
-
return 0;
}
@@ -506,8 +588,6 @@ static int on_chunk_header(llhttp_t *http __attribute__((unused)))
*/
static int on_chunk_header_complete(llhttp_t *http __attribute__((unused)))
{
- printf_debug_info("on_chunk_header_complete", NULL, 0);
-
return 0;
}
@@ -519,13 +599,11 @@ static int on_chunk_header_complete(llhttp_t *http __attribute__((unused)))
*/
static int on_headers_complete(llhttp_t *http)
{
- printf_debug_info("on_headers_complete", NULL, 0);
-
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
assert(half->ref_data);
- http_decoder_table_set_header_complete(half->ref_data->table);
+ // http_decoder_table_set_header_complete(half->ref_data->table);
if (half->parser.type == HTTP_REQUEST)
{
@@ -536,18 +614,22 @@ static int on_headers_complete(llhttp_t *http)
half->event = HTTP_EVENT_RES_HDR_END;
}
half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env); // http_event_handler()
-
return 0;
}
/* Possible return values 0, -1, HPE_USER */
static int on_body(llhttp_t *http, const char *at, size_t length)
{
- printf_debug_info("on_body", at, length);
-
+ if (0 == length)
+ {
+ return 0;
+ }
struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
+ half->ref_data->raw_body.iov_base = (void *)NULL;
+ half->ref_data->raw_body.iov_len = 0;
+
// trigger body_begin event
if (half->parser.type == HTTP_REQUEST)
{
@@ -566,17 +648,8 @@ static int on_body(llhttp_t *http, const char *at, size_t length)
}
}
- 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->ref_data->table, HTTP_ITEM_BODY, at, length);
- http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_BODY);
- }
+ half->ref_data->raw_body.iov_base = (void *)at;
+ half->ref_data->raw_body.iov_len = length;
if (1 == half->decompress_switch && half->ref_data->content_encoding != HTTP_CONTENT_ENCODING_NONE)
{
@@ -602,35 +675,25 @@ static void http_decoder_half_init(struct http_decoder_half *half, http_event_cb
llhttp_settings_init(&half->settings);
llhttp_init(&half->parser, type, &half->settings);
- // half->is_request_flow = (type == HTTP_REQUEST) ? 1 : 0;
half->settings.on_message_begin = on_message_begin;
half->settings.on_message_complete = on_message_complete;
- half->settings.on_reset = on_reset;
-
+ // half->settings.on_reset = on_reset;
half->settings.on_url = on_uri;
half->settings.on_url_complete = on_uri_complete;
-
half->settings.on_status = on_status;
half->settings.on_status_complete = on_status_complete;
-
half->settings.on_method = on_method;
half->settings.on_method_complete = on_method_complete;
-
half->settings.on_version = on_version;
half->settings.on_version_complete = on_version_complete;
-
half->settings.on_header_field = on_header_field;
half->settings.on_header_field_complete = on_header_field_complete;
-
half->settings.on_header_value = on_header_value;
half->settings.on_header_value_complete = on_header_value_complete;
-
half->settings.on_chunk_header = on_chunk_header;
half->settings.on_chunk_complete = on_chunk_header_complete;
-
half->settings.on_headers_complete = on_headers_complete;
half->settings.on_body = on_body;
-
half->error = HPE_OK;
half->http_ev_cb = http_ev_cb; // http_event_handler()
half->ref_data = NULL;
@@ -658,13 +721,11 @@ void http_decoder_half_free(nmx_pool_t *mempool, struct http_decoder_half *half)
{
return;
}
-
if (half->http_ev_ctx != NULL)
{
MEMPOOL_FREE(mempool, half->http_ev_ctx);
half->http_ev_ctx = NULL;
}
-
MEMPOOL_FREE(mempool, half);
}
@@ -673,149 +734,232 @@ void http_decoder_half_reinit(struct http_decoder_half *half,
nmx_pool_t *mempool, struct session *sess)
{
assert(half != NULL);
- 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;
}
-static void publish_message_for_parsed_header(struct http_decoder_half *half)
+static int http_half_is_headers_completed(struct http_decoder_half *half)
{
- if (0 == http_decoder_table_has_parsed_header(half->ref_data->table))
+ if (half->ref_data == NULL)
{
- return;
+ return 0;
}
if (half->parser.type == HTTP_REQUEST)
{
- half->event = HTTP_EVENT_REQ_HDR;
+ if ((int)half->event >= (int)HTTP_EVENT_REQ_HDR_END)
+ {
+ return 1;
+ }
}
else
{
- half->event = HTTP_EVENT_RES_HDR;
+ if ((int)half->event >= (int)HTTP_EVENT_RES_HDR_END)
+ {
+ return 1;
+ }
}
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env); // http_event_handler();
- return;
+ return 0;
}
-int http_decoder_half_parse(int proxy_enable, struct http_decoder_half *half, const char *data, size_t data_len)
+static void http_half_header_filed_dup_name(struct http_header_field_inner *el)
{
- assert(half && data);
-
- half->data = (const char *)data;
- half->data_len = data_len;
- half->error = llhttp_execute(&half->parser, data, data_len);
+ el->field.name = http_string_dup(el->field.name, el->field.name_len);
+ el->name_is_dup = 1;
+}
- int ret = 0;
- enum llhttp_type type = HTTP_BOTH;
+static void http_half_header_filed_dup_value(struct http_header_field_inner *el)
+{
+ el->field.value = http_string_dup(el->field.value, el->field.value_len);
+ el->value_is_dup = 1;
+}
- switch (half->error)
+/*
+ * save temporary data if line/headers is not completed.
+ */
+static void http_half_line_headers_cache(struct http_decoder_half *half)
+{
+ if (FLOW_TYPE_C2S == half->ref_data->flow_dir)
{
- case HPE_OK:
- break;
- case HPE_PAUSED:
- llhttp_resume(&half->parser);
- break;
- case HPE_PAUSED_UPGRADE:
- if (proxy_enable)
+ struct http_request_line_inner *req_inner;
+ if (half->ref_data->req_line_inner.is_completed)
{
- llhttp_resume_after_upgrade(&half->parser);
+ req_inner = &half->ref_data->req_line_inner;
+ }
+ else
+ {
+ req_inner = &half->ref_data->tmp_parsing_line.req_line_inner;
+ }
+ if (req_inner->method_is_dup == 0)
+ {
+ req_inner->req_line.method = http_string_dup(req_inner->req_line.method, req_inner->req_line.method_len);
+ req_inner->method_is_dup = 1;
+ }
+ if (req_inner->uri_is_dup == 0)
+ {
+ req_inner->req_line.uri = http_string_dup(req_inner->req_line.uri, req_inner->req_line.uri_len);
+ req_inner->uri_is_dup = 1;
+ }
+ if (req_inner->version_is_dup == 0)
+ {
+ req_inner->req_line.version = http_string_dup(req_inner->req_line.version, req_inner->req_line.version_len);
+ req_inner->version_is_dup = 1;
}
- ret = 0;
- break;
- default:
- type = (enum llhttp_type)half->parser.type;
- llhttp_init(&half->parser, type, &half->settings);
- ret = -1;
- break;
- }
-
- if (ret < 0)
- {
- // fprintf(stdout,
- // "llhttp_execute parse error: %s err_reason:%s\n",
- // llhttp_errno_name(half->error), half->parser.reason);
- return half->error;
}
-
- if (half->ref_data != NULL)
+ else
{
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_URI) == STRING_STATE_REFER)
+ struct http_response_line_inner *res_inner;
+ if (half->ref_data->res_line_inner.is_completed)
{
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_URI);
+ res_inner = &half->ref_data->res_line_inner;
}
-
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_STATUS) == STRING_STATE_REFER)
+ else
{
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_STATUS);
+ res_inner = &half->ref_data->tmp_parsing_line.res_line_inner;
}
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_METHOD) == STRING_STATE_REFER)
+ if (res_inner->status_is_dup == 0)
{
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_METHOD);
+ res_inner->res_line.status = http_string_dup(res_inner->res_line.status, res_inner->res_line.status_len);
+ res_inner->status_is_dup = 1;
}
-
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_VERSION) == STRING_STATE_REFER)
+ if (res_inner->version_is_dup == 0)
{
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_VERSION);
+ res_inner->res_line.version = http_string_dup(res_inner->res_line.version, res_inner->res_line.version_len);
+ res_inner->version_is_dup = 1;
}
+ }
- if (http_decoder_table_header_complete(half->ref_data->table))
+ /* copy completed headers if not dup */
+ struct http_header_field_inner *el, *tmp;
+ DL_FOREACH_SAFE(half->ref_data->filed_list, el, tmp)
+ {
+ if (el->name_is_dup == 0)
{
- http_decoder_table_reset_header_complete(half->ref_data->table);
+ http_half_header_filed_dup_name(el);
}
- else
+ if (el->value_is_dup == 0)
{
- // if headers are not completed with EOF \r\n\r\n, push the parsed headers so far
- publish_message_for_parsed_header(half);
+ http_half_header_filed_dup_value(el);
}
-
- enum string_state hdr_key_state =
- http_decoder_table_state(half->ref_data->table, HTTP_ITEM_HDRKEY);
- enum string_state hdr_val_state =
- http_decoder_table_state(half->ref_data->table, HTTP_ITEM_HDRVAL);
-
- /* Truncated in http header key
- For example http header k-v => User-Agent: Chrome
- case1:
- packet1: User- hdr_key_state == STRING_STATE_REFER
- packet2: Agent: Chrome
-
- case2:
- packet1: User-Agent: hdr_key_state == STRING_STATE_COMMIT
- hdr_val_state == STRING_STATE_INIT
- packet2: Chrome
- */
- if (hdr_key_state == STRING_STATE_REFER ||
- (hdr_key_state == STRING_STATE_COMMIT && hdr_val_state == STRING_STATE_INIT))
+ }
+ // copy in parsing stage header
+ if (half->ref_data->tmp_parsing_header)
+ {
+ if (half->ref_data->tmp_parsing_header->field.name && half->ref_data->tmp_parsing_header->name_is_dup == 0)
{
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_HDRKEY);
+ http_half_header_filed_dup_name(half->ref_data->tmp_parsing_header);
+ half->ref_data->tmp_parsing_header->name_is_dup = 1;
}
+ if (half->ref_data->tmp_parsing_header->field.value && half->ref_data->tmp_parsing_header->value_is_dup == 0)
+ {
+ http_half_header_filed_dup_value(half->ref_data->tmp_parsing_header);
+ half->ref_data->tmp_parsing_header->value_is_dup = 1;
+ }
+ }
+}
- /* Truncated in http header value
- For example http header k-v => User-Agent: Chrome
- packet1: User-Agent: Ch hdr_key_state == STRING_STATE_COMMIT
- hdr_val_state == STRING_STATE_REFER
-
- packet2: rome
- */
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_HDRVAL) == STRING_STATE_REFER)
+static void http_half_headers_free(struct http_header_field_inner **field_list_head)
+{
+ if (NULL == field_list_head || NULL == *field_list_head)
+ {
+ return;
+ }
+ struct http_header_field_inner *head = *field_list_head;
+ struct http_header_field_inner *el, *tmp;
+ DL_FOREACH_SAFE(head, el, tmp)
+ {
+ if (el->name_is_dup == 1)
{
- /* Header key should have been committed
- If it's not cached, cache it for next packet to use
- */
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_HDRKEY);
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_HDRVAL);
+ FREE(el->field.name);
}
+ if (el->value_is_dup == 1)
+ {
+ FREE(el->field.value);
+ }
+ FREE(el);
+ }
+ *field_list_head = NULL;
+}
+
+static void http_half_req_line_free(struct http_request_line_inner *req_inner)
+{
+ if (req_inner->method_is_dup == 1)
+ {
+ FREE(req_inner->req_line.method);
+ req_inner->method_is_dup = 0;
+ }
+ if (req_inner->uri_is_dup == 1)
+ {
+ FREE(req_inner->req_line.uri);
+ req_inner->uri_is_dup = 0;
+ }
+ if (req_inner->version_is_dup == 1)
+ {
+ FREE(req_inner->req_line.version);
+ req_inner->version_is_dup = 0;
+ }
+}
+
+static void http_half_res_line_free(struct http_response_line_inner *res_inner)
+{
+ if (res_inner->status_is_dup == 1)
+ {
+ FREE(res_inner->res_line.status);
+ res_inner->status_is_dup = 0;
+ }
+ if (res_inner->version_is_dup == 1)
+ {
+ FREE(res_inner->res_line.version);
+ res_inner->version_is_dup = 0;
+ }
+}
+
+void http_half_line_headers_free(struct http_decoder_half_data *ref_data)
+{
+ if (FLOW_TYPE_C2S == ref_data->flow_dir)
+ {
+ http_half_req_line_free(&ref_data->req_line_inner);
+ http_half_req_line_free(&ref_data->tmp_parsing_line.req_line_inner);
+ }
+ else
+ {
+ http_half_res_line_free(&ref_data->res_line_inner);
+ http_half_res_line_free(&ref_data->tmp_parsing_line.res_line_inner);
+ }
+ http_half_headers_free(&ref_data->filed_list);
+ http_half_headers_free(&ref_data->tmp_parsing_header);
+}
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_BODY) == STRING_STATE_REFER)
+int http_decoder_half_parse(int proxy_enable, struct http_decoder_half *half, const char *data, size_t data_len)
+{
+ assert(half && data);
+ half->data = (const char *)data;
+ half->data_len = data_len;
+ half->error = llhttp_execute(&half->parser, data, data_len);
+
+ switch (half->error)
+ {
+ case HPE_OK:
+ break;
+ case HPE_PAUSED:
+ llhttp_resume(&half->parser);
+ break;
+ case HPE_PAUSED_UPGRADE:
+ if (proxy_enable)
{
- http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_BODY);
+ llhttp_resume_after_upgrade(&half->parser);
}
+ break;
+ default:
+ return half->error;
+ break;
}
+ if (http_half_is_headers_completed(half) == 0)
+ {
+ http_half_line_headers_cache(half);
+ }
return 0;
}
@@ -825,30 +969,17 @@ long long http_decoder_half_trans_count(struct http_decoder_half *half)
{
return 0;
}
-
long long trans_cnt = half->trans_counter;
half->trans_counter = 0;
-
return trans_cnt;
}
-struct http_decoder_half_data *
-http_decoder_half_data_new(nmx_pool_t *mempool)
+struct http_decoder_half_data *http_decoder_half_data_new(nmx_pool_t *mempool, enum flow_type flow_dir)
{
- struct http_decoder_half_data *data =
- MEMPOOL_CALLOC(mempool, struct http_decoder_half_data, 1);
+ struct http_decoder_half_data *data = MEMPOOL_CALLOC(mempool, struct http_decoder_half_data, 1);
assert(data);
-
- data->table = http_decoder_table_new(mempool);
- assert(data->table);
-
- data->major_version = -1;
- data->minor_version = -1;
- data->status_code = -1;
-
+ data->flow_dir = flow_dir;
data->content_encoding = HTTP_CONTENT_ENCODING_NONE;
- // data->ref_decompress_body = NULL;
- // data->decompress_body_len = 0;
data->decompress_buffer_list = NULL;
return data;
}
@@ -878,13 +1009,6 @@ void http_decoder_half_data_free(nmx_pool_t *mempool, struct http_decoder_half_d
{
return;
}
-
- if (data->table != NULL)
- {
- http_decoder_table_free(data->table);
- data->table = NULL;
- }
-
if (data->decompress != NULL)
{
http_content_decompress_destroy(data->decompress);
@@ -895,115 +1019,29 @@ void http_decoder_half_data_free(nmx_pool_t *mempool, struct http_decoder_half_d
{
MEMPOOL_FREE(mempool, data->joint_url.iov_base);
data->joint_url.iov_base = NULL;
- data->joint_url_complete = 0;
}
http_decoder_half_decompress_buf_free(data);
+ http_half_line_headers_free(data);
MEMPOOL_FREE(mempool, data);
}
-int http_decoder_half_data_get_request_line(struct http_decoder_half_data *data,
- struct http_request_line *line)
-{
- http_decoder_table_get_method(data->table, &line->method, &line->method_len);
- http_decoder_table_get_uri(data->table, &line->uri, &line->uri_len);
- http_decoder_table_get_version(data->table, &line->version, &line->version_len);
-
- line->major_version = data->major_version;
- line->minor_version = data->minor_version;
-
- return 0;
-}
-
-int http_decoder_half_data_get_response_line(struct http_decoder_half_data *data,
- struct http_response_line *line)
-{
- http_decoder_table_get_version(data->table, &line->version, &line->version_len);
- http_decoder_table_get_status(data->table, &line->status, &line->status_len);
-
- line->major_version = data->major_version;
- line->minor_version = data->minor_version;
- line->status_code = data->status_code;
-
- return 0;
-}
-
-int http_decoder_half_data_get_header(const struct http_decoder_half_data *data,
- const char *name, size_t name_len,
- struct http_header_field *hdr_result)
-{
- return http_decoder_table_get_header(data->table, name, name_len, hdr_result);
-}
-
-int http_decoder_half_data_iter_header(struct http_decoder_half_data *data,
- struct http_header_field *header)
-{
- return http_decoder_table_iter_header((struct http_decoder_table *)data->table, header);
-}
-
-int http_decoder_half_data_reset_header_iter(struct http_decoder_half_data *req_data)
-{
- if (NULL == req_data)
- {
- return -1;
- }
- return http_decoder_table_reset_header_iter(req_data->table);
-}
-
-int http_decoder_half_data_has_parsed_header(struct http_decoder_half_data *data)
-{
- if (NULL == data)
- {
- return 0;
- }
- return http_decoder_table_has_parsed_header(data->table);
-}
-
-int http_decoder_half_data_get_raw_body(const struct http_decoder_half_data *data, const char **body, size_t *body_len)
+const struct http_request_line *http_decoder_half_data_get_request_line(struct http_decoder_half_data *data)
{
- if (NULL == data || NULL == body)
- {
- return -1;
- }
- return http_decoder_table_get_body(data->table, (char **)body, body_len);
+ return &data->req_line_inner.req_line;
}
-#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)
- {
- return http_decoder_table_get_body(data->table, body);
- }
- body->iov_base = data->ref_decompress_body;
- body->iov_len = data->decompress_body_len;
- return 0;
-}
-#endif
-
-void http_decoder_half_data_dump(struct http_decoder_half *half)
+const struct http_response_line *http_decoder_half_data_get_response_line(struct http_decoder_half_data *data)
{
- if (NULL == half || NULL == half->ref_data)
- {
- return;
- }
-
- http_decoder_table_dump(half->ref_data->table);
+ return &data->res_line_inner.res_line;
}
-static void using_session_addr_as_host(struct session *ref_session, struct http_header_field *host_result, nmx_pool_t *mempool)
+struct http_header_field *http_using_session_addr_without_host(struct session *ref_session, nmx_pool_t *mempool)
{
-#if 1 // in native steallar, can't get the tuple4 from the session yet!!!
+ struct http_header_field *host_result = MEMPOOL_CALLOC(mempool, struct http_header_field, 1);
struct httpd_session_addr ssaddr = {};
httpd_session_get_addr(ref_session, &ssaddr);
- if (ssaddr.ipver != 4 && ssaddr.ipver != 6)
- {
- host_result->value = MEMPOOL_CALLOC(mempool, char, 1);
- sprintf((char *)host_result->value, "%s", "");
- host_result->value_len = strlen((char *)host_result->value);
- return;
- }
-
char ip_string_buf[INET6_ADDRSTRLEN];
+
if (4 == ssaddr.ipver)
{
host_result->value = MEMPOOL_CALLOC(mempool, char, (INET_ADDRSTRLEN + 7) /* "ip:port" max length */);
@@ -1020,23 +1058,31 @@ static void using_session_addr_as_host(struct session *ref_session, struct http_
}
else
{
- assert(0);
+ host_result->value = MEMPOOL_CALLOC(mempool, char, 1);
+ sprintf((char *)host_result->value, "%s", "");
+ host_result->value_len = strlen((char *)host_result->value);
+ return host_result;
}
-#else
- host_result->val.iov_base = MEMPOOL_CALLOC(mempool, char, 32);
- sprintf((char *)host_result->val.iov_base, "%s", "todo:get_tuple4");
- host_result->val.iov_len = strlen((char *)host_result->val.iov_base);
-#endif
+ return host_result;
}
void http_decoder_join_url(struct http_decoder_half_data *hfdata, nmx_pool_t *mempool, const struct http_header_field *host_hdr)
{
int append_slash_len = 0;
- if ('/' != ((char *)hfdata->joint_url.iov_base)[0])
+ const char *join_uri = hfdata->req_line_inner.req_line.uri;
+ size_t join_url_len = hfdata->req_line_inner.req_line.uri_len;
+
+ if (join_url_len > 7 && strncasecmp(join_uri, "http://", 7) == 0)
+ {
+ join_uri += 7;
+ join_url_len -= 7;
+ }
+
+ if ('/' != join_uri[0])
{
append_slash_len = 1;
}
- int url_cache_str_len = host_hdr->value_len + hfdata->joint_url.iov_len + append_slash_len;
+ int url_cache_str_len = host_hdr->value_len + join_url_len + append_slash_len;
char *url_cache_str = MEMPOOL_CALLOC(mempool, char, url_cache_str_len);
char *ptr = url_cache_str;
@@ -1047,91 +1093,55 @@ void http_decoder_join_url(struct http_decoder_half_data *hfdata, nmx_pool_t *me
*ptr = '/';
ptr++;
}
- memcpy(ptr, hfdata->joint_url.iov_base, hfdata->joint_url.iov_len);
+ memcpy(ptr, join_uri, join_url_len);
- MEMPOOL_FREE(mempool, hfdata->joint_url.iov_base); // free the cached uri buffer
hfdata->joint_url.iov_base = url_cache_str;
hfdata->joint_url.iov_len = url_cache_str_len;
- hfdata->joint_url_complete = 1;
}
-void http_decoder_get_url(struct http_decoder_half_data *hfdata, nmx_pool_t *mempool)
+int http_parse_headers_finally(struct http_event_context *ev_ctx, struct http_decoder_half_data *hfdata, nmx_pool_t *mempool)
{
- struct http_request_line reqline = {};
- http_decoder_half_data_get_request_line(hfdata, &reqline);
- if (unlikely(http_strncasecmp_safe("CONNECT", (char *)reqline.method, 7, reqline.method_len) == 0))
+ if (FLOW_TYPE_C2S == hfdata->flow_dir)
{
- hfdata->joint_url.iov_base = MEMPOOL_CALLOC(mempool, char, reqline.uri_len + 1);
- memcpy(hfdata->joint_url.iov_base, reqline.uri, reqline.uri_len);
- hfdata->joint_url.iov_len = reqline.uri_len;
- hfdata->joint_url_complete = 1;
- }
-}
-
-int http_decoder_join_url_finally(struct http_event_context *ev_ctx, struct http_decoder_half_data *hfdata, nmx_pool_t *mempool)
-{
- if (hfdata->joint_url_complete)
- {
- return 0;
+ const struct http_header_field *host_filed = http_half_get_header_field(hfdata, "Host", 4);
+ if (NULL == host_filed)
+ {
+ host_filed = http_using_session_addr_without_host(ev_ctx->ref_session, mempool);
+ }
+ http_decoder_join_url(hfdata, mempool, host_filed);
}
- struct http_header_field addr_as_host = {};
- using_session_addr_as_host(ev_ctx->ref_session, &addr_as_host, mempool);
- http_decoder_join_url(hfdata, mempool, &addr_as_host);
- MEMPOOL_FREE(mempool, addr_as_host.value); // free session addr to host buffer
- return 1;
-}
-void http_decoder_get_host_feed_url(struct http_decoder_half *half)
-{
- if (half->ref_data->joint_url_complete)
+ const struct http_header_field *encoding_field = http_half_get_header_field(hfdata, "Content-Encoding", 16);
+ if (NULL == encoding_field)
{
- return;
+ hfdata->content_encoding = HTTP_CONTENT_ENCODING_NONE;
}
- struct http_header_field host_result = {};
- int host_header_cnt = http_decoder_half_data_get_header(half->ref_data, (char *)"Host", 4, &host_result);
- if (host_header_cnt < 0)
+ else
{
- return;
+ hfdata->content_encoding = http_content_encoding_str2int(encoding_field->value, encoding_field->value_len);
}
- http_decoder_join_url(half->ref_data, half->http_ev_ctx->ref_mempool, &host_result);
+ return 1;
}
int http_half_data_get_url(struct http_decoder_half_data *res_data, const char **url_val, size_t *url_len)
{
- if (0 == res_data->joint_url_complete)
- {
- return -1;
- }
+
*url_val = res_data->joint_url.iov_base;
*url_len = res_data->joint_url.iov_len;
return 0;
}
-#if 0
-int http_half_data_get_decode_url(struct http_decoder_half_data *res_data, hstring *url)
-{
- if (0 == res_data->joint_url_complete)
- {
- return -1;
- }
- url->iov_base = res_data->decoded_url.iov_base;
- url->iov_len = res_data->decoded_url.iov_len;
- return 0;
-}
-#endif
int http_half_data_get_transaction_seq(struct http_decoder_half_data *hf_data)
{
return hf_data->transaction_index;
}
-void http_half_data_update_commit_index(struct http_decoder_half_data *half_data)
+int http_half_get_header_count(struct http_decoder_half_data *half_data)
{
- http_decoder_table_update_commit_index(half_data->table);
-}
-
-int http_half_data_get_total_parsed_header_count(struct http_decoder_half_data *half_data)
-{
- return http_decoder_table_get_total_parsed_header(half_data->table);
+ int header_count = 0;
+ struct http_header_field_inner *el;
+ DL_COUNT(half_data->filed_list, el, header_count);
+ return header_count;
}
void http_half_pre_context_free(struct session *sess, struct http_decoder_exdata *exdata)
@@ -1153,7 +1163,6 @@ void http_half_pre_context_free(struct session *sess, struct http_decoder_exdata
session_mq_publish_message(sess, exdata->pub_topic_id, msg);
}
}
-
for (size_t i = 0; i < queue->queue_size; i++)
{
res_data = queue->array[i].res_data;
@@ -1185,4 +1194,4 @@ enum http_content_encoding http_half_data_get_content_encoding(struct http_decod
return HTTP_CONTENT_ENCODING_NONE;
}
return hf_data->content_encoding;
-} \ No newline at end of file
+}
diff --git a/decoders/http/http_decoder_half.h b/decoders/http/http_decoder_half.h
index f525f78..6622b33 100644
--- a/decoders/http/http_decoder_half.h
+++ b/decoders/http/http_decoder_half.h
@@ -13,6 +13,7 @@ typedef struct iovec hstring;
// only one http event is fired at a time
enum http_event
{
+ __HTTP_EVENT_RESERVED = 0,
HTTP_EVENT_REQ_INIT = 1 << 1,
HTTP_EVENT_REQ_LINE = 1 << 2,
HTTP_EVENT_REQ_HDR = 1 << 3,
@@ -62,16 +63,13 @@ int http_decoder_half_parse(int proxy_enable, struct http_decoder_half *half, co
long long http_decoder_half_trans_count(struct http_decoder_half *half);
// http decoder half data API
-struct http_decoder_half_data *
-http_decoder_half_data_new(nmx_pool_t *mempool);
+struct http_decoder_half_data *http_decoder_half_data_new(nmx_pool_t *mempool, enum flow_type flow_dir);
void http_decoder_half_data_free(nmx_pool_t *mempool, struct http_decoder_half_data *data);
-int http_decoder_half_data_get_request_line(struct http_decoder_half_data *data,
- struct http_request_line *line);
+const struct http_request_line *http_decoder_half_data_get_request_line(struct http_decoder_half_data *data);
-int http_decoder_half_data_get_response_line(struct http_decoder_half_data *data,
- struct http_response_line *line);
+const struct http_response_line *http_decoder_half_data_get_response_line(struct http_decoder_half_data *data);
int http_decoder_half_data_get_header(const struct http_decoder_half_data *data,
const char *name, size_t name_len, struct http_header_field *hdr_res);
@@ -86,6 +84,7 @@ int http_decoder_half_data_get_raw_body(const struct http_decoder_half_data *dat
int http_decoder_half_data_get_decompress_body(const struct http_decoder_half_data *data, const char **body, size_t *body_len);
void http_half_get_lastest_decompress_buffer(struct http_decoder_half_data *data, hstring *decompress_body);
void http_half_decompress_buffer_free(struct http_decoder_half_data *data, hstring *decompress_body);
+void http_half_flow_buffer_free(struct http_decoder_half_data *data);
void http_decoder_half_data_dump(struct http_decoder_half *half);
void http_decoder_get_host_feed_url(struct http_decoder_half *half);
@@ -94,16 +93,20 @@ int http_half_data_get_decode_url(struct http_decoder_half_data *res_data, hstri
void http_decoder_join_url(struct http_decoder_half_data *hfdata,
nmx_pool_t *mempool,
const struct http_header_field *host_hdr);
-int http_decoder_join_url_finally(struct http_event_context *ev_ctx,
- struct http_decoder_half_data *hfdata,
- nmx_pool_t *mempool);
+int http_parse_headers_finally(struct http_event_context *ev_ctx,
+ struct http_decoder_half_data *hfdata,
+ nmx_pool_t *mempool);
int http_half_data_get_url(struct http_decoder_half_data *res_data, const char **url_val, size_t *url_len);
int http_half_data_get_transaction_seq(struct http_decoder_half_data *hf_data);
void http_half_data_update_commit_index(struct http_decoder_half_data *half_data);
void http_half_pre_context_free(struct session *sess, struct http_decoder_exdata *exdata);
void http_half_update_state(struct http_decoder_half_data *hf_data, enum http_event state);
-int http_half_data_get_total_parsed_header_count(struct http_decoder_half_data *half_data);
void http_half_get_max_transaction_seq(struct http_decoder_exdata *exdata, long long *max_req_seq, long long *max_res_seq);
-enum http_content_encoding http_half_data_get_content_encoding(struct http_decoder_half_data *hf_data); \ No newline at end of file
+enum http_content_encoding http_half_data_get_content_encoding(struct http_decoder_half_data *hf_data);
+const struct http_header_field *http_half_get_next_header_field(const struct http_decoder_half_data *half_data, const struct http_header_field *current_header);
+const struct http_header_field *http_half_get_header_field(const struct http_decoder_half_data *half_data, const char *field_name, size_t field_name_len);
+int http_half_get_header_count(struct http_decoder_half_data *half_data);
+hstring *http_half_get_raw_body(struct http_decoder_half_data *data);
+void http_half_line_headers_free(struct http_decoder_half_data *ref_data); \ No newline at end of file
diff --git a/decoders/http/http_decoder_private.h b/decoders/http/http_decoder_private.h
index 04130f0..bc772cd 100644
--- a/decoders/http/http_decoder_private.h
+++ b/decoders/http/http_decoder_private.h
@@ -22,7 +22,6 @@ extern "C"
#include "stellar/http.h"
#include "http_decoder_result_queue.h"
#include "http_decoder_half.h"
-#include "http_decoder_table.h"
#include "http_decoder_result_queue.h"
#include "http_decoder_utils.h"
#include "http_decoder_stat.h"
diff --git a/decoders/http/http_decoder_result_queue.c b/decoders/http/http_decoder_result_queue.c
index 5695138..72eb20b 100644
--- a/decoders/http/http_decoder_result_queue.c
+++ b/decoders/http/http_decoder_result_queue.c
@@ -1,8 +1,7 @@
#include <assert.h>
#include "http_decoder_private.h"
-struct http_decoder_result_queue *
-http_decoder_result_queue_new(nmx_pool_t *mempool, size_t queue_size)
+struct http_decoder_result_queue *http_decoder_result_queue_new(nmx_pool_t *mempool, size_t queue_size)
{
struct http_decoder_result_queue *queue =
MEMPOOL_CALLOC(mempool, struct http_decoder_result_queue, 1);
@@ -11,8 +10,7 @@ http_decoder_result_queue_new(nmx_pool_t *mempool, size_t queue_size)
queue->req_index = 0;
queue->res_index = 0;
queue->queue_size = queue_size;
- queue->array = MEMPOOL_CALLOC(mempool, struct http_decoder_result,
- queue->queue_size);
+ queue->array = MEMPOOL_CALLOC(mempool, struct http_decoder_result, queue->queue_size);
assert(queue->array);
return queue;
}
@@ -104,8 +102,7 @@ int http_decoder_result_queue_push_res(struct http_decoder_result_queue *queue,
return 0;
}
-struct http_decoder_half_data *
-http_decoder_result_queue_pop_req(struct http_decoder_result_queue *queue)
+struct http_decoder_half_data *http_decoder_result_queue_pop_req(struct http_decoder_result_queue *queue)
{
if (NULL == queue)
{
@@ -116,8 +113,7 @@ http_decoder_result_queue_pop_req(struct http_decoder_result_queue *queue)
return req_data;
}
-struct http_decoder_half_data *
-http_decoder_result_queue_pop_res(struct http_decoder_result_queue *queue)
+struct http_decoder_half_data *http_decoder_result_queue_pop_res(struct http_decoder_result_queue *queue)
{
if (NULL == queue)
{
@@ -129,8 +125,7 @@ http_decoder_result_queue_pop_res(struct http_decoder_result_queue *queue)
return res_data;
}
-struct http_decoder_half_data *
-http_decoder_result_queue_peek_req(struct http_decoder_result_queue *queue)
+struct http_decoder_half_data *http_decoder_result_queue_peek_req(struct http_decoder_result_queue *queue)
{
if (NULL == queue)
{
@@ -140,8 +135,7 @@ http_decoder_result_queue_peek_req(struct http_decoder_result_queue *queue)
return queue->array[queue->req_index].req_data;
}
-struct http_decoder_half_data *
-http_decoder_result_queue_peek_res(struct http_decoder_result_queue *queue)
+struct http_decoder_half_data *http_decoder_result_queue_peek_res(struct http_decoder_result_queue *queue)
{
if (NULL == queue)
{
diff --git a/decoders/http/http_decoder_string.c b/decoders/http/http_decoder_string.c
deleted file mode 100644
index 6fd5b04..0000000
--- a/decoders/http/http_decoder_string.c
+++ /dev/null
@@ -1,289 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include "http_decoder_private.h"
-
-static const char *string_state_to_desc(enum string_state state)
-{
- switch (state)
- {
- case STRING_STATE_INIT:
- return "init";
- break;
- case STRING_STATE_REFER:
- return "refer";
- break;
- case STRING_STATE_CACHE:
- return "cache";
- break;
- case STRING_STATE_COMMIT:
- return "commit";
- break;
- default:
- return "unknown";
- break;
- }
-}
-
-void http_decoder_string_refer(struct http_decoder_string *rstr, const char *at, size_t length)
-{
- if (NULL == rstr)
- {
- return;
- }
-
- switch (rstr->state)
- {
- case STRING_STATE_INIT:
- case STRING_STATE_CACHE:
- rstr->refer.iov_base = (char *)at;
- rstr->refer.iov_len = length;
- break;
- default:
- abort();
- break;
- }
-
- rstr->state = STRING_STATE_REFER;
-}
-
-static void string_refer2cache(struct http_decoder_string *rstr)
-{
- if (0 == rstr->refer.iov_len)
- {
- return;
- }
- if (rstr->cache.iov_len >= rstr->max_cache_size)
- {
- return;
- }
-
- size_t length = rstr->cache.iov_len + rstr->refer.iov_len;
- if (length > rstr->max_cache_size)
- {
- length = rstr->max_cache_size;
- }
-
- if (NULL == rstr->cache.iov_base)
- {
- rstr->cache.iov_base = CALLOC(char, length + 1);
- memcpy(rstr->cache.iov_base, rstr->refer.iov_base, length);
- }
- else
- {
- rstr->cache.iov_base = REALLOC(char, rstr->cache.iov_base, length + 1);
- memcpy((char *)rstr->cache.iov_base + rstr->cache.iov_len, rstr->refer.iov_base,
- (length - rstr->cache.iov_len));
- }
-
- rstr->cache.iov_len = length;
- rstr->refer.iov_base = NULL;
- rstr->refer.iov_len = 0;
-}
-
-static void string_commit2cache(struct http_decoder_string *rstr)
-{
- if (rstr->cache.iov_len == rstr->commit.iov_len &&
- rstr->cache.iov_base == rstr->commit.iov_base)
- {
- rstr->commit.iov_base = NULL;
- rstr->commit.iov_len = 0;
- return;
- }
-
- // Only http header key need to backward to cache
- size_t length = 0;
- if (rstr->commit.iov_len > rstr->max_cache_size)
- {
- length = rstr->max_cache_size;
- }
- else
- {
- length = rstr->commit.iov_len;
- }
-
- if (length > 0)
- {
- if (NULL == rstr->cache.iov_base)
- {
- rstr->cache.iov_base = CALLOC(char, length + 1);
- }
- else
- {
- abort();
- }
- memcpy(rstr->cache.iov_base, rstr->commit.iov_base, length);
- rstr->cache.iov_len = length;
-
- rstr->commit.iov_base = NULL;
- rstr->commit.iov_len = 0;
- }
-}
-
-void http_decoder_string_cache(struct http_decoder_string *rstr)
-{
- if (NULL == rstr)
- {
- return;
- }
-
- switch (rstr->state)
- {
- case STRING_STATE_REFER:
- string_refer2cache(rstr);
- break;
- case STRING_STATE_CACHE:
- break;
- case STRING_STATE_COMMIT:
- // commit backward to cache
- string_commit2cache(rstr);
- break;
- default:
- abort();
- break;
- }
- rstr->state = STRING_STATE_CACHE;
-}
-
-void http_decoder_string_commit(struct http_decoder_string *rstr)
-{
- if (NULL == rstr)
- {
- return;
- }
-
- switch (rstr->state)
- {
- case STRING_STATE_REFER:
- if (rstr->cache.iov_len)
- {
- http_decoder_string_cache(rstr);
-
- rstr->commit.iov_base = rstr->cache.iov_base;
- rstr->commit.iov_len = rstr->cache.iov_len;
- // not overwrite rstr->cache.iov_base
- }
- else
- {
- rstr->commit.iov_base = rstr->refer.iov_base;
- rstr->commit.iov_len = rstr->refer.iov_len;
-
- rstr->refer.iov_base = NULL;
- rstr->refer.iov_len = 0;
- }
- break;
- case STRING_STATE_CACHE:
- rstr->commit.iov_base = rstr->cache.iov_base;
- rstr->commit.iov_len = rstr->cache.iov_len;
- // not overwrite rstr->cache.iov_base
- break;
- default:
- // abort();
- break;
- }
-
- rstr->state = STRING_STATE_COMMIT;
-}
-
-void http_decoder_string_reset(struct http_decoder_string *rstr)
-{
- assert(rstr);
-
- switch (rstr->state)
- {
- case STRING_STATE_INIT:
- case STRING_STATE_REFER:
- case STRING_STATE_CACHE:
- case STRING_STATE_COMMIT:
- FREE(rstr->cache.iov_base);
- memset(rstr, 0, sizeof(struct http_decoder_string));
- break;
- default:
- abort();
- break;
- }
-
- rstr->state = STRING_STATE_INIT;
-}
-
-void http_decoder_string_init(struct http_decoder_string *rstr, size_t max_cache_size)
-{
- rstr->max_cache_size = max_cache_size;
-}
-
-void http_decoder_string_reinit(struct http_decoder_string *rstr)
-{
- if (rstr->state == STRING_STATE_CACHE)
- {
- return;
- }
-
- if (rstr->state == STRING_STATE_COMMIT &&
- rstr->cache.iov_base == rstr->commit.iov_base &&
- rstr->cache.iov_len == rstr->commit.iov_len)
- {
- return;
- }
-
- if (rstr->cache.iov_base != NULL)
- {
- FREE(rstr->cache.iov_base);
- rstr->cache.iov_len = 0;
- }
-
-#if 0
- rstr->refer.iov_base = NULL;
- rstr->refer.iov_len = 0;
- rstr->commit.iov_base = NULL;
- rstr->commit.iov_len = 0;
- rstr->state = STRING_STATE_INIT;
-#endif
-}
-
-enum string_state http_decoder_string_state(const struct http_decoder_string *rstr)
-{
- return rstr->state;
-}
-
-int http_decoder_string_get(const struct http_decoder_string *rstr, char **name, size_t *name_len)
-{
- if (NULL == rstr || NULL == name || 0 == name_len)
- {
- return -1;
- }
-
- if (http_decoder_string_state(rstr) == STRING_STATE_COMMIT)
- {
- *name = rstr->commit.iov_base;
- *name_len = rstr->commit.iov_len;
- }
- else
- {
- *name = NULL;
- *name_len = 0;
- }
- return 0;
-}
-
-void http_decoder_string_dump(struct http_decoder_string *rstr, const char *desc)
-{
- if (NULL == rstr)
- {
- return;
- }
-
- char *refer_str = http_safe_dup((char *)rstr->refer.iov_base, rstr->refer.iov_len);
- char *cache_str = http_safe_dup((char *)rstr->cache.iov_base, rstr->cache.iov_len);
- char *commit_str = http_safe_dup((char *)rstr->commit.iov_base, rstr->commit.iov_len);
-
- printf("%s: state: %s, refer: {len: %02zu, iov_base: %s}, cache: {len: %02zu, iov_base: %s}, commit: {len: %02zu, iov_base: %s}\n",
- desc, string_state_to_desc(rstr->state),
- rstr->refer.iov_len, refer_str,
- rstr->cache.iov_len, cache_str,
- rstr->commit.iov_len, commit_str);
-
- FREE(refer_str);
- FREE(cache_str);
- FREE(commit_str);
-} \ No newline at end of file
diff --git a/decoders/http/http_decoder_string.h b/decoders/http/http_decoder_string.h
deleted file mode 100644
index 83721e9..0000000
--- a/decoders/http/http_decoder_string.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#pragma once
-
-#include "stellar/http.h"
-
-enum string_state {
- STRING_STATE_INIT,
- STRING_STATE_REFER,
- STRING_STATE_CACHE,
- STRING_STATE_COMMIT,
-};
-
-/* state transition diagram
- * +----------+
- * | |
- * \|/ |
- * +------+ |
- * | init | |
- * +------+ |
- * | |
- * +---->| |
- * | \|/ |
- * | +-------+ |
- * | | refer |--+ |
- * | +-------+ | |
- * | | | |
- * | \|/ | |
- * | +-------+ | |
- * +--| cache | | |
- * +-------+ | |
- * | | |
- * |<------+ |
- * \|/ |
- * +--------+ |
- * | commit | |
- * +--------+ |
- * | |
- * \|/ |
- * +--------+ |
- * | reset |----+
- * +--------+
- */
-
-
-//http decoder string
-struct http_decoder_string {
- hstring refer; // shallow copy
- hstring cache; // deep copy
- hstring commit;
-
- enum string_state state;
- size_t max_cache_size;
-};
-
-void http_decoder_string_refer(struct http_decoder_string *rstr,
- const char *at, size_t length);
-
-void http_decoder_string_cache(struct http_decoder_string *rstr);
-
-void http_decoder_string_commit(struct http_decoder_string *rstr);
-
-void http_decoder_string_reset(struct http_decoder_string *rstr);
-
-void http_decoder_string_init(struct http_decoder_string *rstr,
- size_t max_cache_size);
-
-void http_decoder_string_reinit(struct http_decoder_string *rstr);
-
-enum string_state http_decoder_string_state(const struct http_decoder_string *rstr);
-
-int http_decoder_string_get(const struct http_decoder_string *rstr, char **name, size_t *name_len);
-
-void http_decoder_string_dump(struct http_decoder_string *rstr, const char *desc);
- \ No newline at end of file
diff --git a/decoders/http/http_decoder_table.c b/decoders/http/http_decoder_table.c
deleted file mode 100644
index c85b876..0000000
--- a/decoders/http/http_decoder_table.c
+++ /dev/null
@@ -1,579 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include "http_decoder_private.h"
-
-#define INIT_HEADER_CNT 16
-#define MAX_URI_CACHE_SIZE 2048
-#define MAX_STATUS_CACHE_SIZE 32
-#define MAX_METHOD_CACHE_SIZE 8
-#define MAX_VERSION_CACHE_SIZE 4
-#define MAX_HEADER_KEY_CACHE_SIZE 4096
-#define MAX_HEADER_VALUE_CACHE_SIZE 4096
-
-struct http_decoder_header
-{
- struct http_decoder_string key;
- struct http_decoder_string val;
-};
-
-struct http_decoder_table
-{
- struct http_decoder_string uri;
- struct http_decoder_string status;
- struct http_decoder_string method;
- struct http_decoder_string version;
- struct http_decoder_string body;
-
- nmx_pool_t *ref_mempool;
- int header_complete; // flag for all headers parsed completely
- size_t header_cnt;
- size_t header_index; // current parsing header
- size_t header_iter; // plugins iterate cursor
- size_t commit_header_index; // pushed to plugins, whether has called http_message_get0_next_header()
- struct http_decoder_header *headers;
-};
-
-static void http_decoder_table_init(struct http_decoder_table *table)
-{
- if (NULL == table)
- {
- return;
- }
-
- struct http_decoder_header *header = NULL;
- assert(table);
-
- http_decoder_string_init(&table->uri, MAX_URI_CACHE_SIZE);
- http_decoder_string_init(&table->status, MAX_STATUS_CACHE_SIZE);
- http_decoder_string_init(&table->method, MAX_METHOD_CACHE_SIZE);
- http_decoder_string_init(&table->version, MAX_METHOD_CACHE_SIZE);
-
- for (size_t i = 0; i < table->header_cnt; i++)
- {
- header = &table->headers[i];
- http_decoder_string_init(&header->key, MAX_HEADER_KEY_CACHE_SIZE);
- http_decoder_string_init(&header->val, MAX_HEADER_VALUE_CACHE_SIZE);
- }
-
- http_decoder_string_init(&table->body, 0);
-}
-
-struct http_decoder_table *http_decoder_table_new(nmx_pool_t *mempool)
-{
- struct http_decoder_table *table =
- MEMPOOL_CALLOC(mempool, struct http_decoder_table, 1);
- assert(table);
-
- table->ref_mempool = mempool;
- table->header_cnt = INIT_HEADER_CNT;
- table->headers = MEMPOOL_CALLOC(mempool, struct http_decoder_header,
- table->header_cnt);
- table->commit_header_index = 0;
- http_decoder_table_init(table);
-
- return table;
-}
-
-void http_decoder_table_free(struct http_decoder_table *table)
-{
- if (NULL == table)
- {
- return;
- }
- if (table->uri.cache.iov_base != NULL)
- {
- FREE(table->uri.cache.iov_base);
- }
- if (table->status.cache.iov_base != NULL)
- {
- FREE(table->status.cache.iov_base);
- }
- if (table->method.cache.iov_base != NULL)
- {
- FREE(table->method.cache.iov_base);
- }
- if (table->version.cache.iov_base != NULL)
- {
- FREE(table->version.cache.iov_base);
- }
- if (table->body.cache.iov_base != NULL)
- {
- FREE(table->body.cache.iov_base);
- }
-
- if (table->headers != NULL)
- {
- for (size_t i = 0; i < table->header_cnt; i++)
- {
- if (table->headers[i].key.cache.iov_base != NULL)
- {
- FREE(table->headers[i].key.cache.iov_base);
- }
-
- if (table->headers[i].val.cache.iov_base != NULL)
- {
- FREE(table->headers[i].val.cache.iov_base);
- }
- }
-
- MEMPOOL_FREE(table->ref_mempool, table->headers);
- table->headers = NULL;
- }
- MEMPOOL_FREE(table->ref_mempool, table);
-}
-
-enum string_state http_decoder_table_state(struct http_decoder_table *table, enum http_item type)
-{
- if (NULL == table)
- {
- return STRING_STATE_INIT;
- }
- struct http_decoder_header *header = NULL;
- enum string_state state = STRING_STATE_INIT;
- assert(table);
-
- switch (type)
- {
- case HTTP_ITEM_URI:
- state = http_decoder_string_state(&table->uri);
- break;
- case HTTP_ITEM_STATUS:
- state = http_decoder_string_state(&table->status);
- break;
- case HTTP_ITEM_METHOD:
- state = http_decoder_string_state(&table->method);
- break;
- case HTTP_ITEM_VERSION:
- state = http_decoder_string_state(&table->version);
- break;
- case HTTP_ITEM_HDRKEY:
- assert(table->header_index < table->header_cnt);
- header = &table->headers[table->header_index];
- state = http_decoder_string_state(&header->key);
- break;
- case HTTP_ITEM_HDRVAL:
- assert(table->header_index < table->header_cnt);
- header = &table->headers[table->header_index];
- state = http_decoder_string_state(&header->val);
- break;
- case HTTP_ITEM_BODY:
- state = http_decoder_string_state(&table->body);
- break;
- default:
- abort();
- break;
- }
-
- return state;
-}
-
-void http_decoder_table_refer(struct http_decoder_table *table, enum http_item type, const char *at, size_t len)
-{
- if (NULL == table)
- {
- return;
- }
-
- struct http_decoder_header *header = NULL;
- assert(table);
-
- switch (type)
- {
- case HTTP_ITEM_URI:
- http_decoder_string_refer(&table->uri, at, len);
- break;
- case HTTP_ITEM_STATUS:
- http_decoder_string_refer(&table->status, at, len);
- break;
- case HTTP_ITEM_METHOD:
- http_decoder_string_refer(&table->method, at, len);
- break;
- case HTTP_ITEM_VERSION:
- http_decoder_string_refer(&table->version, at, len);
- break;
- case HTTP_ITEM_HDRKEY:
- assert(table->header_index < table->header_cnt);
- header = &table->headers[table->header_index];
- http_decoder_string_refer(&header->key, at, len);
- break;
- case HTTP_ITEM_HDRVAL:
- assert(table->header_index < table->header_cnt);
- header = &table->headers[table->header_index];
- http_decoder_string_refer(&header->val, at, len);
- break;
- case HTTP_ITEM_BODY:
- http_decoder_string_refer(&table->body, at, len);
- break;
- default:
- abort();
- break;
- }
-}
-
-void http_decoder_table_cache(struct http_decoder_table *table, enum http_item type)
-{
- if (NULL == table)
- {
- return;
- }
-
- struct http_decoder_header *header = NULL;
- assert(table);
-
- switch (type)
- {
- case HTTP_ITEM_URI:
- http_decoder_string_cache(&table->uri);
- break;
- case HTTP_ITEM_STATUS:
- http_decoder_string_cache(&table->status);
- break;
- case HTTP_ITEM_METHOD:
- http_decoder_string_cache(&table->method);
- break;
- case HTTP_ITEM_VERSION:
- http_decoder_string_cache(&table->version);
- break;
- case HTTP_ITEM_HDRKEY:
- assert(table->header_index < table->header_cnt);
- header = &table->headers[table->header_index];
- http_decoder_string_cache(&header->key);
- break;
- case HTTP_ITEM_HDRVAL:
- assert(table->header_index < table->header_cnt);
- header = &table->headers[table->header_index];
- http_decoder_string_cache(&header->val);
- break;
- case HTTP_ITEM_BODY:
- http_decoder_string_cache(&table->body);
- break;
- default:
- abort();
- break;
- }
-}
-
-void http_decoder_table_commit(struct http_decoder_table *table, enum http_item type)
-{
- if (NULL == table)
- {
- return;
- }
-
- size_t i = 0;
- struct http_decoder_header *header = NULL;
- assert(table);
-
- switch (type)
- {
- case HTTP_ITEM_URI:
- http_decoder_string_commit(&table->uri);
- break;
- case HTTP_ITEM_STATUS:
- http_decoder_string_commit(&table->status);
- break;
- case HTTP_ITEM_METHOD:
- http_decoder_string_commit(&table->method);
- break;
- case HTTP_ITEM_VERSION:
- http_decoder_string_commit(&table->version);
- break;
- case HTTP_ITEM_HDRKEY:
- assert(table->header_index < table->header_cnt);
- header = &table->headers[table->header_index];
- http_decoder_string_commit(&header->key);
- break;
- case HTTP_ITEM_HDRVAL:
- header = &table->headers[table->header_index];
- http_decoder_string_commit(&header->val);
- // inc index
- if ((table->header_index + 1) >= table->header_cnt)
- {
- struct http_decoder_header *old_headers = table->headers;
- table->headers =
- MEMPOOL_CALLOC(table->ref_mempool, struct http_decoder_header,
- table->header_cnt * 2);
- table->header_cnt *= 2;
-
- for (i = 0; i <= table->header_index; i++)
- {
- table->headers[i] = old_headers[i];
- }
-
- MEMPOOL_FREE(table->ref_mempool, old_headers);
-
- for (i = table->header_index + 1; i < table->header_cnt; i++)
- {
- header = &table->headers[i];
- memset(header, 0, sizeof(struct http_decoder_header));
- http_decoder_string_init(&header->key, MAX_HEADER_KEY_CACHE_SIZE);
- http_decoder_string_init(&header->val, MAX_HEADER_VALUE_CACHE_SIZE);
- }
- }
- table->header_index++;
- break;
- case HTTP_ITEM_BODY:
- http_decoder_string_commit(&table->body);
- break;
- default:
- abort();
- break;
- }
-}
-
-void http_decoder_table_reset(struct http_decoder_table *table, enum http_item type)
-{
- if (NULL == table)
- {
- return;
- }
-
- struct http_decoder_header *header = NULL;
- assert(table);
-
- switch (type)
- {
- case HTTP_ITEM_URI:
- http_decoder_string_reset(&table->uri);
- break;
- case HTTP_ITEM_STATUS:
- http_decoder_string_reset(&table->status);
- break;
- case HTTP_ITEM_METHOD:
- http_decoder_string_reset(&table->method);
- break;
- case HTTP_ITEM_VERSION:
- http_decoder_string_reset(&table->version);
- break;
- case HTTP_ITEM_HDRKEY:
- header = &table->headers[table->header_index];
- http_decoder_string_reset(&header->key);
- break;
- case HTTP_ITEM_HDRVAL:
- header = &table->headers[table->header_index];
- http_decoder_string_reset(&header->val);
- break;
- case HTTP_ITEM_BODY:
- http_decoder_string_reset(&table->body);
- break;
- default:
- abort();
- break;
- }
-}
-
-void http_decoder_table_reinit(struct http_decoder_table *table)
-{
- assert(table);
- struct http_decoder_header *header = NULL;
-
- http_decoder_string_reinit(&table->uri);
- http_decoder_string_reinit(&table->status);
- http_decoder_string_reinit(&table->method);
- http_decoder_string_reinit(&table->version);
- // for (size_t i = 0; i < table->header_iter; i++) {
- for (size_t i = 0; i < table->commit_header_index; i++)
- {
- // todo, reset header_index, avoid realloc headers as much as possible
- header = &table->headers[i];
- http_decoder_string_reinit(&header->key);
- http_decoder_string_reinit(&header->val);
- }
-
- http_decoder_string_reinit(&table->body);
-}
-
-void http_decoder_table_dump(struct http_decoder_table *table)
-{
- if (NULL == table)
- {
- return;
- }
-
- http_decoder_string_dump(&table->uri, "uri");
- http_decoder_string_dump(&table->status, "status");
- http_decoder_string_dump(&table->method, "method");
- http_decoder_string_dump(&table->version, "version");
- http_decoder_string_dump(&table->body, "body");
-
- for (size_t i = 0; i < table->header_cnt; i++)
- {
- struct http_decoder_header *header = &table->headers[i];
- if (NULL == header)
- {
- continue;
- }
-
- http_decoder_string_dump(&header->key, "key");
- http_decoder_string_dump(&header->val, "val");
- }
-}
-
-int http_decoder_table_get_uri(const struct http_decoder_table *table, char **out, size_t *out_len)
-{
- if (NULL == table || NULL == out)
- {
- return -1;
- }
- return http_decoder_string_get(&table->uri, out, out_len);
-}
-
-int http_decoder_table_get_method(const struct http_decoder_table *table, char **out, size_t *out_len)
-{
- if (NULL == table || NULL == out)
- {
- return -1;
- }
- return http_decoder_string_get(&table->method, out, out_len);
-}
-
-int http_decoder_table_get_status(const struct http_decoder_table *table, char **out, size_t *out_len)
-{
- if (NULL == table || NULL == out)
- {
- return -1;
- }
- return http_decoder_string_get(&table->status, out, out_len);
-}
-
-int http_decoder_table_get_version(const struct http_decoder_table *table, char **out, size_t *out_len)
-{
- if (NULL == table || NULL == out)
- {
- return -1;
- }
- return http_decoder_string_get(&table->version, out, out_len);
-}
-
-int http_decoder_table_get_body(const struct http_decoder_table *table, char **out, size_t *out_len)
-{
- if (NULL == table || NULL == out)
- {
- return -1;
- }
- return http_decoder_string_get(&table->body, (char **)out, out_len);
-}
-
-int http_decoder_table_get_header(const struct http_decoder_table *table, const char *name, size_t name_len,
- struct http_header_field *hdr_result)
-{
- for (size_t i = 0; i < table->header_cnt; i++)
- {
- const struct http_decoder_header *tmp_header = &table->headers[i];
- if (tmp_header->key.commit.iov_len != name_len)
- {
- continue;
- }
-
- if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT &&
- http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT)
- {
- hstring tmp_key;
- http_decoder_string_get(&tmp_header->key, (char **)&tmp_key.iov_base, &tmp_key.iov_len);
-
- if (tmp_key.iov_len == name_len &&
- (0 == strncasecmp((char *)tmp_key.iov_base, name, name_len)))
- {
- http_decoder_string_get(&tmp_header->key, &hdr_result->name, &hdr_result->name_len);
- http_decoder_string_get(&tmp_header->val, &hdr_result->value, &hdr_result->value_len);
- return 0;
- }
- }
- }
- return -1;
-}
-
-int http_decoder_table_iter_header(struct http_decoder_table *table, struct http_header_field *hdr)
-{
- if (NULL == table || NULL == hdr)
- {
- return -1;
- }
- if (table->header_iter >= table->header_cnt)
- {
- return -1;
- }
-
- struct http_decoder_header *tmp_header = &table->headers[table->header_iter];
- if (tmp_header != NULL)
- {
- if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT &&
- http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT)
- {
-
- http_decoder_string_get(&tmp_header->key, &hdr->name, &hdr->name_len);
- http_decoder_string_get(&tmp_header->val, &hdr->value, &hdr->value_len);
- table->header_iter++;
- return 1;
- }
- }
-
- hdr->name = NULL;
- hdr->name_len = 0;
- hdr->value = NULL;
- hdr->value_len = 0;
-
- return -1;
-}
-
-int http_decoder_table_reset_header_iter(struct http_decoder_table *table)
-{
- table->header_iter = 0;
- return 0;
-}
-
-int http_decoder_table_has_parsed_header(struct http_decoder_table *table)
-{
- // if (NULL == table || (table->header_iter == table->header_index)) {
- if (NULL == table || (table->commit_header_index == table->header_index))
- {
- return 0;
- }
-
- const struct http_decoder_header *tmp_header = &table->headers[table->header_iter];
-
- if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT && http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT)
- {
- return 1;
- }
-
- return 0;
-}
-
-int http_decoder_table_header_complete(struct http_decoder_table *table)
-{
- if (NULL == table)
- {
- return -1;
- }
- return table->header_complete;
-}
-
-void http_decoder_table_set_header_complete(struct http_decoder_table *table)
-{
- if (NULL == table)
- {
- return;
- }
- table->header_complete = 1;
-}
-
-void http_decoder_table_reset_header_complete(struct http_decoder_table *table)
-{
- if (NULL == table)
- {
- return;
- }
- table->header_complete = 0;
-}
-
-void http_decoder_table_update_commit_index(struct http_decoder_table *table)
-{
- table->commit_header_index = table->header_index;
-}
-
-int http_decoder_table_get_total_parsed_header(struct http_decoder_table *table)
-{
- return table->header_index;
-} \ No newline at end of file
diff --git a/decoders/http/http_decoder_table.h b/decoders/http/http_decoder_table.h
deleted file mode 100644
index 9a8d948..0000000
--- a/decoders/http/http_decoder_table.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-#include <stddef.h>
-#include "stellar/http.h"
-#include "http_decoder_private.h"
-#include "http_decoder_string.h"
-
-enum http_item
-{
- HTTP_ITEM_URI = 0x01,
- HTTP_ITEM_STATUS = 0x02,
- HTTP_ITEM_METHOD = 0x03,
- HTTP_ITEM_VERSION = 0x04,
- HTTP_ITEM_HDRKEY = 0x05,
- HTTP_ITEM_HDRVAL = 0x06,
- HTTP_ITEM_BODY = 0x07,
-};
-
-struct http_decoder_table;
-struct http_decoder_table *http_decoder_table_new(nmx_pool_t *mempool);
-
-void http_decoder_table_free(struct http_decoder_table *table);
-
-enum string_state
-http_decoder_table_state(struct http_decoder_table *table, enum http_item type);
-
-void http_decoder_table_refer(struct http_decoder_table *table, enum http_item type,
- const char *at, size_t len);
-
-void http_decoder_table_cache(struct http_decoder_table *table, enum http_item type);
-
-void http_decoder_table_commit(struct http_decoder_table *table, enum http_item type);
-
-void http_decoder_table_reset(struct http_decoder_table *table, enum http_item type);
-
-void http_decoder_table_reinit(struct http_decoder_table *table);
-
-void http_decoder_table_dump(struct http_decoder_table *table);
-
-int http_decoder_table_get_uri(const struct http_decoder_table *table, char **out, size_t *out_len);
-
-int http_decoder_table_get_method(const struct http_decoder_table *table, char **out, size_t *out_len);
-
-int http_decoder_table_get_status(const struct http_decoder_table *table, char **out, size_t *out_len);
-
-int http_decoder_table_get_version(const struct http_decoder_table *table, char **out, size_t *out_len);
-
-int http_decoder_table_get_body(const struct http_decoder_table *table, char **out, size_t *out_len);
-
-int http_decoder_table_get_header(const struct http_decoder_table *table,
- const char *name, size_t name_len,
- struct http_header_field *hdr_res);
-
-int http_decoder_table_iter_header(struct http_decoder_table *table,
- struct http_header_field *hdr);
-int http_decoder_table_reset_header_iter(struct http_decoder_table *table);
-/**
- * @brief Is there a parsed header
- *
- * @retval yes(1) no(0)
- */
-int http_decoder_table_has_parsed_header(struct http_decoder_table *table);
-
-/**
- * @brief If headers have been parsed completely
- *
- * @retval yes(1) no(0)
- */
-int http_decoder_table_header_complete(struct http_decoder_table *table);
-
-/**
- * @brief set flag for headers parsed completely
- */
-void http_decoder_table_set_header_complete(struct http_decoder_table *table);
-
-void http_decoder_table_reset_header_complete(struct http_decoder_table *table);
-
-void http_decoder_table_update_commit_index(struct http_decoder_table *table);
-
-int http_decoder_table_get_total_parsed_header(struct http_decoder_table *table);
diff --git a/decoders/http/http_decoder_tunnel.c b/decoders/http/http_decoder_tunnel.c
index a6abda8..d1677f0 100644
--- a/decoders/http/http_decoder_tunnel.c
+++ b/decoders/http/http_decoder_tunnel.c
@@ -21,20 +21,17 @@ int httpd_tunnel_identify(struct http_decoder_env *httpd_env, int curdir, struct
if (FLOW_TYPE_C2S == curdir)
{
- struct http_request_line reqline = {};
- http_decoder_half_data_get_request_line(hfdata, &reqline);
- if (0 == http_strncasecmp_safe("CONNECT", (char *)reqline.method,
- 7, reqline.method_len))
+ const struct http_request_line *reqline = http_decoder_half_data_get_request_line(hfdata);
+ if (0 == http_strncasecmp_safe("CONNECT", (char *)reqline->method, 7, reqline->method_len))
{
return 1;
}
}
else
{
- struct http_response_line resline = {};
- http_decoder_half_data_get_response_line(hfdata, &resline);
- if (resline.status_code == HTTP_STATUS_OK && 0 == http_strncasecmp_safe("Connection established", (char *)resline.status,
- strlen("Connection established"), resline.status_len))
+ const struct http_response_line *resline = http_decoder_half_data_get_response_line(hfdata);
+ if ((resline->status_code == HTTP_STATUS_OK) && (0 == http_strncasecmp_safe("Connection established", (char *)resline->status,
+ strlen("Connection established"), resline->status_len)))
{
return 1;
}
diff --git a/decoders/http/http_decoder_utils.c b/decoders/http/http_decoder_utils.c
index 08c66b0..25795d7 100644
--- a/decoders/http/http_decoder_utils.c
+++ b/decoders/http/http_decoder_utils.c
@@ -1,5 +1,6 @@
#include <string.h>
#include <assert.h>
+#include <arpa/inet.h>
#include "stellar/http.h"
#include "http_decoder_private.h"
@@ -33,14 +34,8 @@ const char *http_message_type_to_string(enum http_message_type type)
switch (type)
{
- case HTTP_MESSAGE_REQ_LINE:
- sname = "HTTP_MESSAGE_REQ_LINE";
- break;
- case HTTP_MESSAGE_REQ_HEADER:
- sname = "HTTP_MESSAGE_REQ_HEADER";
- break;
- case HTTP_MESSAGE_REQ_HEADER_END:
- sname = "HTTP_MESSAGE_REQ_HEADER_END";
+ case HTTP_MESSAGE_REQ_LINE_HEADERS:
+ sname = "HTTP_MESSAGE_REQ_LINE_HEADERS";
break;
case HTTP_MESSAGE_REQ_BODY_START:
sname = "HTTP_MESSAGE_REQ_BODY_START";
@@ -51,14 +46,8 @@ const char *http_message_type_to_string(enum http_message_type type)
case HTTP_MESSAGE_REQ_BODY_END:
sname = "HTTP_MESSAGE_REQ_BODY_END";
break;
- case HTTP_MESSAGE_RES_LINE:
- sname = "HTTP_MESSAGE_RES_LINE";
- break;
- case HTTP_MESSAGE_RES_HEADER:
- sname = "HTTP_MESSAGE_RES_HEADER";
- break;
- case HTTP_MESSAGE_RES_HEADER_END:
- sname = "HTTP_MESSAGE_RES_HEADER_END";
+ case HTTP_MESSAGE_RES_LINE_HEADERS:
+ sname = "HTTP_MESSAGE_RES_LINE_HEADERS";
break;
case HTTP_MESSAGE_RES_BODY_START:
sname = "HTTP_MESSAGE_RES_BODY_START";
@@ -89,18 +78,14 @@ int http_message_type_is_req(struct session *sess, enum http_message_type msg_ty
switch (msg_type)
{
- case HTTP_MESSAGE_REQ_LINE:
- case HTTP_MESSAGE_REQ_HEADER:
- case HTTP_MESSAGE_REQ_HEADER_END:
+ case HTTP_MESSAGE_REQ_LINE_HEADERS:
case HTTP_MESSAGE_REQ_BODY_START:
case HTTP_MESSAGE_REQ_BODY:
case HTTP_MESSAGE_REQ_BODY_END:
is_req_msg = 1;
break;
- case HTTP_MESSAGE_RES_LINE:
- case HTTP_MESSAGE_RES_HEADER:
- case HTTP_MESSAGE_RES_HEADER_END:
+ case HTTP_MESSAGE_RES_LINE_HEADERS:
case HTTP_MESSAGE_RES_BODY_START:
case HTTP_MESSAGE_RES_BODY:
case HTTP_MESSAGE_RES_BODY_END:
@@ -308,4 +293,126 @@ void httpd_session_get_addr(const struct session *sess, struct httpd_session_add
break;
}
}
-} \ No newline at end of file
+}
+
+void http_session_addr_ntop(const struct httpd_session_addr *sesaddr, char *buf, size_t buflen)
+{
+ char sip_str[INET6_ADDRSTRLEN] = {0};
+ char dip_str[INET6_ADDRSTRLEN] = {0};
+ uint16_t sport_host, dport_host;
+ if (sesaddr->ipver == 4)
+ {
+ inet_ntop(AF_INET, &sesaddr->saddr4, sip_str, sizeof(sip_str));
+ inet_ntop(AF_INET, &sesaddr->daddr4, dip_str, sizeof(dip_str));
+
+ }
+ else if (sesaddr->ipver == 6)
+ {
+ inet_ntop(AF_INET6, &sesaddr->saddr6, sip_str, sizeof(sip_str));
+ inet_ntop(AF_INET6, &sesaddr->daddr6, dip_str, sizeof(dip_str));
+ }
+ sport_host = ntohs(sesaddr->sport);
+ dport_host = ntohs(sesaddr->dport);
+ snprintf(buf, buflen, "%s:%u-%s:%u", sip_str, sport_host, dip_str, dport_host);
+}
+
+struct http_buffer *http_buffer_new(void)
+{
+ struct http_buffer *buffer = CALLOC(struct http_buffer, 1);
+ buffer->buffer = NULL;
+ buffer->buffer_size = 0;
+ return buffer;
+}
+
+void http_buffer_free(struct http_buffer *buffer)
+{
+ if (NULL == buffer)
+ {
+ return;
+ }
+ FREE(buffer->buffer);
+ FREE(buffer);
+}
+
+int http_buffer_add(struct http_buffer *buffer, const char *data, size_t data_len)
+{
+ if (NULL == buffer || NULL == data || 0 == data_len)
+ {
+ return -1;
+ }
+ buffer->buffer = REALLOC(char, buffer->buffer, buffer->buffer_size + data_len);
+ memcpy(buffer->buffer + buffer->buffer_size, data, data_len);
+ buffer->buffer_size += data_len;
+ return 0;
+}
+
+int http_buffer_read(struct http_buffer *buffer, char **data, size_t *data_len)
+{
+ if (NULL == buffer)
+ {
+ if (data)
+ {
+ *data = NULL;
+ }
+ if (data_len)
+ {
+ *data_len = 0;
+ }
+ return -1;
+ }
+ *data = buffer->buffer;
+ *data_len = buffer->buffer_size;
+ return 0;
+}
+
+char *http_string_dup(const char *str, size_t len)
+{
+ if (NULL == str || 0 == len)
+ {
+ return NULL;
+ }
+ char *new_str = ALLOC(char, len);
+ memcpy(new_str, str, len);
+ return new_str;
+}
+
+enum http_method_type http_get_method(const char *method, size_t method_len)
+{
+ enum http_method_type type = HTTP_METHOD_UNKNOWN;
+
+ if (NULL == method || 0 == method_len)
+ {
+ return type;
+ }
+
+ if (http_strncasecmp_safe(method, "GET", method_len, 3) == 0)
+ {
+ type = HTTP_METHOD_GET;
+ }
+ else if (http_strncasecmp_safe(method, "POST", method_len, 4) == 0)
+ {
+ type = HTTP_METHOD_POST;
+ }
+ else if (http_strncasecmp_safe(method, "HEAD", method_len, 4) == 0)
+ {
+ type = HTTP_METHOD_HEAD;
+ }
+ else if (http_strncasecmp_safe(method, "PUT", method_len, 3) == 0)
+ {
+ type = HTTP_METHOD_PUT;
+ }
+ else if (http_strncasecmp_safe(method, "DELETE", method_len, 6) == 0)
+ {
+ type = HTTP_METHOD_DELETE;
+ }
+ else if (http_strncasecmp_safe(method, "CONNECT", method_len, 7) == 0)
+ {
+ type = HTTP_METHOD_CONNECT;
+ }
+ else if (http_strncasecmp_safe(method, "OPTIONS", method_len, 7) == 0)
+ {
+ type = HTTP_METHOD_OPTIONS;
+ }
+
+ return type;
+}
diff --git a/decoders/http/http_decoder_utils.h b/decoders/http/http_decoder_utils.h
index 01a32b2..a8d2d46 100644
--- a/decoders/http/http_decoder_utils.h
+++ b/decoders/http/http_decoder_utils.h
@@ -71,9 +71,29 @@ struct httpd_session_addr
union
{
uint32_t saddr4;
- uint32_t daddr4;
struct in6_addr saddr6;
+ };
+ union
+ {
+ uint32_t daddr4;
struct in6_addr daddr6;
};
};
+/*
+ why not use libevent evbuffer?
+ 1. evbuffer is a buffer chain, it is not suitable for http half flow cache;
+ 2. http_half_flow_buffer is a whole continuous buffer;
+ */
+struct http_buffer
+{
+ char *buffer;
+ size_t buffer_size;
+};
+
void httpd_session_get_addr(const struct session *sess, struct httpd_session_addr *addr);
+void http_session_addr_ntop(const struct httpd_session_addr *sesaddr, char *buf, size_t buflen);
+struct http_buffer *http_buffer_new(void);
+void http_buffer_free(struct http_buffer *buffer);
+int http_buffer_add(struct http_buffer *buffer, const char *data, size_t data_len);
+int http_buffer_read(struct http_buffer *buffer, char **data, size_t *data_len);
+char *http_string_dup(const char *str, size_t len); \ No newline at end of file
diff --git a/decoders/http/version.map b/decoders/http/version.map
index a64b729..eacc6bc 100644
--- a/decoders/http/version.map
+++ b/decoders/http/version.map
@@ -6,6 +6,7 @@ global:
http_decoder_exit;
http_decoder_tcp_stream_msg_cb;
http_url_decode;
+ http_get_method;
};
local: *;
}; \ No newline at end of file
diff --git a/include/stellar/http.h b/include/stellar/http.h
index 1cc5bec..9873d62 100644
--- a/include/stellar/http.h
+++ b/include/stellar/http.h
@@ -12,16 +12,12 @@ extern "C"
{
HTTP_TRANSACTION_START,
- HTTP_MESSAGE_REQ_LINE,
- HTTP_MESSAGE_REQ_HEADER,
- HTTP_MESSAGE_REQ_HEADER_END, // todo, delete END, push all fileds at once
+ HTTP_MESSAGE_REQ_LINE_HEADERS,
HTTP_MESSAGE_REQ_BODY_START,
HTTP_MESSAGE_REQ_BODY,
HTTP_MESSAGE_REQ_BODY_END,
- HTTP_MESSAGE_RES_LINE,
- HTTP_MESSAGE_RES_HEADER,
- HTTP_MESSAGE_RES_HEADER_END, // todo, delete END, push all fileds at once
+ HTTP_MESSAGE_RES_LINE_HEADERS,
HTTP_MESSAGE_RES_BODY_START,
HTTP_MESSAGE_RES_BODY,
HTTP_MESSAGE_RES_BODY_END,
@@ -31,32 +27,44 @@ extern "C"
HTTP_MESSAGE_MAX
};
+ enum http_method_type
+ {
+ HTTP_METHOD_DELETE = 0,
+ HTTP_METHOD_GET = 1,
+ HTTP_METHOD_HEAD = 2,
+ HTTP_METHOD_POST = 3,
+ HTTP_METHOD_PUT = 4,
+ HTTP_METHOD_CONNECT = 5,
+ HTTP_METHOD_OPTIONS = 6,
+
+ HTTP_METHOD_UNKNOWN = 255,
+ };
+
struct http_header_field
{
- char *name;
+ const char *name;
size_t name_len;
- char *value;
+ const char *value;
size_t value_len;
};
struct http_request_line
{
- char *method;
+ const char *method;
size_t method_len;
- char *uri;
+ const char *uri;
size_t uri_len;
- char *version;
+ const char *version;
size_t version_len;
-
int major_version;
int minor_version;
};
struct http_response_line
{
- char *version;
+ const char *version;
size_t version_len;
- char *status;
+ const char *status;
size_t status_len;
int major_version;
int minor_version;
@@ -64,42 +72,31 @@ extern "C"
};
enum http_message_type http_message_get_type(const struct http_message *msg);
-
- void http_message_get0_request_line(const struct http_message *msg, struct http_request_line *line);
-
- void http_message_get0_response_line(const struct http_message *msg, struct http_response_line *line);
+ enum http_method_type http_get_method(const char *method, size_t method_len);
+ const struct http_request_line *http_message_get0_request_line(const struct http_message *msg);
+ const struct http_response_line *http_message_get0_response_line(const struct http_message *msg);
/*
- * Pay attention: key->iov_base is case-insensitive.
+ * Pay attention: field name is case-insensitive.
*/
- void http_message_get0_header(const struct http_message *msg, const char *name, size_t name_len, struct http_header_field *field_result);
+ const struct http_header_field *http_message_get0_header(const struct http_message *msg, const char *field_name, size_t field_name_len);
/**
- * @brief loop reading all headers.
+ * @brief The first time, set param 'header' as NULL, and the subsequent calls use return value until result is NULL.
*
- * @retval succeed( >= 0) failed(-1)
- */
- int http_message_get0_next_header(const struct http_message *msg, struct http_header_field *header);
-
- /**
- * @retval succeed( >= 0) failed(-1)
+ * @retval not-NULL: success
+ * NULL: empty or EOF
*/
- int http_message_reset_header_iter(struct http_message *msg); // to do , obsoleted
-
- void http_message_get0_uncompressed_body(const struct http_message *msg, const char **body, size_t *body_len);
+ const struct http_header_field *http_message_get0_next_header(const struct http_message *msg, const struct http_header_field *header);
- /**
- * @brief If the body hasn't been compressed, same as http_message_get0_uncompressed_body().
- *
- */
- void http_message_get0_decompressed_body(const struct http_message *msg, const char **body, size_t *body_len);
+ void http_message_get0_uncompressed_body(const struct http_message *msg, const char **uncompressed_body, size_t *uncompressed_len);
+ void http_message_get0_decompressed_body(const struct http_message *msg, const char **decompressed_body, size_t *decompressed_len);
void http_message_get0_raw_url(const struct http_message *msg, const char **url, size_t *url_len);
-
/*
return value:
0: failed
- >1: success, length of decoded_url_buffer, not C string( no EOF with '\0' )
+ >1: success, length of decoded url. Pay attention: decoded url is not C string (no EOF with '\0')!
*/
size_t http_url_decode(const char *raw_url, size_t raw_url_len, char *decoded_url_buffer, size_t decoded_url_buffer_len);
diff --git a/include/stellar/utils.h b/include/stellar/utils.h
index 3d6ab43..826ced0 100644
--- a/include/stellar/utils.h
+++ b/include/stellar/utils.h
@@ -10,7 +10,7 @@
#define FREE(p) \
{ \
- free(p); \
+ free((void *)p); \
p = NULL; \
}
diff --git a/test/decoders/http/CMakeLists.txt b/test/decoders/http/CMakeLists.txt
index 5011a95..b2246a0 100644
--- a/test/decoders/http/CMakeLists.txt
+++ b/test/decoders/http/CMakeLists.txt
@@ -12,7 +12,7 @@ include_directories(${PROJECT_SOURCE_DIR}/decoders/http)
include_directories(${PROJECT_SOURCE_DIR}/include/stellar)
add_executable(gtest_http http_gtest.cpp ${PROJECT_SOURCE_DIR}/decoders/http/http_decoder_utils.c ${PROJECT_SOURCE_DIR}/decoders/http/http_content_decompress.c ${PROJECT_SOURCE_DIR}/deps/md5/md5.c)
-target_link_libraries(gtest_http gtest stellar_lib llhttp-static z brotli-dec-static brotli-enc-static brotli-common-static libevent-static)
+target_link_libraries(gtest_http gtest stellar_lib llhttp-static z brotli-dec-static brotli-enc-static brotli-common-static)
add_executable(http_test_main plugin_test_main.cpp)
set_target_properties(http_test_main
diff --git a/test/decoders/http/benchmarks/json/http_get_encoded_uri.json b/test/decoders/http/benchmarks/json/http_get_encoded_uri.json
index de1419a..433faeb 100644
--- a/test/decoders/http/benchmarks/json/http_get_encoded_uri.json
+++ b/test/decoders/http/benchmarks/json/http_get_encoded_uri.json
@@ -38,8 +38,7 @@
"Content-Type": "text/html;charset=UTF-8",
"Transfer-Encoding": "chunked",
"Date": "Sat, 18 May 2019 01:36:57 GMT",
- "__X_HTTP_RAW_PAYLOAD_MD5": "d545e0faf20f7ffe90e31cfc1aef1782",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "d545e0faf20f7ffe90e31cfc1aef1782"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "d545e0faf20f7ffe90e31cfc1aef1782"
},
{
"__X_HTTP_TRANSACTION": "request",
@@ -75,7 +74,6 @@
"Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8",
"Content-Length": "1703517",
"Date": "Sat, 18 May 2019 01:37:00 GMT",
- "__X_HTTP_RAW_PAYLOAD_MD5": "3598c468910611a3128d068e20ae0e82",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "3598c468910611a3128d068e20ae0e82"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "3598c468910611a3128d068e20ae0e82"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_get_req_pipeline.json b/test/decoders/http/benchmarks/json/http_get_req_pipeline.json
index af8ff75..5054c03 100644
--- a/test/decoders/http/benchmarks/json/http_get_req_pipeline.json
+++ b/test/decoders/http/benchmarks/json/http_get_req_pipeline.json
@@ -62,7 +62,6 @@
"Date": "Wed, 25 Oct 2023 06:43:35 GMT",
"Content-Type": "text/html",
"Connection": "close",
- "__X_HTTP_RAW_PAYLOAD_MD5": "6fb335f443cfc8a9d952d27cf3dc1059",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "6fb335f443cfc8a9d952d27cf3dc1059"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "6fb335f443cfc8a9d952d27cf3dc1059"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_get_single_trans.json b/test/decoders/http/benchmarks/json/http_get_single_trans.json
index 165bb65..772c7a9 100644
--- a/test/decoders/http/benchmarks/json/http_get_single_trans.json
+++ b/test/decoders/http/benchmarks/json/http_get_single_trans.json
@@ -28,7 +28,6 @@
"Content-type": "text/html",
"Content-Length": "144",
"Last-Modified": "Thu, 30 Nov 2023 08:38:54 GMT",
- "__X_HTTP_RAW_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_hdrs_exceed_maximum.json b/test/decoders/http/benchmarks/json/http_hdrs_exceed_maximum.json
index 9bc751b..3298b60 100644
--- a/test/decoders/http/benchmarks/json/http_hdrs_exceed_maximum.json
+++ b/test/decoders/http/benchmarks/json/http_hdrs_exceed_maximum.json
@@ -45,7 +45,6 @@
"Keep-Alive": "timeout=15",
"Connection": "Keep-Alive",
"Content-Type": "image/gif",
- "__X_HTTP_RAW_PAYLOAD_MD5": "ad480fd0732d0f6f1a8b06359e3a42bb",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "ad480fd0732d0f6f1a8b06359e3a42bb"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "ad480fd0732d0f6f1a8b06359e3a42bb"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state.json b/test/decoders/http/benchmarks/json/http_msg_type_state.json
index 5dc0564..31cd5ac 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state.json
@@ -1,20 +1,16 @@
[
{
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
- "msg_1": "HTTP_MESSAGE_REQ_LINE",
- "msg_2": "HTTP_MESSAGE_REQ_HEADER",
- "msg_3": "HTTP_MESSAGE_REQ_HEADER_END",
- "msg_4": "HTTP_MESSAGE_REQ_BODY_START",
- "msg_5": "HTTP_MESSAGE_REQ_BODY",
- "msg_6": "HTTP_MESSAGE_REQ_BODY_END"
+ "msg_1": "HTTP_MESSAGE_REQ_LINE_HEADERS",
+ "msg_2": "HTTP_MESSAGE_REQ_BODY_START",
+ "msg_3": "HTTP_MESSAGE_REQ_BODY",
+ "msg_4": "HTTP_MESSAGE_REQ_BODY_END"
},
{
- "msg_7": "HTTP_MESSAGE_RES_LINE",
- "msg_8": "HTTP_MESSAGE_RES_HEADER",
- "msg_9": "HTTP_MESSAGE_RES_HEADER_END",
- "msg_10": "HTTP_MESSAGE_RES_BODY_START",
- "msg_11": "HTTP_MESSAGE_RES_BODY",
- "msg_12": "HTTP_MESSAGE_RES_BODY_END",
- "msg_13": "HTTP_TRANSACTION_END_transaction_0"
+ "msg_5": "HTTP_MESSAGE_RES_LINE_HEADERS",
+ "msg_6": "HTTP_MESSAGE_RES_BODY_START",
+ "msg_7": "HTTP_MESSAGE_RES_BODY",
+ "msg_8": "HTTP_MESSAGE_RES_BODY_END",
+ "msg_9": "HTTP_TRANSACTION_END_transaction_0"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state_c2s.json b/test/decoders/http/benchmarks/json/http_msg_type_state_c2s.json
index 8533bb9..15385ad 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state_c2s.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state_c2s.json
@@ -1,13 +1,11 @@
[
{
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
- "msg_1": "HTTP_MESSAGE_REQ_LINE",
- "msg_2": "HTTP_MESSAGE_REQ_HEADER",
- "msg_3": "HTTP_MESSAGE_REQ_HEADER_END",
- "msg_4": "HTTP_MESSAGE_REQ_BODY_START",
- "msg_5": "HTTP_MESSAGE_REQ_BODY",
- "msg_6": "HTTP_MESSAGE_REQ_BODY_END",
- "msg_7": "HTTP_TRANSACTION_END_transaction_0"
+ "msg_1": "HTTP_MESSAGE_REQ_LINE_HEADERS",
+ "msg_2": "HTTP_MESSAGE_REQ_BODY_START",
+ "msg_3": "HTTP_MESSAGE_REQ_BODY",
+ "msg_4": "HTTP_MESSAGE_REQ_BODY_END",
+ "msg_5": "HTTP_TRANSACTION_END_transaction_0"
},
{}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state_exception_c2s.json b/test/decoders/http/benchmarks/json/http_msg_type_state_exception_c2s.json
index e694238..c78cf34 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state_exception_c2s.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state_exception_c2s.json
@@ -1,13 +1,11 @@
[
{
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
- "msg_1": "HTTP_MESSAGE_REQ_LINE",
- "msg_2": "HTTP_MESSAGE_REQ_HEADER",
- "msg_3": "HTTP_MESSAGE_REQ_HEADER_END",
- "msg_4": "HTTP_MESSAGE_REQ_BODY_START",
- "msg_5": "HTTP_MESSAGE_REQ_BODY"
+ "msg_1": "HTTP_MESSAGE_REQ_LINE_HEADERS",
+ "msg_2": "HTTP_MESSAGE_REQ_BODY_START",
+ "msg_3": "HTTP_MESSAGE_REQ_BODY"
},
{
- "msg_6": "HTTP_TRANSACTION_END_transaction_0"
+ "msg_4": "HTTP_TRANSACTION_END_transaction_0"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state_exception_s2c.json b/test/decoders/http/benchmarks/json/http_msg_type_state_exception_s2c.json
index cf03270..a7c9865 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state_exception_s2c.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state_exception_s2c.json
@@ -1,16 +1,12 @@
[
{
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
- "msg_1": "HTTP_MESSAGE_REQ_LINE",
- "msg_2": "HTTP_MESSAGE_REQ_HEADER",
- "msg_3": "HTTP_MESSAGE_REQ_HEADER_END"
+ "msg_1": "HTTP_MESSAGE_REQ_LINE_HEADERS"
},
{
- "msg_4": "HTTP_MESSAGE_RES_LINE",
- "msg_5": "HTTP_MESSAGE_RES_HEADER",
- "msg_6": "HTTP_MESSAGE_RES_HEADER_END",
- "msg_7": "HTTP_MESSAGE_RES_BODY_START",
- "msg_8": "HTTP_MESSAGE_RES_BODY",
- "msg_9": "HTTP_TRANSACTION_END_transaction_0"
+ "msg_2": "HTTP_MESSAGE_RES_LINE_HEADERS",
+ "msg_3": "HTTP_MESSAGE_RES_BODY_START",
+ "msg_4": "HTTP_MESSAGE_RES_BODY",
+ "msg_5": "HTTP_TRANSACTION_END_transaction_0"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state_pipeline.json b/test/decoders/http/benchmarks/json/http_msg_type_state_pipeline.json
index d50f4ac..4028c0f 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state_pipeline.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state_pipeline.json
@@ -1,61 +1,45 @@
[
{
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
- "msg_1": "HTTP_MESSAGE_REQ_LINE",
- "msg_2": "HTTP_MESSAGE_REQ_HEADER",
- "msg_3": "HTTP_MESSAGE_REQ_HEADER_END",
- "msg_8": "HTTP_TRANSACTION_START_transaction_1",
- "msg_9": "HTTP_MESSAGE_REQ_LINE",
- "msg_10": "HTTP_MESSAGE_REQ_HEADER",
- "msg_11": "HTTP_MESSAGE_REQ_HEADER_END",
- "msg_16": "HTTP_TRANSACTION_START_transaction_2",
- "msg_17": "HTTP_MESSAGE_REQ_LINE",
- "msg_18": "HTTP_MESSAGE_REQ_HEADER",
- "msg_19": "HTTP_MESSAGE_REQ_HEADER_END",
- "msg_24": "HTTP_TRANSACTION_START_transaction_3",
- "msg_25": "HTTP_MESSAGE_REQ_LINE",
- "msg_26": "HTTP_MESSAGE_REQ_HEADER",
- "msg_27": "HTTP_MESSAGE_REQ_HEADER_END"
+ "msg_1": "HTTP_MESSAGE_REQ_LINE_HEADERS",
+ "msg_4": "HTTP_TRANSACTION_START_transaction_1",
+ "msg_5": "HTTP_MESSAGE_REQ_LINE_HEADERS",
+ "msg_8": "HTTP_TRANSACTION_START_transaction_2",
+ "msg_9": "HTTP_MESSAGE_REQ_LINE_HEADERS",
+ "msg_12": "HTTP_TRANSACTION_START_transaction_3",
+ "msg_13": "HTTP_MESSAGE_REQ_LINE_HEADERS"
},
{
- "msg_4": "HTTP_MESSAGE_RES_LINE",
- "msg_5": "HTTP_MESSAGE_RES_HEADER",
- "msg_6": "HTTP_MESSAGE_RES_HEADER_END",
- "msg_7": "HTTP_TRANSACTION_END_transaction_0",
- "msg_12": "HTTP_MESSAGE_RES_LINE",
- "msg_13": "HTTP_MESSAGE_RES_HEADER",
- "msg_14": "HTTP_MESSAGE_RES_HEADER_END",
- "msg_15": "HTTP_TRANSACTION_END_transaction_1",
- "msg_20": "HTTP_MESSAGE_RES_LINE",
- "msg_21": "HTTP_MESSAGE_RES_HEADER",
- "msg_22": "HTTP_MESSAGE_RES_HEADER_END",
- "msg_23": "HTTP_TRANSACTION_END_transaction_2",
- "msg_28": "HTTP_MESSAGE_RES_LINE",
- "msg_29": "HTTP_MESSAGE_RES_HEADER",
- "msg_30": "HTTP_MESSAGE_RES_HEADER_END",
- "msg_31": "HTTP_MESSAGE_RES_BODY_START",
+ "msg_2": "HTTP_MESSAGE_RES_LINE_HEADERS",
+ "msg_3": "HTTP_TRANSACTION_END_transaction_0",
+ "msg_6": "HTTP_MESSAGE_RES_LINE_HEADERS",
+ "msg_7": "HTTP_TRANSACTION_END_transaction_1",
+ "msg_10": "HTTP_MESSAGE_RES_LINE_HEADERS",
+ "msg_11": "HTTP_TRANSACTION_END_transaction_2",
+ "msg_14": "HTTP_MESSAGE_RES_LINE_HEADERS",
+ "msg_15": "HTTP_MESSAGE_RES_BODY_START",
+ "msg_16": "HTTP_MESSAGE_RES_BODY",
+ "msg_17": "HTTP_MESSAGE_RES_BODY",
+ "msg_18": "HTTP_MESSAGE_RES_BODY",
+ "msg_19": "HTTP_MESSAGE_RES_BODY",
+ "msg_20": "HTTP_MESSAGE_RES_BODY",
+ "msg_21": "HTTP_MESSAGE_RES_BODY",
+ "msg_22": "HTTP_MESSAGE_RES_BODY",
+ "msg_23": "HTTP_MESSAGE_RES_BODY",
+ "msg_24": "HTTP_MESSAGE_RES_BODY",
+ "msg_25": "HTTP_MESSAGE_RES_BODY",
+ "msg_26": "HTTP_MESSAGE_RES_BODY",
+ "msg_27": "HTTP_MESSAGE_RES_BODY",
+ "msg_28": "HTTP_MESSAGE_RES_BODY",
+ "msg_29": "HTTP_MESSAGE_RES_BODY",
+ "msg_30": "HTTP_MESSAGE_RES_BODY",
+ "msg_31": "HTTP_MESSAGE_RES_BODY",
"msg_32": "HTTP_MESSAGE_RES_BODY",
"msg_33": "HTTP_MESSAGE_RES_BODY",
"msg_34": "HTTP_MESSAGE_RES_BODY",
"msg_35": "HTTP_MESSAGE_RES_BODY",
"msg_36": "HTTP_MESSAGE_RES_BODY",
- "msg_37": "HTTP_MESSAGE_RES_BODY",
- "msg_38": "HTTP_MESSAGE_RES_BODY",
- "msg_39": "HTTP_MESSAGE_RES_BODY",
- "msg_40": "HTTP_MESSAGE_RES_BODY",
- "msg_41": "HTTP_MESSAGE_RES_BODY",
- "msg_42": "HTTP_MESSAGE_RES_BODY",
- "msg_43": "HTTP_MESSAGE_RES_BODY",
- "msg_44": "HTTP_MESSAGE_RES_BODY",
- "msg_45": "HTTP_MESSAGE_RES_BODY",
- "msg_46": "HTTP_MESSAGE_RES_BODY",
- "msg_47": "HTTP_MESSAGE_RES_BODY",
- "msg_48": "HTTP_MESSAGE_RES_BODY",
- "msg_49": "HTTP_MESSAGE_RES_BODY",
- "msg_50": "HTTP_MESSAGE_RES_BODY",
- "msg_51": "HTTP_MESSAGE_RES_BODY",
- "msg_52": "HTTP_MESSAGE_RES_BODY",
- "msg_53": "HTTP_MESSAGE_RES_BODY_END",
- "msg_54": "HTTP_TRANSACTION_END_transaction_3"
+ "msg_37": "HTTP_MESSAGE_RES_BODY_END",
+ "msg_38": "HTTP_TRANSACTION_END_transaction_3"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state_s2c.json b/test/decoders/http/benchmarks/json/http_msg_type_state_s2c.json
index c59d0bb..92f9df0 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state_s2c.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state_s2c.json
@@ -2,12 +2,10 @@
{},
{
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
- "msg_1": "HTTP_MESSAGE_RES_LINE",
- "msg_2": "HTTP_MESSAGE_RES_HEADER",
- "msg_3": "HTTP_MESSAGE_RES_HEADER_END",
- "msg_4": "HTTP_MESSAGE_RES_BODY_START",
- "msg_5": "HTTP_MESSAGE_RES_BODY",
- "msg_6": "HTTP_MESSAGE_RES_BODY_END",
- "msg_7": "HTTP_TRANSACTION_END_transaction_0"
+ "msg_1": "HTTP_MESSAGE_RES_LINE_HEADERS",
+ "msg_2": "HTTP_MESSAGE_RES_BODY_START",
+ "msg_3": "HTTP_MESSAGE_RES_BODY",
+ "msg_4": "HTTP_MESSAGE_RES_BODY_END",
+ "msg_5": "HTTP_TRANSACTION_END_transaction_0"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel.json b/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel.json
index 4a66f37..ad22440 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel.json
@@ -3,20 +3,16 @@
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
"msg_1": "HTTP_MESSAGE_REQ_LINE",
"msg_2": "HTTP_MESSAGE_REQ_HEADER",
- "msg_3": "HTTP_MESSAGE_REQ_HEADER_END",
"msg_8": "HTTP_TRANSACTION_START_transaction_1",
"msg_9": "HTTP_MESSAGE_REQ_LINE",
- "msg_10": "HTTP_MESSAGE_REQ_HEADER",
- "msg_11": "HTTP_MESSAGE_REQ_HEADER_END"
+ "msg_10": "HTTP_MESSAGE_REQ_HEADER"
},
{
"msg_4": "HTTP_MESSAGE_RES_LINE",
"msg_5": "HTTP_MESSAGE_RES_HEADER",
- "msg_6": "HTTP_MESSAGE_RES_HEADER_END",
"msg_7": "HTTP_TRANSACTION_END_transaction_0",
"msg_12": "HTTP_MESSAGE_RES_LINE",
"msg_13": "HTTP_MESSAGE_RES_HEADER",
- "msg_14": "HTTP_MESSAGE_RES_HEADER_END",
"msg_15": "HTTP_MESSAGE_RES_BODY",
"msg_16": "HTTP_MESSAGE_RES_BODY",
"msg_17": "HTTP_MESSAGE_RES_BODY",
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_c2s.json b/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_c2s.json
index 5b7e588..6f8857b 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_c2s.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_c2s.json
@@ -3,12 +3,10 @@
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
"msg_1": "HTTP_MESSAGE_REQ_LINE",
"msg_2": "HTTP_MESSAGE_REQ_HEADER",
- "msg_3": "HTTP_MESSAGE_REQ_HEADER_END",
"msg_4": "HTTP_TRANSACTION_END_transaction_0",
"msg_5": "HTTP_TRANSACTION_START_transaction_1",
"msg_6": "HTTP_MESSAGE_REQ_LINE",
"msg_7": "HTTP_MESSAGE_REQ_HEADER",
- "msg_8": "HTTP_MESSAGE_REQ_HEADER_END",
"msg_9": "HTTP_TRANSACTION_END_transaction_1"
},
{}
diff --git a/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_s2c.json b/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_s2c.json
index 07a1451..66704f1 100644
--- a/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_s2c.json
+++ b/test/decoders/http/benchmarks/json/http_msg_type_state_tunnel_s2c.json
@@ -4,12 +4,10 @@
"msg_0": "HTTP_TRANSACTION_START_transaction_0",
"msg_1": "HTTP_MESSAGE_RES_LINE",
"msg_2": "HTTP_MESSAGE_RES_HEADER",
- "msg_3": "HTTP_MESSAGE_RES_HEADER_END",
"msg_4": "HTTP_TRANSACTION_END_transaction_0",
"msg_5": "HTTP_TRANSACTION_START_transaction_1",
"msg_6": "HTTP_MESSAGE_RES_LINE",
"msg_7": "HTTP_MESSAGE_RES_HEADER",
- "msg_8": "HTTP_MESSAGE_RES_HEADER_END",
"msg_9": "HTTP_MESSAGE_RES_BODY",
"msg_10": "HTTP_MESSAGE_RES_BODY",
"msg_11": "HTTP_MESSAGE_RES_BODY",
diff --git a/test/decoders/http/benchmarks/json/http_multi_parse_error.json b/test/decoders/http/benchmarks/json/http_multi_parse_error.json
index c49d41e..578b8df 100644
--- a/test/decoders/http/benchmarks/json/http_multi_parse_error.json
+++ b/test/decoders/http/benchmarks/json/http_multi_parse_error.json
@@ -15,9 +15,8 @@
"Content-Type": "text/xml",
"Date": "Sat Sep 7 10:05:13 2019",
"Content-Length": "468",
- "__X_HTTP_URL": ":4445/RPC2",
- "__X_HTTP_RAW_PAYLOAD_MD5": "6eccbcf261f04aabfa69884aa283f4f3",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "6eccbcf261f04aabfa69884aa283f4f3"
+ "__X_HTTP_URL": "/:4445/RPC2",
+ "__X_HTTP_RAW_PAYLOAD_MD5": "6eccbcf261f04aabfa69884aa283f4f3"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -32,7 +31,6 @@
"Transfer-Encoding": "chunked",
"X-Powered-By": "ulxmlrpcpp/1.7.4",
"Date": "Sat Sep 7 01:09:24 2019",
- "__X_HTTP_RAW_PAYLOAD_MD5": "5cf8a4aa9a54e7f2d05b55ed05bf9071",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "5cf8a4aa9a54e7f2d05b55ed05bf9071"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "5cf8a4aa9a54e7f2d05b55ed05bf9071"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_no_content_length.json b/test/decoders/http/benchmarks/json/http_no_content_length.json
index 9310d04..6539bc4 100644
--- a/test/decoders/http/benchmarks/json/http_no_content_length.json
+++ b/test/decoders/http/benchmarks/json/http_no_content_length.json
@@ -40,7 +40,6 @@
"P3P": "policyref=\"/w3c/p3p.xml\", CP=\"ALL IND DSP COR ADM CONo CUR IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI\"",
"Set-Cookie": "trafic_ranking=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; expires=Sun, 11-Jan-2037 14:00:00 GMT; path=/; domain=.xxxxxx.xx",
"connection": "close",
- "__X_HTTP_RAW_PAYLOAD_MD5": "9fb54a2726ca3cf54a82804d0e66d08a",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "9fb54a2726ca3cf54a82804d0e66d08a"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "9fb54a2726ca3cf54a82804d0e66d08a"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_out_of_order.json b/test/decoders/http/benchmarks/json/http_out_of_order.json
index 489b7c1..cd9baeb 100644
--- a/test/decoders/http/benchmarks/json/http_out_of_order.json
+++ b/test/decoders/http/benchmarks/json/http_out_of_order.json
@@ -38,7 +38,6 @@
"Keep-Alive": "timeout=120, max=1000",
"Connection": "Keep-Alive",
"Content-Type": "image/jpeg",
- "__X_HTTP_RAW_PAYLOAD_MD5": "c4c9d459415e922f877a2af6afd9d316",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "c4c9d459415e922f877a2af6afd9d316"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "c4c9d459415e922f877a2af6afd9d316"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_over_pppoe.json b/test/decoders/http/benchmarks/json/http_over_pppoe.json
index b4b4bfb..ffc82b1 100644
--- a/test/decoders/http/benchmarks/json/http_over_pppoe.json
+++ b/test/decoders/http/benchmarks/json/http_over_pppoe.json
@@ -30,7 +30,6 @@
"X-RTFM": "Learn about this site at http://bit.ly/14DAh2o and don't abuse the service",
"X-YOU-SHOULD-APPLY-FOR-A-JOB": "If you're reading this, apply here: http://rackertalent.com/",
"X-ICANHAZNODE": "icanhazip1.nugget",
- "__X_HTTP_RAW_PAYLOAD_MD5": "624520ac54235ac2284ed2dd2b17e1ad",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "624520ac54235ac2284ed2dd2b17e1ad"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "624520ac54235ac2284ed2dd2b17e1ad"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_pipeline_header_splitting.json b/test/decoders/http/benchmarks/json/http_pipeline_header_splitting.json
index bebfa94..014c706 100644
--- a/test/decoders/http/benchmarks/json/http_pipeline_header_splitting.json
+++ b/test/decoders/http/benchmarks/json/http_pipeline_header_splitting.json
@@ -31,8 +31,7 @@
"Server": "BaseHTTP/0.6 Python/3.6.88",
"Date": "Sun, 01 Sep 2024 07:31:09 GMTT",
"Content-length": "88",
- "__X_HTTP_RAW_PAYLOAD_MD5": "c396b63d897591e928fae959915e9ebc",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "c396b63d897591e928fae959915e9ebc"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "c396b63d897591e928fae959915e9ebc"
},
{
"__X_HTTP_TRANSACTION": "request",
@@ -63,7 +62,6 @@
"Server": "BaseHTTP/0.6 Python/3.6.88",
"Date": "Sun, 01 Sep 2024 07:31:09 GMTT",
"Content-length": "89",
- "__X_HTTP_RAW_PAYLOAD_MD5": "5e3c5a7de2696e52ef42d9ccfd8ce831",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "5e3c5a7de2696e52ef42d9ccfd8ce831"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "5e3c5a7de2696e52ef42d9ccfd8ce831"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_post_multipart_form_data.json b/test/decoders/http/benchmarks/json/http_post_multipart_form_data.json
index ac524f6..99e8852 100644
--- a/test/decoders/http/benchmarks/json/http_post_multipart_form_data.json
+++ b/test/decoders/http/benchmarks/json/http_post_multipart_form_data.json
@@ -31,8 +31,7 @@
"Content-Type": "text/html;charset=UTF-8",
"Content-Length": "468",
"Date": "Thu, 28 Mar 2019 08:13:33 GMT",
- "__X_HTTP_RAW_PAYLOAD_MD5": "2b8cd757ab5ffba85acac26c008a1ffc",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "2b8cd757ab5ffba85acac26c008a1ffc"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "2b8cd757ab5ffba85acac26c008a1ffc"
},
{
"__X_HTTP_TRANSACTION": "request",
@@ -63,8 +62,7 @@
"Content-Type": "text/html;charset=UTF-8",
"Content-Length": "468",
"Date": "Thu, 28 Mar 2019 08:13:33 GMT",
- "__X_HTTP_RAW_PAYLOAD_MD5": "2b8cd757ab5ffba85acac26c008a1ffc",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "2b8cd757ab5ffba85acac26c008a1ffc"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "2b8cd757ab5ffba85acac26c008a1ffc"
},
{
"__X_HTTP_TRANSACTION": "request",
@@ -87,8 +85,7 @@
"Accept-Language": "zh-CN,zh;q=0.8",
"Cookie": "JSESSIONID=969AC5FBD069EE6218EB10513726B244; JSESSIONID=400CC78DF5784F303702CC7F02C6122C",
"__X_HTTP_URL": "192.168.57.14:8080/fileupload/servlet/UploadHandleServlet",
- "__X_HTTP_RAW_PAYLOAD_MD5": "550be33bf0ac01b6f7ac175bb8f4522a",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "550be33bf0ac01b6f7ac175bb8f4522a"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "550be33bf0ac01b6f7ac175bb8f4522a"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -102,7 +99,6 @@
"Content-Type": "text/html;charset=UTF-8",
"Content-Length": "144",
"Date": "Thu, 28 Mar 2019 08:13:37 GMT",
- "__X_HTTP_RAW_PAYLOAD_MD5": "3fa07f3ec9f9fefed96e9886f80760bb",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "3fa07f3ec9f9fefed96e9886f80760bb"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "3fa07f3ec9f9fefed96e9886f80760bb"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_req_1byte_sliding_window.json b/test/decoders/http/benchmarks/json/http_req_1byte_sliding_window.json
index 13b360d..b96fdd4 100644
--- a/test/decoders/http/benchmarks/json/http_req_1byte_sliding_window.json
+++ b/test/decoders/http/benchmarks/json/http_req_1byte_sliding_window.json
@@ -29,7 +29,6 @@
"Content-type": "text/html",
"Content-Length": "144",
"Last-Modified": "Fri, 29 Dec 2023 08:50:53 GMT",
- "__X_HTTP_RAW_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_res_1byte_sliding_window.json b/test/decoders/http/benchmarks/json/http_res_1byte_sliding_window.json
index f527839..e46872e 100644
--- a/test/decoders/http/benchmarks/json/http_res_1byte_sliding_window.json
+++ b/test/decoders/http/benchmarks/json/http_res_1byte_sliding_window.json
@@ -29,7 +29,6 @@
"Content-type": "text/html",
"Content-Length": "144",
"Last-Modified": "Fri, 29 Dec 2023 08:50:53 GMT",
- "__X_HTTP_RAW_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "3e11876cd3a234541ae37d833c088a76"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_trans_pipeline.json b/test/decoders/http/benchmarks/json/http_trans_pipeline.json
index 4bd0879..88cfb2f 100644
--- a/test/decoders/http/benchmarks/json/http_trans_pipeline.json
+++ b/test/decoders/http/benchmarks/json/http_trans_pipeline.json
@@ -81,19 +81,6 @@
"__X_HTTP_URL": "116.181.2.152/_vti_bin/_vti_adm/admin.exe"
},
{
- "__X_HTTP_TRANSACTION": "request",
- "__X_HTTP_TRANSACTION_SEQ": 6,
- "method": "GET",
- "uri": "/_vti_bin/fpcount.exe?Page=default.asp|Image=3",
- "req_version": "1.1",
- "major_version": 1,
- "minor_version": 1,
- "Host": "116.181.2.152",
- "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
- "Connection": "keep-alive",
- "__X_HTTP_URL": "116.181.2.152/_vti_bin/fpcount.exe?Page=default.asp|Image=3"
- },
- {
"__X_HTTP_TRANSACTION": "response",
"__X_HTTP_TRANSACTION_SEQ": 0,
"res_version": "1.1",
@@ -106,8 +93,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "32dc0b2772bd73a952abba009291a399",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "32dc0b2772bd73a952abba009291a399"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "32dc0b2772bd73a952abba009291a399"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -122,8 +108,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "db2ff8008149d8e70d8a2929acbb0f56",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "db2ff8008149d8e70d8a2929acbb0f56"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "db2ff8008149d8e70d8a2929acbb0f56"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -138,8 +123,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "f5df152f7d8f34c630f298d2fcb46ed3",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "f5df152f7d8f34c630f298d2fcb46ed3"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "f5df152f7d8f34c630f298d2fcb46ed3"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -154,8 +138,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "73e98ca7b62764869357b3e3c40dcd68",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "73e98ca7b62764869357b3e3c40dcd68"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "73e98ca7b62764869357b3e3c40dcd68"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -170,8 +153,20 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "a5733c8989bde7f08506fa68c20f0c62",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "a5733c8989bde7f08506fa68c20f0c62"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "a5733c8989bde7f08506fa68c20f0c62"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "__X_HTTP_TRANSACTION_SEQ": 6,
+ "method": "GET",
+ "uri": "/_vti_bin/fpcount.exe?Page=default.asp|Image=3",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/fpcount.exe?Page=default.asp|Image=3"
},
{
"__X_HTTP_TRANSACTION": "request",
@@ -290,8 +285,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "4bc0dde3722f76d60fef6f1d878cbb14",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "4bc0dde3722f76d60fef6f1d878cbb14"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "4bc0dde3722f76d60fef6f1d878cbb14"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -306,8 +300,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "728dc2eafd49c9be8149add7c6aff207",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "728dc2eafd49c9be8149add7c6aff207"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "728dc2eafd49c9be8149add7c6aff207"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -322,8 +315,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "0cde98e33181ee0ded49e8d0a3178d55",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "0cde98e33181ee0ded49e8d0a3178d55"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "0cde98e33181ee0ded49e8d0a3178d55"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -338,8 +330,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "d627268e0aba817d818b6e2b7e41aa11",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "d627268e0aba817d818b6e2b7e41aa11"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "d627268e0aba817d818b6e2b7e41aa11"
},
{
"__X_HTTP_TRANSACTION": "response",
@@ -354,8 +345,7 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "e99d9829d50bd94b3497b91011f6e349",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "e99d9829d50bd94b3497b91011f6e349"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "e99d9829d50bd94b3497b91011f6e349"
},
{
"__X_HTTP_TRANSACTION": "request",
@@ -383,7 +373,6 @@
"Content-Type": "text/html",
"Content-Length": "146",
"Connection": "keep-alive",
- "__X_HTTP_RAW_PAYLOAD_MD5": "99a813d29c5da4e6f7269be4c1a31c8e",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "99a813d29c5da4e6f7269be4c1a31c8e"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "99a813d29c5da4e6f7269be4c1a31c8e"
}
] \ No newline at end of file
diff --git a/test/decoders/http/benchmarks/json/http_url_test_without_host.json b/test/decoders/http/benchmarks/json/http_url_test_without_host.json
index 09427a7..6538a08 100644
--- a/test/decoders/http/benchmarks/json/http_url_test_without_host.json
+++ b/test/decoders/http/benchmarks/json/http_url_test_without_host.json
@@ -24,7 +24,6 @@
"Server": "BaseHTTP/0.6 Python/3.6.8",
"Date": "Thu, 14 Mar 2024 06:15:20 GMT",
"Content-type": "application/json",
- "__X_HTTP_RAW_PAYLOAD_MD5": "49dfdd54b01cbcd2d2ab5e9e5ee6b9b9",
- "__X_HTTP_DECOMPRESS_PAYLOAD_MD5": "49dfdd54b01cbcd2d2ab5e9e5ee6b9b9"
+ "__X_HTTP_RAW_PAYLOAD_MD5": "49dfdd54b01cbcd2d2ab5e9e5ee6b9b9"
}
] \ No newline at end of file
diff --git a/test/decoders/http/http_gtest.cpp b/test/decoders/http/http_gtest.cpp
index 4f99fb6..e442e87 100644
--- a/test/decoders/http/http_gtest.cpp
+++ b/test/decoders/http/http_gtest.cpp
@@ -7,7 +7,6 @@
#include "http_decoder_private.h"
#include "brotli/decode.h"
#include "brotli/encode.h"
-#include "event2/buffer.h"
#define ZIP_UNZIP_TEST_DATA_LEN (1024 * 1024)
void httpd_url_decode(const char *string, size_t length, char *ostring, size_t *olen);
@@ -60,27 +59,27 @@ TEST(http_url_decoder, chinese2)
EXPECT_EQ(decoded_url_len, strlen("http://www.baidu.com/\xE7\xBC\x96\xE8\xA7\xA3\xE7\xA0\x81\xE6\xB5\x8B\xE8\xAF\x95\xE5\x93\x88\xE5\x93\x88"));
}
-TEST(http, event_buffer)
+TEST(http, buffer)
{
- struct evbuffer *evbuf = evbuffer_new();
+ struct http_buffer *hbuf = http_buffer_new();
- evbuffer_add(evbuf, "hello", 5);
+ http_buffer_add(hbuf, "hello", 5);
+
+ char *data;
+ size_t len;
+ http_buffer_read(hbuf, &data, &len);
- size_t len = evbuffer_get_length(evbuf);
- EXPECT_EQ(len, 5);
- char outbuf[16];
- len = evbuffer_copyout(evbuf, outbuf, sizeof(outbuf));
EXPECT_EQ(len, 5);
- EXPECT_EQ(0, memcmp(outbuf, "hello", 5));
+ EXPECT_EQ(0, memcmp(data, "hello", 5));
- evbuffer_add(evbuf, ",", 1);
- evbuffer_add(evbuf, "world", 5);
+ http_buffer_add(hbuf, ",", 1);
+ http_buffer_add(hbuf, "world", 5);
- len = evbuffer_copyout(evbuf, outbuf, sizeof(outbuf));
+ http_buffer_read(hbuf, &data, &len);
EXPECT_EQ(len, 11);
- EXPECT_EQ(0, memcmp(outbuf, "hello,world", 11));
+ EXPECT_EQ(0, memcmp(data, "hello,world", 11));
- evbuffer_free(evbuf);
+ http_buffer_free(hbuf);
}
static int http_compress_use_deflate(unsigned char *indata, size_t indata_len, unsigned char *zip_data, size_t *zip_data_len)
diff --git a/test/decoders/http/http_test_plug.cpp b/test/decoders/http/http_test_plug.cpp
index d91b552..5b8d2e0 100644
--- a/test/decoders/http/http_test_plug.cpp
+++ b/test/decoders/http/http_test_plug.cpp
@@ -166,7 +166,7 @@ void transaction_index_to_json(cJSON *ctx, int transaction_index)
cJSON_AddNumberToObject(ctx, GTEST_HTTP_TRANS_SEQ_NAME, transaction_index);
}
-void req_line_to_json(cJSON *ctx, struct http_request_line *req_line)
+void req_line_to_json(cJSON *ctx, const struct http_request_line *req_line)
{
http_field_to_json(ctx, "method", (char *)req_line->method, req_line->method_len);
http_field_to_json(ctx, "uri", (char *)req_line->uri, req_line->uri_len);
@@ -176,7 +176,7 @@ void req_line_to_json(cJSON *ctx, struct http_request_line *req_line)
cJSON_AddNumberToObject(ctx, "minor_version", req_line->minor_version);
}
-void res_line_to_json(cJSON *ctx, struct http_response_line *res_line)
+void res_line_to_json(cJSON *ctx, const struct http_response_line *res_line)
{
http_field_to_json(ctx, "res_version", (char *)res_line->version, res_line->version_len);
http_field_to_json(ctx, "res_status", (char *)res_line->status, res_line->status_len);
@@ -186,7 +186,7 @@ void res_line_to_json(cJSON *ctx, struct http_response_line *res_line)
cJSON_AddNumberToObject(ctx, "status_code", res_line->status_code);
}
-void http_header_to_json(cJSON *ctx, struct http_header_field *header)
+void http_header_to_json(cJSON *ctx, const struct http_header_field *header)
{
char key[MAX_KEY_STR_LEN] = {0};
if ((header->name == NULL) || (header->value == NULL))
@@ -218,7 +218,7 @@ void http_url_add_to_json(cJSON *ctx, struct http_message *msg)
return;
}
- http_message_get0_raw_url(msg, (const char **)&raw_url_result, &raw_url_result.iov_len);
+ http_message_get0_raw_url(msg, (const char **)&raw_url_result.iov_base, &raw_url_result.iov_len);
if (raw_url_result.iov_base == NULL)
{
return;
@@ -309,8 +309,14 @@ static void commit_last_half_flow_data(struct gtest_plug_exdata_t *gtest_plug_ex
}
}
+
static void http_decoder_test_update_session_tuple4(struct session *sess, struct gtest_plug_exdata_t *gtest_plug_exdata)
{
+ char sess_addr_string[256] = {};
+ struct httpd_session_addr sesaddr = {};
+ httpd_session_get_addr(sess, &sesaddr);
+ http_session_addr_ntop(&sesaddr, sess_addr_string, sizeof(sess_addr_string));
+
if (gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION] == NULL)
{
const char *human_addr_cstr = session_get0_readable_addr(sess);
@@ -319,6 +325,7 @@ static void http_decoder_test_update_session_tuple4(struct session *sess, struct
fprintf(stderr, "can't get readable_addr, to use session_get0_readable_addr() the sapp_log.conf level must <= INFO\n");
return;
}
+ assert(0 == strncasecmp(human_addr_cstr, sess_addr_string, strlen(sess_addr_string)));
char result_name[MAX_KEY_STR_LEN] = {0};
gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION] = cJSON_CreateObject();
cJSON_AddStringToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION], GTEST_HTTP_TUPLE4_NAME, human_addr_cstr);
@@ -392,9 +399,6 @@ extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, cons
(void)topic_id;
(void)no_use_ctx;
(void)plugin_env;
- struct http_request_line req_line = {};
- struct http_response_line res_line = {};
- struct http_header_field header = {};
hstring body = {};
struct http_message *msg = (struct http_message *)raw_msg;
enum http_message_type msg_type = http_message_get_type(msg);
@@ -406,34 +410,26 @@ extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, cons
session_exdata_set(sess, g_exdata_idx, gtest_plug_exdata);
}
- // if (http_message_type_is_req(sess, msg_type))
- // {
- // cJSON *json = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ];
- // }
- // else
- // {
- // cJSON *json = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES];
- // }
-
http_decoder_test_update_session_tuple4(sess, gtest_plug_exdata);
switch (msg_type)
{
- case HTTP_MESSAGE_REQ_LINE:
+ case HTTP_MESSAGE_REQ_LINE_HEADERS:
+ {
commit_last_half_flow_data(gtest_plug_exdata, msg, HTTP_TRANSACTION_REQ, 0);
- http_message_get0_request_line(msg, &req_line);
- req_line_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], &req_line);
- break;
- case HTTP_MESSAGE_REQ_HEADER:
- while (http_message_get0_next_header(msg, &header) >= 0)
+ const struct http_request_line *req_line = NULL;
+ req_line = http_message_get0_request_line(msg);
+ req_line_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], req_line);
+
+ const struct http_header_field *current_header = NULL;
+ while ((current_header = http_message_get0_next_header(msg, current_header)) != NULL)
{
- http_header_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], &header);
+ http_header_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], current_header);
}
g_header_count = 1;
- break;
- case HTTP_MESSAGE_REQ_HEADER_END:
http_url_add_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], msg);
- break;
+ }
+ break;
case HTTP_MESSAGE_REQ_BODY_START:
case HTTP_MESSAGE_REQ_BODY:
memset(&body, 0, sizeof(hstring));
@@ -450,18 +446,20 @@ extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, cons
append_http_payload(sess, gtest_plug_exdata, PAYLOAD_DECOMPRESS, &body, HTTP_TRANSACTION_REQ);
}
break;
- case HTTP_MESSAGE_RES_LINE:
+ case HTTP_MESSAGE_RES_LINE_HEADERS:
+ {
commit_last_half_flow_data(gtest_plug_exdata, msg, HTTP_TRANSACTION_RES, 0);
- http_message_get0_response_line(msg, &res_line);
- res_line_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], &res_line);
- break;
- case HTTP_MESSAGE_RES_HEADER:
- while (http_message_get0_next_header(msg, &header) >= 0)
+ const struct http_response_line *res_line = NULL;
+ res_line = http_message_get0_response_line(msg);
+ res_line_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], res_line);
+ const struct http_header_field *current_header = NULL;
+ while ((current_header = http_message_get0_next_header(msg, current_header)) != NULL)
{
- http_header_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], &header);
+ http_header_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], current_header);
}
g_header_count = 1;
- break;
+ }
+ break;
case HTTP_MESSAGE_RES_BODY_START:
case HTTP_MESSAGE_RES_BODY:
memset(&body, 0, sizeof(hstring));
@@ -480,7 +478,12 @@ extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, cons
}
break;
- // to do: check payload
+ // case HTTP_TRANSACTION_END:
+
+ // commit_last_half_flow_data(gtest_plug_exdata, msg, HTTP_TRANSACTION_REQ, 0);
+ // commit_last_half_flow_data(gtest_plug_exdata, msg, HTTP_TRANSACTION_RES, 0);
+ // break;
+
default:
break;
}
@@ -507,14 +510,6 @@ void http_decoder_test_exdata_free(int idx, void *ex_ptr, void *arg)
}
}
-// static int update_config_file(const char *filename, const char *key, const char *value)
-// {
-// char cmd_buf[1024] = {};
-// snprintf(cmd_buf, 1024, "sed 's/^[ \t]*%s=.*/%s=%s/g' -i %s", key, key, value, filename);
-// int ret = system(cmd_buf);
-// return ret;
-// }
-
extern "C" void http_decoder_test_state_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env)
{
(void)topic_id;