summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlijia <[email protected]>2024-06-06 11:16:22 +0800
committerlijia <[email protected]>2024-06-06 11:16:22 +0800
commit7d6170a23027aff0ebf2e7832dc11e4bbdce57ea (patch)
treeaf9caf24c274b561bc92f07f8db7c14b89c5e425
parent1c232f0176c43c93c3e787ac83f3573bf42c58f1 (diff)
add fieldstat4 statistics, push transaction free msg in session closing state.v2.0.3
-rw-r--r--include/http_decoder.h3
-rw-r--r--src/http_content_decompress.cpp12
-rw-r--r--src/http_decoder.cpp155
-rw-r--r--src/http_decoder_half.cpp160
-rw-r--r--src/http_decoder_half.h20
-rw-r--r--src/http_decoder_inc.h20
-rw-r--r--src/http_decoder_result_queue.cpp11
-rw-r--r--src/http_decoder_stat.cpp130
-rw-r--r--src/http_decoder_stat.h58
-rw-r--r--src/http_decoder_table.cpp5
-rw-r--r--src/http_decoder_table.h1
-rw-r--r--test/http_decoder_gtest.cpp13
-rw-r--r--test/http_decoder_perf_main.cpp5
-rw-r--r--test/http_pcap/http_error.pcapbin0 -> 456 bytes
-rw-r--r--test/http_pcap/http_session_exception_c2s.pcapbin0 -> 710 bytes
-rw-r--r--test/http_pcap/http_session_exception_s2c.pcapbin0 -> 1113 bytes
-rw-r--r--test/test_result_json/http_msg_type_state_exception_c2s.json12
-rw-r--r--test/test_result_json/http_msg_type_state_exception_s2c.json15
-rw-r--r--test_based_on_stellar/CMakeLists.txt7
19 files changed, 392 insertions, 235 deletions
diff --git a/include/http_decoder.h b/include/http_decoder.h
index 449d498..9ee6ff4 100644
--- a/include/http_decoder.h
+++ b/include/http_decoder.h
@@ -7,6 +7,8 @@ extern "C"
#endif
enum http_message_type {
+ HTTP_TRANSACTION_NEW,
+
HTTP_MESSAGE_REQ_LINE,
HTTP_MESSAGE_REQ_HEADER,
HTTP_MESSAGE_REQ_HEADER_END,
@@ -19,7 +21,6 @@ enum http_message_type {
HTTP_MESSAGE_RES_BODY,
HTTP_MESSAGE_RES_BODY_END,
- HTTP_TRANSACTION_NEW,
HTTP_TRANSACTION_FREE,
HTTP_MESSAGE_MAX
diff --git a/src/http_content_decompress.cpp b/src/http_content_decompress.cpp
index e761f1d..5c436d9 100644
--- a/src/http_content_decompress.cpp
+++ b/src/http_content_decompress.cpp
@@ -153,9 +153,9 @@ http_content_decompress_write_zlib(struct http_content_decompress *decompress,
decompress->buffer_size);
*outdata = decompress->buffer;
*outdata_len = *outdata_len + have;
- http_decoder_log(DEBUG, "%s realloc outbuffer %zu bytes",
- http_content_encoding_int2str(decompress->encoding),
- decompress->buffer_size);
+ // http_decoder_log(DEBUG, "%s realloc outbuffer %zu bytes",
+ // http_content_encoding_int2str(decompress->encoding),
+ // decompress->buffer_size);
z_stream_ptr->avail_out = have;
z_stream_ptr->next_out = (unsigned char *)decompress->buffer +
(decompress->buffer_size - have);
@@ -211,9 +211,9 @@ http_content_decompress_write_br(struct http_content_decompress *decompress,
if (ret == BROTLI_DECODER_RESULT_ERROR) {
BrotliDecoderErrorCode errcode =
BrotliDecoderGetErrorCode(decompress->br_state);
- http_decoder_log(ERROR,
- "BrotliDecoderDecompressStream() failed: errno = %d, %s",
- errcode, BrotliDecoderErrorString(errcode));
+ // http_decoder_log(ERROR,
+ // "BrotliDecoderDecompressStream() failed: errno = %d, %s",
+ // errcode, BrotliDecoderErrorString(errcode));
return -1;
}
diff --git a/src/http_decoder.cpp b/src/http_decoder.cpp
index 750a739..8aa39e9 100644
--- a/src/http_decoder.cpp
+++ b/src/http_decoder.cpp
@@ -1,10 +1,9 @@
#include <assert.h>
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include "http_decoder_inc.h"
-__thread struct http_decoder_stat _th_stat;
-
struct http_message *http_message_new(enum http_message_type type, struct http_decoder_result_queue *queue,
int queue_index, uint8_t flow_type)
{
@@ -25,10 +24,11 @@ static void http_message_free(struct session *sess, void *http_msg, void *cb_arg
}
static void http_event_handler(enum http_event event, struct http_decoder_half_data **data,
- struct http_event_context *ev_ctx)
+ struct http_event_context *ev_ctx, void *httpd_plugin_env)
{
assert(ev_ctx);
-
+ assert(httpd_plugin_env);
+ struct http_decoder_env *httpd_env = (struct http_decoder_env *)httpd_plugin_env;
size_t queue_idx = 0;
nmx_pool_t *mempool = ev_ctx->ref_mempool;
struct http_decoder_result_queue *queue = ev_ctx->ref_queue;
@@ -37,10 +37,14 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
int ret = 0;
u_int8_t flow_flag = 0;
+ int thread_id = stellar_get_current_thread_id(httpd_env->st);
+
if(http_event_is_req(event)){
queue_idx = http_decoder_result_queue_req_index(queue);
+ half_data = http_decoder_result_queue_peek_req(queue);
}else{
queue_idx = http_decoder_result_queue_res_index(queue);
+ half_data = http_decoder_result_queue_peek_res(queue);
}
switch (event)
@@ -70,10 +74,18 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
}
*data = half_data;
queue_idx = http_decoder_result_queue_req_index(queue); //get the index after inc
+#if 1 /* llhttp always call on_message_begin() even if llhttp_execute() error!!! */
msg = http_message_new(HTTP_TRANSACTION_NEW, queue, queue_idx, HTTP_REQUEST);
- session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TRANSACTION_NEW, 1);
+#endif
break;
case HTTP_EVENT_REQ_LINE:
+#if 0
+ msg = http_message_new(HTTP_TRANSACTION_NEW, queue, queue_idx, HTTP_REQUEST);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TRANSACTION_NEW, 1);
+#endif
msg = http_message_new(HTTP_MESSAGE_REQ_LINE, queue, queue_idx, HTTP_REQUEST);
session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
break;
@@ -92,7 +104,14 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
}
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, ev_ctx->topic_id, msg);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+
+ int tot_c2s_headers = http_half_data_get_total_parsed_header_count(half_data);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_HEADERS_C2S, tot_c2s_headers);
+
+ struct hstring tmp_url = {};
+ http_half_data_get_url(half_data, &tmp_url);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_URL_BYTES, tmp_url.str_len);
}
break;
case HTTP_EVENT_REQ_BODY_BEGIN:
@@ -108,12 +127,14 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
break;
case HTTP_EVENT_REQ_END:
{
- if(0 == session_is_symmetric(ev_ctx->ref_session, &flow_flag)){
- if(SESSION_SEEN_C2S_FLOW == flow_flag){
- msg = http_message_new(HTTP_TRANSACTION_FREE, queue, queue_idx, HTTP_REQUEST);
- session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
- }
+ session_is_symmetric(ev_ctx->ref_session, &flow_flag);
+ if(SESSION_SEEN_C2S_FLOW == flow_flag){
+ msg = http_message_new(HTTP_TRANSACTION_FREE, queue, queue_idx, HTTP_REQUEST);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TRANSACTION_FREE, 1);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ASYMMETRY_TRANSACTION_C2S, 1);
}
+ http_half_update_state(half_data, event);
http_decoder_result_queue_inc_req_index(queue);
half_data = http_decoder_result_queue_pop_req(queue);
if (half_data != NULL)
@@ -161,10 +182,11 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
break;
case HTTP_EVENT_RES_HDR:
- msg = http_message_new(HTTP_MESSAGE_RES_HEADER, queue, queue_idx, HTTP_REQUEST);
+ msg = http_message_new(HTTP_MESSAGE_RES_HEADER, queue, queue_idx, HTTP_RESPONSE);
session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
break;
case HTTP_EVENT_RES_HDR_END:
+ {
/* 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)){
@@ -174,6 +196,10 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
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, ev_ctx->topic_id, msg);
+
+ int tot_s2c_headers = http_half_data_get_total_parsed_header_count(half_data);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_HEADERS_S2C, tot_s2c_headers);
+ }
break;
case HTTP_EVENT_RES_BODY_BEGIN:
break;
@@ -188,6 +214,12 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
case HTTP_EVENT_RES_END:
msg = http_message_new(HTTP_TRANSACTION_FREE, queue, queue_idx, HTTP_RESPONSE);
session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TRANSACTION_FREE, 1);
+ session_is_symmetric(ev_ctx->ref_session, &flow_flag);
+ if(SESSION_SEEN_S2C_FLOW == flow_flag){
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ASYMMETRY_TRANSACTION_S2C, 1);
+ }
+ http_half_update_state(half_data, event);
http_decoder_result_queue_inc_res_index(queue);
half_data = http_decoder_result_queue_pop_res(queue);
if (half_data != NULL)
@@ -200,14 +232,17 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d
assert(0);
break;
}
+ if(half_data){
+ http_half_update_state(half_data, event);
+ }
}
-static struct http_decoder *http_decoder_new(nmx_pool_t *mempool, http_event_cb *ev_cb, int decompress_switch)
+static struct http_decoder *http_decoder_new(nmx_pool_t *mempool, http_event_cb *ev_cb, int decompress_switch, struct http_decoder_env *httpd_env)
{
struct http_decoder *decoder = MEMPOOL_CALLOC(mempool, struct http_decoder, 1);
assert(decoder);
- decoder->c2s_half = http_decoder_half_new(mempool, ev_cb, HTTP_REQUEST, decompress_switch);
- decoder->s2c_half = http_decoder_half_new(mempool, ev_cb, HTTP_RESPONSE, decompress_switch);
+ decoder->c2s_half = http_decoder_half_new(mempool, ev_cb, HTTP_REQUEST, decompress_switch, httpd_env);
+ decoder->s2c_half = http_decoder_half_new(mempool, ev_cb, HTTP_RESPONSE, decompress_switch, httpd_env);
return decoder;
}
@@ -230,11 +265,12 @@ static void http_decoder_free(nmx_pool_t *mempool, struct http_decoder *decoder)
MEMPOOL_FREE(mempool, decoder);
}
-static struct http_decoder_exdata *http_decoder_exdata_new(size_t mempool_size, size_t queue_size,int decompress_switch)
+static struct http_decoder_exdata *http_decoder_exdata_new(size_t mempool_size, size_t queue_size,
+ int decompress_switch, struct http_decoder_env *httpd_env)
{
struct http_decoder_exdata *ex_data = CALLOC(struct http_decoder_exdata, 1);
ex_data->mempool = nmx_create_pool(mempool_size);
- ex_data->decoder = http_decoder_new(ex_data->mempool, http_event_handler, decompress_switch);
+ ex_data->decoder = http_decoder_new(ex_data->mempool, http_event_handler, decompress_switch, httpd_env);
ex_data->queue = http_decoder_result_queue_new(ex_data->mempool, queue_size);
return ex_data;
}
@@ -277,26 +313,27 @@ static int http_protocol_identify(const char *data, size_t data_len)
return 0;
}
-static void _http_decoder_context_free(struct http_decoder_context *ctx)
+static void _http_decoder_context_free(struct http_decoder_env *env)
{
- if (NULL == ctx)
+ if (NULL == env)
{
return;
}
-
- if (ctx->fse != NULL)
+ if (env->hd_stat.fse != NULL)
{
- fieldstat_easy_free(ctx->fse);
- ctx->fse = NULL;
+ fieldstat_easy_free(env->hd_stat.fse);
+ env->hd_stat.fse = NULL;
}
- if (ctx->httpd_msg_topic_id >= 0)
+ http_decoder_stat_free(&env->hd_stat);
+
+ if (env->httpd_msg_topic_id >= 0)
{
- stellar_session_mq_destroy_topic(ctx->st, ctx->httpd_msg_topic_id);
- ctx->httpd_msg_topic_id = -1;
+ stellar_session_mq_destroy_topic(env->st, env->httpd_msg_topic_id);
+ env->httpd_msg_topic_id = -1;
}
- FREE(ctx);
+ FREE(env);
}
static int load_http_decoder_config(const char *cfg_path,
@@ -444,8 +481,7 @@ extern "C"
{
#endif
- void _httpd_ex_data_free_cb(struct session *s, int idx,
- void *ex_data, void *arg)
+ void _httpd_ex_data_free_cb(struct session *s, int idx, void *ex_data, void *arg)
{
if (NULL == ex_data)
{
@@ -459,40 +495,63 @@ extern "C"
{
// If not http, ignore this session
size_t payload_len;
- const struct http_decoder_context *httpd_env = (struct http_decoder_context *)plugin_env;
+ struct http_decoder_env *httpd_env = (struct http_decoder_env *)plugin_env;
const char *payload = session_get0_current_payload(sess, &payload_len);
if (payload != NULL && payload_len > 0)
{
- size_t http_identify_len = payload_len > HTTP_IDENTIFY_LEN
- ? HTTP_IDENTIFY_LEN
- : payload_len;
-
+ size_t http_identify_len = payload_len > HTTP_IDENTIFY_LEN ? HTTP_IDENTIFY_LEN : payload_len;
int ret = http_protocol_identify(payload, http_identify_len);
if (ret < 0)
{
stellar_session_plugin_dettach_current_session(sess);
- return NULL;
+ return (void *)"not_http_session";
}
}
struct http_decoder_exdata *ex_data = http_decoder_exdata_new(httpd_env->hd_cfg.mempool_size,
httpd_env->hd_cfg.result_queue_len,
- httpd_env->hd_cfg.decompress_switch);
+ httpd_env->hd_cfg.decompress_switch,
+ httpd_env);
session_exdata_set(sess, httpd_env->ex_data_idx, ex_data);
+ int thread_id = stellar_get_current_thread_id(httpd_env->st);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_SESSION_NEW, 1);
+
return (void *)"fake_http_decoder_ctx"; // http decoder not use ctx, use exdata only!
}
void _httpd_session_ctx_free_cb(struct session *sess, void *session_ctx, void *plugin_env)
{
- // done in _httpd_ex_data_free_cb()
+ if(NULL == plugin_env || NULL == session_ctx){
+ return;
+ }
+ if(strncmp((const char *)session_ctx, "not_http_session", strlen("not_http_session")) == 0){
+ return;
+ }
+ struct http_decoder_env *httpd_env = (struct http_decoder_env *)plugin_env;
+ int thread_id = stellar_get_current_thread_id(httpd_env->st);
+ unsigned char flow_flag = 0;
+ session_is_symmetric(sess, &flow_flag);
+
+ if(SESSION_SEEN_C2S_FLOW == flow_flag){
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ASYMMETRY_SESSION_C2S, 1);
+ }else if(SESSION_SEEN_S2C_FLOW == flow_flag){
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ASYMMETRY_SESSION_S2C, 1);
+ }else{
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_SESSION_FREE, 1);
+ }
}
void http_decoder_tcp_stream_msg_cb(struct session *sess, int topic_id, const void *msg, void *no_use_ctx, void *plugin_env)
{
- struct http_decoder_context *httpd_env = (struct http_decoder_context *)plugin_env;
+ struct http_decoder_env *httpd_env = (struct http_decoder_env *)plugin_env;
struct http_decoder_exdata *ex_data = (struct http_decoder_exdata *)session_exdata_get(sess, httpd_env->ex_data_idx);
size_t payload_len;
+ if(SESSION_STATE_CLOSING == session_get_current_state(sess)){
+ http_half_pre_context_free(sess, httpd_env, ex_data);
+ return;
+ }
+
const char *payload = session_get0_current_payload(sess, &payload_len);
if (unlikely(0 == payload_len || NULL == ex_data))
{
@@ -505,10 +564,14 @@ extern "C"
if (PACKET_DIRECTION_C2S == packet_get_direction(session_get0_current_packet(sess)))
{
cur_half = ex_data->decoder->c2s_half;
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_BYTES_C2S, payload_len);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TCP_SEG_C2S, 1);
}
else
{
cur_half = ex_data->decoder->s2c_half;
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_BYTES_S2C, payload_len);
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TCP_SEG_S2C, 1);
}
http_decoder_half_reinit(cur_half, httpd_env->httpd_msg_topic_id, ex_data->queue,
@@ -516,14 +579,9 @@ extern "C"
int ret = http_decoder_half_parse(cur_half, payload, payload_len);
if (ret < 0)
{
- _th_stat.err_pkts += 1;
+ http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_PARSE_ERR, 1);
+ stellar_session_plugin_dettach_current_session(sess);
}
- _th_stat.incoming_bytes += payload_len;
- _th_stat.incoming_pkts += 1;
- _th_stat.incoming_trans += http_decoder_half_trans_count(cur_half);
- _th_stat.counter++;
-
- http_decoder_stat_output(httpd_env, thread_id);
return;
}
@@ -532,7 +590,7 @@ extern "C"
int httpd_msg_topic_id = -1, tcp_stream_topic_id = -1;
int thread_num = 0;
- struct http_decoder_context *httpd_env = CALLOC(struct http_decoder_context, 1);
+ struct http_decoder_env *httpd_env = CALLOC(struct http_decoder_env, 1);
int ret = load_http_decoder_config(HTTPD_CFG_FILE, &httpd_env->hd_cfg);
if (ret < 0)
{
@@ -563,7 +621,8 @@ extern "C"
thread_num = stellar_get_worker_thread_num(st);
assert(thread_num >= 1);
- if (http_decoder_stat_init(httpd_env, thread_num) < 0)
+ if (http_decoder_stat_init( &httpd_env->hd_stat, thread_num,
+ httpd_env->hd_cfg.stat_interval_pkts, httpd_env->hd_cfg.stat_output_interval) < 0)
{
goto failed;
}
@@ -584,7 +643,7 @@ extern "C"
{
return;
}
- struct http_decoder_context *httpd_env = (struct http_decoder_context *)plugin_env;
+ struct http_decoder_env *httpd_env = (struct http_decoder_env *)plugin_env;
_http_decoder_context_free(httpd_env);
}
diff --git a/src/http_decoder_half.cpp b/src/http_decoder_half.cpp
index d3c2ee2..441ff2c 100644
--- a/src/http_decoder_half.cpp
+++ b/src/http_decoder_half.cpp
@@ -13,6 +13,8 @@ struct http_decoder_half_data
int minor_version;
int status_code;
+ enum http_event state;
+
enum http_content_encoding content_encoding;
struct http_content_decompress *decompress;
char *ref_decompress_body;
@@ -29,6 +31,7 @@ struct http_decoder_half
llhttp_settings_t settings;
enum llhttp_errno error;
int decompress_switch;
+ struct http_decoder_env *httpd_env;
// uint8_t is_request_flow;
enum http_event event;
@@ -103,8 +106,7 @@ 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);
+ struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
if (half->parser.type == HTTP_REQUEST)
@@ -119,7 +121,7 @@ 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); // http_event_handler()
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env); // http_event_handler()
half->trans_counter++;
half->ref_data->transaction_index = half->transaction_seq++;
@@ -138,7 +140,7 @@ static int on_message_complete(llhttp_t *http)
if (half->event == HTTP_EVENT_REQ_BODY_DATA)
{
half->event = HTTP_EVENT_REQ_BODY_END;
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
}
}
else
@@ -146,7 +148,7 @@ static int on_message_complete(llhttp_t *http)
if (half->event == HTTP_EVENT_RES_BODY_DATA)
{
half->event = HTTP_EVENT_RES_BODY_END;
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
}
}
@@ -154,12 +156,12 @@ static int on_message_complete(llhttp_t *http)
if (half->parser.type == HTTP_REQUEST)
{
half->event = HTTP_EVENT_REQ_END;
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
}
else
{
half->event = HTTP_EVENT_RES_END;
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
}
return 0;
@@ -187,12 +189,10 @@ 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);
+ 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_decoder_table_refer(half->ref_data->table, HTTP_ITEM_METHOD, at, length);
return 0;
}
@@ -201,8 +201,7 @@ 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);
+ struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
if (is_line_crlf(half) == 0)
@@ -220,12 +219,10 @@ static int on_uri(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_uri", at, length);
- struct http_decoder_half *half =
- container_of(http, struct http_decoder_half, parser);
+ 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_decoder_table_refer(half->ref_data->table, HTTP_ITEM_URI, at, length);
return 0;
}
@@ -254,8 +251,7 @@ 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);
+ struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
if (is_line_crlf(half) == 0)
@@ -278,12 +274,10 @@ static int on_version(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_version", at, length);
- struct http_decoder_half *half =
- container_of(http, struct http_decoder_half, parser);
+ 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_VERSION,
- at, length);
+ http_decoder_table_refer(half->ref_data->table, HTTP_ITEM_VERSION, at, length);
return 0;
}
@@ -292,8 +286,7 @@ 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);
+ struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
if (is_line_crlf(half) == 0)
@@ -311,7 +304,7 @@ static int on_version_complete(llhttp_t *http)
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->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
}
}
@@ -323,12 +316,10 @@ 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);
+ 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_decoder_table_refer(half->ref_data->table, HTTP_ITEM_STATUS, at, length);
return 0;
}
@@ -337,8 +328,7 @@ 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);
+ struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
if (is_line_crlf(half) == 0)
@@ -354,7 +344,7 @@ static int on_status_complete(llhttp_t *http)
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->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
}
}
@@ -366,12 +356,10 @@ static int on_header_field(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_header_field", at, length);
- struct http_decoder_half *half =
- container_of(http, struct http_decoder_half, parser);
+ 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_decoder_table_refer(half->ref_data->table, HTTP_ITEM_HDRKEY, at, length);
return 0;
}
@@ -380,8 +368,7 @@ 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);
+ 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);
@@ -394,12 +381,10 @@ static int on_header_value(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_header_value", at, length);
- struct http_decoder_half *half =
- container_of(http, struct http_decoder_half, parser);
+ 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_decoder_table_refer(half->ref_data->table, HTTP_ITEM_HDRVAL, at, length);
return 0;
}
@@ -409,8 +394,7 @@ static int on_header_value_complete(llhttp_t *http)
{
printf_debug_info("on_header_value_complete", NULL, 0);
- struct http_decoder_half *half =
- container_of(http, struct http_decoder_half, parser);
+ 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) ==
@@ -439,8 +423,10 @@ static int on_header_value_complete(llhttp_t *http)
}
}
- http_decoder_get_host_feed_url(half);
-
+ if(http->type == HTTP_REQUEST)
+ {
+ http_decoder_get_host_feed_url(half);
+ }
return 0;
}
@@ -476,8 +462,7 @@ 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);
+ struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
assert(half->ref_data);
@@ -491,7 +476,7 @@ 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); // http_event_handler()
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env); // http_event_handler()
return 0;
}
@@ -501,8 +486,7 @@ static int on_body(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_body", at, length);
- struct http_decoder_half *half =
- container_of(http, struct http_decoder_half, parser);
+ struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
// trigger body_begin event
@@ -511,7 +495,7 @@ static int on_body(llhttp_t *http, const char *at, size_t length)
if (half->event == HTTP_EVENT_REQ_HDR_END)
{
half->event = HTTP_EVENT_REQ_BODY_BEGIN;
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); // http_event_handler()
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env); // http_event_handler()
}
}
else
@@ -519,7 +503,7 @@ static int on_body(llhttp_t *http, const char *at, size_t length)
if (half->event == HTTP_EVENT_RES_HDR_END)
{
half->event = HTTP_EVENT_RES_BODY_BEGIN;
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
}
}
@@ -531,8 +515,7 @@ static int on_body(llhttp_t *http, const char *at, size_t length)
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_refer(half->ref_data->table, HTTP_ITEM_BODY, at, length);
http_decoder_table_commit(half->ref_data->table, HTTP_ITEM_BODY);
}
@@ -545,12 +528,12 @@ static int on_body(llhttp_t *http, const char *at, size_t length)
if (half->parser.type == HTTP_REQUEST)
{
half->event = HTTP_EVENT_REQ_BODY_DATA;
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); // http_event_handler()
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env); // http_event_handler()
}
else
{
half->event = HTTP_EVENT_RES_BODY_DATA;
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env);
}
return 0;
@@ -596,9 +579,8 @@ static void http_decoder_half_init(struct http_decoder_half *half,
half->ref_data = NULL;
}
-struct http_decoder_half *
-http_decoder_half_new(nmx_pool_t *mempool, http_event_cb *ev_cb, enum llhttp_type http_type,
- int decompress_switch)
+struct http_decoder_half * http_decoder_half_new(nmx_pool_t *mempool, http_event_cb *ev_cb, enum llhttp_type http_type,
+ int decompress_switch, struct http_decoder_env *httpd_env)
{
struct http_decoder_half *half = MEMPOOL_CALLOC(mempool, struct http_decoder_half, 1);
assert(half);
@@ -607,6 +589,7 @@ http_decoder_half_new(nmx_pool_t *mempool, http_event_cb *ev_cb, enum llhttp_typ
half->http_ev_ctx = MEMPOOL_CALLOC(mempool, struct http_event_context, 1);
http_decoder_half_init(half, ev_cb, http_type);
+ half->httpd_env = httpd_env;
return half;
}
@@ -653,17 +636,13 @@ static void publish_message_for_parsed_header(struct http_decoder_half *half)
}else{
half->event = HTTP_EVENT_RES_HDR;
}
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); // http_event_handler();
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx, half->httpd_env); // http_event_handler();
return;
}
-int http_decoder_half_parse(struct http_decoder_half *half, const char *data,
- size_t data_len)
+int http_decoder_half_parse(struct http_decoder_half *half, const char *data, size_t data_len)
{
- if (NULL == half || NULL == data || 0 == data_len)
- {
- return -1;
- }
+ assert(half && data);
half->data = (const char *)data;
half->data_len = data_len;
@@ -812,8 +791,7 @@ http_decoder_half_data_new(nmx_pool_t *mempool)
return data;
}
-void http_decoder_half_data_free(nmx_pool_t *mempool,
- struct http_decoder_half_data *data)
+void http_decoder_half_data_free(nmx_pool_t *mempool, struct http_decoder_half_data *data)
{
if (NULL == data)
{
@@ -838,7 +816,6 @@ void http_decoder_half_data_free(nmx_pool_t *mempool,
data->joint_url.str = NULL;
data->joint_url_complete = 0;
}
-
MEMPOOL_FREE(mempool, data);
}
@@ -1049,4 +1026,45 @@ 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)
{
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);
+}
+
+void http_half_pre_context_free(struct session *sess, struct http_decoder_env *httpd_env,
+ struct http_decoder_exdata *ex_data)
+{
+ if (NULL == ex_data)
+ {
+ return;
+ }
+ struct http_message *msg = NULL;
+ struct http_decoder_half_data *req_data;
+ struct http_decoder_half_data *res_data;
+ struct http_decoder_result_queue *queue = ex_data->queue;
+ for(int i = 0; i < queue->queue_size; i++){
+ req_data = queue->array[i].req_data;
+ res_data = queue->array[i].res_data;
+ if ((req_data != NULL) && (NULL == res_data) && (req_data->state < HTTP_EVENT_REQ_END))
+ {
+ msg = http_message_new(HTTP_TRANSACTION_FREE, queue, i, HTTP_REQUEST);
+ session_mq_publish_message(sess, httpd_env->httpd_msg_topic_id, msg);
+ }
+ }
+
+ for(int i = 0; i < queue->queue_size; i++){
+ res_data = queue->array[i].res_data;
+ if ((res_data != NULL) && (res_data->state < HTTP_EVENT_RES_END))
+ {
+ msg = http_message_new(HTTP_TRANSACTION_FREE, queue, i, HTTP_RESPONSE);
+ session_mq_publish_message(sess, httpd_env->httpd_msg_topic_id, msg);
+ }
+ }
+}
+
+void http_half_update_state(struct http_decoder_half_data *hf_data, enum http_event state)
+{
+ hf_data->state = state;
} \ No newline at end of file
diff --git a/src/http_decoder_half.h b/src/http_decoder_half.h
index 362708a..e918e6e 100644
--- a/src/http_decoder_half.h
+++ b/src/http_decoder_half.h
@@ -40,11 +40,11 @@ struct http_decoder_half;
struct http_decoder_half_data;
typedef void http_event_cb(enum http_event event, struct http_decoder_half_data **data,
- struct http_event_context *ev_ctx);
+ struct http_event_context *ev_ctx, void *httpd_plugin_env);
struct http_decoder_half *
http_decoder_half_new(nmx_pool_t *mempool, http_event_cb *event_cb, enum llhttp_type http_type,
- int decompress_switch);
+ int decompress_switch, struct http_decoder_env *httpd_env);
void http_decoder_half_free(nmx_pool_t *mempool, struct http_decoder_half *half);
@@ -52,8 +52,7 @@ void http_decoder_half_reinit(struct http_decoder_half *half, int topic_id,
struct http_decoder_result_queue *queue,
nmx_pool_t *mempool, struct session *sess);
-int http_decoder_half_parse(struct http_decoder_half *half, const char *data,
- size_t data_len);
+int http_decoder_half_parse(struct http_decoder_half *half, const char *data, size_t data_len);
long long http_decoder_half_trans_count(struct http_decoder_half *half);
@@ -61,8 +60,7 @@ long long http_decoder_half_trans_count(struct http_decoder_half *half);
struct http_decoder_half_data *
http_decoder_half_data_new(nmx_pool_t *mempool);
-void http_decoder_half_data_free(nmx_pool_t *mempool,
- struct http_decoder_half_data *data);
+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);
@@ -78,11 +76,9 @@ int http_decoder_half_data_iter_header(struct http_decoder_half_data *data,
int http_decoder_half_data_reset_header_iter(struct http_decoder_half_data *req_data);
int http_decoder_half_data_has_parsed_header(struct http_decoder_half_data *data);
-int http_decoder_half_data_get_raw_body(const struct http_decoder_half_data *data,
- struct hstring *body);
+int http_decoder_half_data_get_raw_body(const struct http_decoder_half_data *data, struct hstring *body);
-int http_decoder_half_data_get_decompress_body(const struct http_decoder_half_data *data,
- struct hstring *body);
+int http_decoder_half_data_get_decompress_body(const struct http_decoder_half_data *data, struct hstring *body);
void http_decoder_half_data_dump(struct http_decoder_half *half);
@@ -97,4 +93,8 @@ int http_half_data_get_url(struct http_decoder_half_data *res_data, struct hstri
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_env *httpd_env,
+ struct http_decoder_exdata *ex_data);
+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);
#endif \ No newline at end of file
diff --git a/src/http_decoder_inc.h b/src/http_decoder_inc.h
index 3e2939d..760eaba 100644
--- a/src/http_decoder_inc.h
+++ b/src/http_decoder_inc.h
@@ -11,6 +11,7 @@
#ifndef _HTTP_DECODER_INC_H_
#define _HTTP_DECODER_INC_H_
+#include <cstddef>
#ifdef __cplusplus
extern "C"
{
@@ -61,7 +62,7 @@ extern "C"
#define DEFAULT_MEMPOOL_SIZE (32 * 1024)
#define HTTPD_CFG_FILE "./etc/http/http_decoder.toml"
-#define FILEDSTAT_OUTPUT_FILE "./http_decoder.fs"
+#define FILEDSTAT_OUTPUT_FILE "./http_decoder.fs4"
struct http_decoder_config
{
@@ -96,27 +97,14 @@ struct http_decoder_exdata
nmx_pool_t *mempool;
};
-struct http_decoder_stat
-{
- long long incoming_bytes;
- long long incoming_pkts;
- long long incoming_trans;
- long long err_pkts;
- int counter;
-};
-
-struct http_decoder_context
+struct http_decoder_env
{
int plugin_id;
int httpd_msg_topic_id;
int ex_data_idx;
- int fs_incoming_bytes_id;
- int fs_incoming_pkts_id;
- int fs_incoming_trans_id;
- int fs_err_pkts_id;
struct stellar *st;
- struct fieldstat_easy *fse;
struct http_decoder_config hd_cfg;
+ struct http_decoder_stat hd_stat;
};
struct http_message;
diff --git a/src/http_decoder_result_queue.cpp b/src/http_decoder_result_queue.cpp
index 32d2895..6a5e003 100644
--- a/src/http_decoder_result_queue.cpp
+++ b/src/http_decoder_result_queue.cpp
@@ -26,8 +26,7 @@ http_decoder_result_queue_new(nmx_pool_t *mempool, size_t queue_size)
return queue;
}
-void http_decoder_result_queue_free(nmx_pool_t *mempool,
- struct http_decoder_result_queue *queue)
+void http_decoder_result_queue_free(nmx_pool_t *mempool, struct http_decoder_result_queue *queue)
{
if (NULL == queue) {
return;
@@ -111,10 +110,8 @@ http_decoder_result_queue_pop_req(struct http_decoder_result_queue *queue)
if (NULL == queue) {
return NULL;
}
- struct http_decoder_half_data *req_data =
- queue->array[queue->req_index].req_data;
+ struct http_decoder_half_data *req_data = queue->array[queue->req_index].req_data;
queue->array[queue->req_index].req_data = NULL;
-
return req_data;
}
@@ -125,10 +122,8 @@ http_decoder_result_queue_pop_res(struct http_decoder_result_queue *queue)
return NULL;
}
- struct http_decoder_half_data *res_data =
- queue->array[queue->res_index].res_data;
+ struct http_decoder_half_data *res_data = queue->array[queue->res_index].res_data;
queue->array[queue->res_index].res_data = NULL;
-
return res_data;
}
diff --git a/src/http_decoder_stat.cpp b/src/http_decoder_stat.cpp
index ffa01eb..dfd1a2e 100644
--- a/src/http_decoder_stat.cpp
+++ b/src/http_decoder_stat.cpp
@@ -3,56 +3,61 @@
#include <unistd.h>
#include "http_decoder_inc.h"
-static __thread struct http_decoder_stat _th_stat;
-
-int http_decoder_stat_init(struct http_decoder_context *ctx, int thread_num)
+static const struct hd_stat_config_tuple g_httpd_stat_tuple[HTTPD_STAT_MAX] =
{
- ctx->fse = fieldstat_easy_new(thread_num, "http_decoder_statistics", NULL, 0);
- if (NULL == ctx->fse)
- {
- fprintf(stderr, "fieldstat_easy_new failed.");
- return -1;
- }
-
- ctx->fs_incoming_bytes_id =
- fieldstat_easy_register_counter(ctx->fse, "incoming_bytes");
- if (ctx->fs_incoming_bytes_id < 0)
- {
- fprintf(stderr, "fieldstat_easy_register_counter incoming_bytes failed.");
- return -1;
- }
-
- ctx->fs_incoming_trans_id =
- fieldstat_easy_register_counter(ctx->fse, "incoming_trans");
- if (ctx->fs_incoming_trans_id < 0)
- {
- fprintf(stderr, "fieldstat_easy_register_counter incoming_trans failed.");
- return -1;
+ {HTTPD_STAT_BYTES_C2S, "bytes_c2s"},
+ {HTTPD_STAT_BYTES_S2C, "bytes_s2c"},
+ {HTTPD_STAT_TCP_SEG_C2S, "tcp_seg_c2s"},
+ {HTTPD_STAT_TCP_SEG_S2C, "tcp_seg_s2c"},
+ {HTTPD_STAT_HEADERS_C2S, "headers_c2s"},
+ {HTTPD_STAT_HEADERS_S2C, "headers_s2c"},
+ {HTTPD_STAT_URL_BYTES, "url_bytes"},
+ {HTTPD_STAT_SESSION_NEW, "session_new"},
+ {HTTPD_STAT_SESSION_FREE, "session_free"},
+ {HTTPD_STAT_SESSION_EXCEPTION, "sess_exception"},
+ {HTTPD_STAT_TRANSACTION_NEW, "trans_new"},
+ {HTTPD_STAT_TRANSACTION_FREE, "trans_free"},
+ {HTTPD_STAT_ASYMMETRY_SESSION_C2S, "asymmetry_sess_c2s"},
+ {HTTPD_STAT_ASYMMETRY_SESSION_S2C, "asymmetry_sess_s2c"},
+ {HTTPD_STAT_ASYMMETRY_TRANSACTION_C2S, "asymmetry_trans_c2s"},
+ {HTTPD_STAT_ASYMMETRY_TRANSACTION_S2C, "asymmetry_trans_s2c"},
+ {HTTPD_STAT_PARSE_ERR, "parse_err"},
+};
+
+void http_decoder_stat_free(struct http_decoder_stat *hd_stat)
+{
+ if(hd_stat->stats != NULL){
+ free(hd_stat->stats);
}
-
- ctx->fs_incoming_pkts_id =
- fieldstat_easy_register_counter(ctx->fse, "incoming_pkts");
- if (ctx->fs_incoming_pkts_id < 0)
- {
- fprintf(stderr, "fieldstat_easy_register_counter incoming_pkts failed.");
- return -1;
+ if(hd_stat->fse != NULL){
+ fieldstat_easy_free(hd_stat->fse);
}
+}
- ctx->fs_err_pkts_id = fieldstat_easy_register_counter(ctx->fse, "err_pkts");
- if (ctx->fs_err_pkts_id < 0)
+int http_decoder_stat_init(struct http_decoder_stat *hd_stat, int thread_max, int stat_interval_pkts, int stat_interval_time)
+{
+ assert(sizeof(g_httpd_stat_tuple)/sizeof(struct hd_stat_config_tuple) == HTTPD_STAT_MAX);
+ hd_stat->fse = fieldstat_easy_new(thread_max, "http_decoder_statistics", NULL, 0);
+ if (NULL == hd_stat->fse)
{
- fprintf(stderr, "fieldstat_easy_register_counter err_pkts failed.");
+ fprintf(stderr, "fieldstat_easy_new failed.");
return -1;
}
- int stat_output_interval = DEFAULT_STAT_OUTPUT_INTERVAL;
- if (ctx->hd_cfg.stat_output_interval > 0)
+ for(int i = 0; i < HTTPD_STAT_MAX; i++)
{
- stat_output_interval = ctx->hd_cfg.stat_output_interval;
+ hd_stat->field_stat_id[i] = fieldstat_easy_register_counter(hd_stat->fse, g_httpd_stat_tuple[i].name);
+ if (hd_stat->field_stat_id[i] < 0)
+ {
+ fprintf(stderr, "fieldstat_easy_register_counter %s failed.", g_httpd_stat_tuple[i].name);
+ return -1;
+ }
}
- int ret = fieldstat_easy_enable_auto_output(ctx->fse, FILEDSTAT_OUTPUT_FILE,
- stat_output_interval);
+ hd_stat->stats = (struct hd_statistics *)calloc(thread_max, sizeof(struct hd_statistics));
+ hd_stat->stat_interval_pkts = stat_interval_pkts;
+
+ int ret = fieldstat_easy_enable_auto_output(hd_stat->fse, FILEDSTAT_OUTPUT_FILE, stat_interval_time);
if (ret < 0)
{
fprintf(stderr, "fieldstat_easy_enable_auto_output failed.");
@@ -62,38 +67,21 @@ int http_decoder_stat_init(struct http_decoder_context *ctx, int thread_num)
return 0;
}
-void http_decoder_stat_output(struct http_decoder_context *ctx, int thread_id)
+void http_decoder_stat_update(struct http_decoder_stat *hd_stat, int thread_id, enum http_decoder_stat_type type, long long value)
{
- assert(ctx != NULL);
-
- int stat_interval_pkts = DEFAULT_STAT_INTERVAL_PKTS;
- if (ctx->hd_cfg.stat_interval_pkts > 0)
- {
- stat_interval_pkts = ctx->hd_cfg.stat_interval_pkts;
- }
-
- if (_th_stat.counter >= stat_interval_pkts)
- {
- fieldstat_easy_counter_incrby(ctx->fse, thread_id,
- ctx->fs_incoming_bytes_id, NULL, 0,
- _th_stat.incoming_bytes);
-
- fieldstat_easy_counter_incrby(ctx->fse, thread_id,
- ctx->fs_incoming_pkts_id, NULL, 0,
- _th_stat.incoming_pkts);
-
- fieldstat_easy_counter_incrby(ctx->fse, thread_id,
- ctx->fs_incoming_trans_id, NULL, 0,
- _th_stat.incoming_trans);
-
- fieldstat_easy_counter_incrby(ctx->fse, thread_id,
- ctx->fs_err_pkts_id, NULL, 0,
- _th_stat.err_pkts);
-
- _th_stat.counter = 0;
- _th_stat.err_pkts = 0;
- _th_stat.incoming_bytes = 0;
- _th_stat.incoming_pkts = 0;
- _th_stat.incoming_trans = 0;
+ assert(hd_stat);
+ assert(thread_id >= 0);
+ assert(type < HTTPD_STAT_MAX);
+
+ hd_stat->stats[thread_id].counter[type] += value;
+ hd_stat->stats[thread_id].batch++;
+
+ if(hd_stat->stats[thread_id].batch >= hd_stat->stat_interval_pkts){
+ for(int i = 0; i < HTTPD_STAT_MAX; i++){
+ //update all type, maybe decrease performance ?
+ fieldstat_easy_counter_incrby(hd_stat->fse, thread_id, hd_stat->field_stat_id[i], NULL, 0, hd_stat->stats[thread_id].counter[i]);
+ hd_stat->stats[thread_id].counter[i] = 0;
+ }
+ hd_stat->stats[thread_id].batch = 0;
}
}
diff --git a/src/http_decoder_stat.h b/src/http_decoder_stat.h
index dbf245f..235475d 100644
--- a/src/http_decoder_stat.h
+++ b/src/http_decoder_stat.h
@@ -1,5 +1,59 @@
#ifndef _HTTP_DECODER_STAT_H_
#define _HTTP_DECODER_STAT_H_ 1
-int http_decoder_stat_init(struct http_decoder_context *ctx, int thread_num);
-void http_decoder_stat_output(struct http_decoder_context *ctx, int thread_id);
+
+#include <fieldstat/fieldstat_easy.h>
+enum http_decoder_stat_type
+{
+ HTTPD_STAT_BYTES_C2S = 0,
+ HTTPD_STAT_BYTES_S2C,
+ HTTPD_STAT_TCP_SEG_C2S,
+ HTTPD_STAT_TCP_SEG_S2C,
+ HTTPD_STAT_HEADERS_C2S,
+ HTTPD_STAT_HEADERS_S2C,
+ HTTPD_STAT_URL_BYTES,
+ HTTPD_STAT_SESSION_NEW,
+ HTTPD_STAT_SESSION_FREE,
+ HTTPD_STAT_SESSION_EXCEPTION, // rst, kickout, lost packet, etc.
+ HTTPD_STAT_TRANSACTION_NEW,
+ HTTPD_STAT_TRANSACTION_FREE,
+ HTTPD_STAT_ASYMMETRY_SESSION_C2S,
+ HTTPD_STAT_ASYMMETRY_SESSION_S2C,
+ HTTPD_STAT_ASYMMETRY_TRANSACTION_C2S,
+ HTTPD_STAT_ASYMMETRY_TRANSACTION_S2C,
+ HTTPD_STAT_PARSE_ERR,
+ HTTPD_STAT_MAX,
+};
+
+struct hd_stat_config_tuple
+{
+ enum http_decoder_stat_type type;
+ const char *name;
+};
+
+struct hd_statistics
+{
+ // long long incoming_bytes;
+ // long long incoming_tcp_seg;
+ // long long session_new;
+ // long long session_free;
+ // long long transaction_new;
+ // long long transaction_free;
+ // long long incoming_trans;
+ // long long err_pkts;
+
+ long long counter[HTTPD_STAT_MAX];
+ int batch; //call fieldstat_easy_counter_incrby() per batch
+}__attribute__ ((aligned (64)));
+
+struct http_decoder_stat
+{
+ struct fieldstat_easy *fse;
+ int stat_interval_pkts; // call fieldstat_incrby every stat_interval_pkts
+ int field_stat_id[HTTPD_STAT_MAX];
+ struct hd_statistics *stats; //multi thread
+};
+
+int http_decoder_stat_init(struct http_decoder_stat *hd_stat, int thread_max, int stat_interval_pkts, int stat_interval_time);
+void http_decoder_stat_free(struct http_decoder_stat *hd_stat);
+void http_decoder_stat_update(struct http_decoder_stat *hd_stat, int thread_id, enum http_decoder_stat_type type, long long value);
#endif \ No newline at end of file
diff --git a/src/http_decoder_table.cpp b/src/http_decoder_table.cpp
index b11e1b9..d1fc6e9 100644
--- a/src/http_decoder_table.cpp
+++ b/src/http_decoder_table.cpp
@@ -526,4 +526,9 @@ void http_decoder_table_reset_header_complete(struct http_decoder_table *table)
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/src/http_decoder_table.h b/src/http_decoder_table.h
index ce79d46..1272d3a 100644
--- a/src/http_decoder_table.h
+++ b/src/http_decoder_table.h
@@ -76,4 +76,5 @@ 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);
#endif \ No newline at end of file
diff --git a/test/http_decoder_gtest.cpp b/test/http_decoder_gtest.cpp
index 3956a28..b2677fc 100644
--- a/test/http_decoder_gtest.cpp
+++ b/test/http_decoder_gtest.cpp
@@ -464,7 +464,18 @@ extern "C" void http_decoder_test_state_entry(struct session *sess, int topic_id
}else{
json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES];
}
-
+ if(HTTP_TRANSACTION_FREE == msg_type){
+ unsigned char flow_flag;
+ session_is_symmetric(sess, &flow_flag);
+ if(SESSION_SEEN_C2S_FLOW == flow_flag){
+ json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ];
+ }
+ else if(SESSION_SEEN_S2C_FLOW == flow_flag){
+ json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES];
+ }else{ // is symmetric
+ json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES];
+ }
+ }
int cur_transaction_id = http_message_get_transaction_seq((const http_message* )raw_msg);
if(HTTP_TRANSACTION_NEW ==msg_type || HTTP_TRANSACTION_FREE == msg_type){
diff --git a/test/http_decoder_perf_main.cpp b/test/http_decoder_perf_main.cpp
index 1dd7734..5cfcf2c 100644
--- a/test/http_decoder_perf_main.cpp
+++ b/test/http_decoder_perf_main.cpp
@@ -106,6 +106,11 @@ void *session_exdata_get(struct session *sess, int idx)
return sess->exdata;
}
+enum session_state session_get_current_state(struct session *sess)
+{
+ return SESSION_STATE_ACTIVE;
+}
+
int stellar_session_mq_get_topic_id(struct stellar *st, const char *topic_name)
{
if(strcmp(topic_name, "HTTP_DECODER_MESSAGE") == 0){
diff --git a/test/http_pcap/http_error.pcap b/test/http_pcap/http_error.pcap
new file mode 100644
index 0000000..3ef0829
--- /dev/null
+++ b/test/http_pcap/http_error.pcap
Binary files differ
diff --git a/test/http_pcap/http_session_exception_c2s.pcap b/test/http_pcap/http_session_exception_c2s.pcap
new file mode 100644
index 0000000..eb93c24
--- /dev/null
+++ b/test/http_pcap/http_session_exception_c2s.pcap
Binary files differ
diff --git a/test/http_pcap/http_session_exception_s2c.pcap b/test/http_pcap/http_session_exception_s2c.pcap
new file mode 100644
index 0000000..d5caa49
--- /dev/null
+++ b/test/http_pcap/http_session_exception_s2c.pcap
Binary files differ
diff --git a/test/test_result_json/http_msg_type_state_exception_c2s.json b/test/test_result_json/http_msg_type_state_exception_c2s.json
new file mode 100644
index 0000000..1edf964
--- /dev/null
+++ b/test/test_result_json/http_msg_type_state_exception_c2s.json
@@ -0,0 +1,12 @@
+[
+ {
+ "msg_0": "HTTP_TRANSACTION_NEW_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"
+ },
+ {
+ "msg_5": "HTTP_TRANSACTION_FREE_transaction_0"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_msg_type_state_exception_s2c.json b/test/test_result_json/http_msg_type_state_exception_s2c.json
new file mode 100644
index 0000000..50fda4e
--- /dev/null
+++ b/test/test_result_json/http_msg_type_state_exception_s2c.json
@@ -0,0 +1,15 @@
+[
+ {
+ "msg_0": "HTTP_TRANSACTION_NEW_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_RES_LINE",
+ "msg_5": "HTTP_MESSAGE_RES_HEADER",
+ "msg_6": "HTTP_MESSAGE_RES_HEADER_END",
+ "msg_7": "HTTP_MESSAGE_RES_BODY",
+ "msg_8": "HTTP_TRANSACTION_FREE_transaction_0"
+ }
+] \ No newline at end of file
diff --git a/test_based_on_stellar/CMakeLists.txt b/test_based_on_stellar/CMakeLists.txt
index 088bfc4..29d53ac 100644
--- a/test_based_on_stellar/CMakeLists.txt
+++ b/test_based_on_stellar/CMakeLists.txt
@@ -172,9 +172,14 @@ add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_S2C_TEST COMMAND ./${TEST_MAIN} ${TES
-r ${TEST_PCAP_DIR}/http_post_s2c.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_PIPELINE_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_pipeline.json
-r ${TEST_PCAP_DIR}/http_get_multi_trans.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
-
+add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_SES_EXCEPTION_C2S_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_exception_c2s.json
+ -r ${TEST_PCAP_DIR}/http_session_exception_c2s.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_SES_EXCEPTION_S2C_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_exception_s2c.json
+ -r ${TEST_PCAP_DIR}/http_session_exception_s2c.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
set_tests_properties(STELLAR_HTTP_MSG_TYPE_STATE_TEST
STELLAR_HTTP_MSG_TYPE_STATE_C2S_TEST
STELLAR_HTTP_MSG_TYPE_STATE_S2C_TEST
STELLAR_HTTP_MSG_TYPE_STATE_PIPELINE_TEST
+ STELLAR_HTTP_MSG_TYPE_STATE_SES_EXCEPTION_C2S_TEST
+ STELLAR_HTTP_MSG_TYPE_STATE_SES_EXCEPTION_S2C_TEST
PROPERTIES FIXTURES_REQUIRED TestState) \ No newline at end of file