summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlijia <[email protected]>2024-05-24 22:47:32 +0800
committerlijia <[email protected]>2024-06-03 11:08:06 +0800
commit1c232f0176c43c93c3e787ac83f3573bf42c58f1 (patch)
tree734c31a97ec38847972b70a18ec075fd415bb5f6 /src
parent22d071e23ff423242f51dce2eab1477b5fb9d106 (diff)
Adapt to stellar2.0;update API,add HDR_END,BODY_END,TRANSACTION_NEW,FREE msg.v2.0.2
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt7
-rw-r--r--src/http_content_decompress.cpp (renamed from src/http_content_decompress.c)22
-rw-r--r--src/http_decoder.c991
-rw-r--r--src/http_decoder.cpp833
-rw-r--r--src/http_decoder_half.cpp (renamed from src/http_decoder_half.c)203
-rw-r--r--src/http_decoder_half.h33
-rw-r--r--src/http_decoder_inc.h94
-rw-r--r--src/http_decoder_result_queue.cpp (renamed from src/http_decoder_result_queue.c)19
-rw-r--r--src/http_decoder_result_queue.h12
-rw-r--r--src/http_decoder_stat.cpp99
-rw-r--r--src/http_decoder_stat.h5
-rw-r--r--src/http_decoder_string.cpp (renamed from src/http_decoder_string.c)25
-rw-r--r--src/http_decoder_string.h25
-rw-r--r--src/http_decoder_table.cpp (renamed from src/http_decoder_table.c)89
-rw-r--r--src/http_decoder_table.h35
-rw-r--r--src/http_decoder_utils.c25
-rw-r--r--src/http_decoder_utils.cpp137
-rw-r--r--src/http_decoder_utils.h26
-rw-r--r--src/version.map2
19 files changed, 1269 insertions, 1413 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 533eea8..1d3c949 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,13 +3,14 @@ add_definitions(-fPIC)
include_directories(/opt/MESA/include/)
include_directories(/opt/tsg/framework/include/)
include_directories(${PROJECT_SOURCE_DIR}/deps/)
+include_directories(${CMAKE_BINARY_DIR}/vendor/vbuild/include)
aux_source_directory(${PROJECT_SOURCE_DIR}/deps/mempool DEPS_SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml DEPS_SRC)
-set(HTTP_SRC ${DEPS_SRC} http_decoder.c http_decoder_utils.c http_decoder_half.c
- http_decoder_table.c http_decoder_string.c http_content_decompress.c
- http_decoder_result_queue.c)
+set(HTTP_SRC ${DEPS_SRC} http_decoder.cpp http_decoder_utils.cpp http_decoder_half.cpp
+ http_decoder_table.cpp http_decoder_string.cpp http_content_decompress.cpp
+ http_decoder_result_queue.cpp http_decoder_stat.cpp)
add_library(http_decoder SHARED ${HTTP_SRC})
set_target_properties(http_decoder PROPERTIES LINK_FLAGS "-Wl,--version-script=${PROJECT_SOURCE_DIR}/src/version.map")
diff --git a/src/http_content_decompress.c b/src/http_content_decompress.cpp
index 5fe08a8..e761f1d 100644
--- a/src/http_content_decompress.c
+++ b/src/http_content_decompress.cpp
@@ -7,25 +7,18 @@
* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
***********************************************************************************************
*/
-
-
#include <zlib.h>
#include <string.h>
#include <assert.h>
#include <brotli/decode.h>
-
-#include "stellar/utils.h"
-#include "http_decoder_utils.h"
-#include "http_content_decompress.h"
+#include "http_decoder_inc.h"
#define BUFFER_SIZE (16 * 1024)
struct http_content_decompress {
enum http_content_encoding encoding;
-
z_stream *z_stream_ptr;
BrotliDecoderState *br_state;
-
char *buffer;
size_t buffer_size;
};
@@ -36,15 +29,12 @@ http_content_encoding_str2int(const char *content_encoding)
if (strcasestr(content_encoding, "gzip") != NULL) {
return HTTP_CONTENT_ENCODING_GZIP;
}
-
if (strcasestr(content_encoding, "deflate") != NULL) {
return HTTP_CONTENT_ENCODING_DEFLATE;
}
-
if (strcasestr(content_encoding, "br") != NULL) {
return HTTP_CONTENT_ENCODING_BR;
}
-
return HTTP_CONTENT_ENCODING_NONE;
}
@@ -54,15 +44,12 @@ http_content_encoding_int2str(enum http_content_encoding content_encoding)
if (content_encoding == HTTP_CONTENT_ENCODING_GZIP) {
return "gzip";
}
-
if (content_encoding == HTTP_CONTENT_ENCODING_DEFLATE) {
return "deflate";
}
-
if (content_encoding == HTTP_CONTENT_ENCODING_BR) {
return "br";
}
-
return "unknown";
}
@@ -98,7 +85,6 @@ http_content_decompress_create(enum http_content_encoding encoding)
goto error;
}
}
-
if (encoding == HTTP_CONTENT_ENCODING_DEFLATE) {
if (inflateInit2(decompress->z_stream_ptr, -MAX_WBITS) != Z_OK) {
goto error;
@@ -112,7 +98,6 @@ http_content_decompress_create(enum http_content_encoding encoding)
goto error;
}
}
-
return decompress;
error:
@@ -125,17 +110,14 @@ void http_content_decompress_destroy(struct http_content_decompress *decompress)
if (NULL == decompress) {
return;
}
-
if (decompress->z_stream_ptr != NULL) {
inflateEnd(decompress->z_stream_ptr);
FREE(decompress->z_stream_ptr);
}
-
if (decompress->br_state) {
BrotliDecoderDestroyInstance(decompress->br_state);
decompress->br_state = NULL;
}
-
FREE(decompress->buffer);
FREE(decompress);
}
@@ -257,12 +239,10 @@ int http_content_decompress_write(struct http_content_decompress *decompress,
return http_content_decompress_write_zlib(decompress, indata, indata_len,
outdata, outdata_len);
}
-
if (decompress->encoding == HTTP_CONTENT_ENCODING_BR) {
return http_content_decompress_write_br(decompress, indata, indata_len,
outdata, outdata_len);
}
-
assert(0);
return -1;
} \ No newline at end of file
diff --git a/src/http_decoder.c b/src/http_decoder.c
deleted file mode 100644
index 9dcffe2..0000000
--- a/src/http_decoder.c
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
-**********************************************************************************************
-* File: http_decoder.c
-* Description:
-* Authors: Liu WenTan <[email protected]>
-* Date: 2024-01-10
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
-#include <assert.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "toml/toml.h"
-#include "stellar/utils.h"
-#include "stellar/session.h"
-#include "stellar/session_mq.h"
-#include "stellar/session_exdata.h"
-#include "http_decoder.h"
-#include "http_decoder_half.h"
-#include "http_decoder_table.h"
-#include "http_decoder_result_queue.h"
-#include "llhttp.h"
-#include "http_decoder_inc.h"
-#include "fieldstat/fieldstat_easy.h"
-
-#define HTTP_IDENTIFY_LEN 16
-#define HD_RESULT_QUEUE_LEN 16
-
-#define DEFAULT_STAT_OUTPUT_INTERVAL 1
-#define DEFAULT_STAT_INTERVAL_PKTS 1000
-#define DEFAULT_MEMPOOL_SIZE (32 * 1024)
-
-const char *g_hd_cfg_path = "./etc/http/http_decoder.toml";
-const char *http_decoder_topic = "HTTP_DECODER_MESSAGE";
-const char *fs_file_name = "http_decoder.fs";
-
-struct http_decoder_config
-{
- int decompress_switch;
- int stat_interval_pkts; // call fieldstat_incrby every stat_interval_pkts
- int stat_output_interval;
- size_t result_queue_len; // per session result queue length
- size_t mempool_size; // per session mempool size
-};
-
-/**
- * NOTE: http_message don't have the ownership of data
- */
-struct http_message
-{
- enum http_message_type type;
- struct http_decoder_result_queue *ref_queue;
- size_t queue_index;
-};
-
-struct http_decoder
-{
- struct http_decoder_half *c2s_half;
- struct http_decoder_half *s2c_half;
-};
-
-struct http_decoder_exdata
-{
- struct http_decoder_result_queue *queue;
- struct http_decoder *decoder;
- 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
-{
- int plugin_id;
- int 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;
-};
-
-__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)
-{
- struct http_message *msg = CALLOC(struct http_message, 1);
-
- msg->type = type;
- msg->ref_queue = queue;
- msg->queue_index = queue_index;
-
- return msg;
-}
-
-static void http_message_free(void *http_msg, void *cb_arg)
-{
- if (NULL == http_msg)
- {
- return;
- }
-
- FREE(http_msg);
-}
-
-static void http_event_handler(enum http_event event,
- struct http_decoder_half_data **data,
- struct http_event_context *ev_ctx)
-{
- assert(ev_ctx);
-
- size_t queue_idx = 0;
- nmx_pool_t *mempool = ev_ctx->ref_mempool;
- struct http_decoder_result_queue *queue = ev_ctx->ref_queue;
- struct http_message *msg = NULL;
- struct http_decoder_half_data *half_data = NULL;
- int ret = 0;
-
- switch (event)
- {
- case HTTP_EVENT_REQ_INIT:
- half_data = http_decoder_result_queue_peek_req(queue);
- if (half_data != NULL)
- {
- http_decoder_result_queue_inc_req_index(queue);
- }
-
- half_data = http_decoder_result_queue_peek_req(queue);
- if (half_data != NULL)
- {
- half_data = http_decoder_result_queue_pop_req(queue);
- http_decoder_half_data_free(mempool, half_data);
- half_data = NULL;
- }
-
- half_data = http_decoder_half_data_new(mempool);
- 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;
- }
- *data = half_data;
- break;
- case HTTP_EVENT_REQ_LINE:
- queue_idx = http_decoder_result_queue_req_index(queue);
- msg = http_message_new(HTTP_MESSAGE_REQ_LINE, queue, queue_idx);
- session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
- break;
- case HTTP_EVENT_REQ_HDR_END:
- {
- int build_url_final = http_decoder_join_url_finally(ev_ctx, http_decoder_result_queue_peek_req(queue), mempool);
- ret = http_decoder_half_data_has_parsed_header(*data);
- if (0 == ret && 0 == build_url_final)
- {
- break;
- }
- queue_idx = http_decoder_result_queue_req_index(queue);
- msg = http_message_new(HTTP_MESSAGE_REQ_HEADER, queue, queue_idx);
- session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
- }
- break;
- case HTTP_EVENT_REQ_BODY_BEGIN:
- break;
- case HTTP_EVENT_REQ_BODY_DATA:
- queue_idx = http_decoder_result_queue_req_index(queue);
- msg = http_message_new(HTTP_MESSAGE_REQ_BODY, queue, queue_idx);
- session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
- break;
- case HTTP_EVENT_REQ_BODY_END:
- break;
- case HTTP_EVENT_REQ_END:
- http_decoder_result_queue_inc_req_index(queue);
- half_data = http_decoder_result_queue_pop_req(queue);
- if (half_data != NULL)
- {
- http_decoder_half_data_free(mempool, half_data);
- half_data = NULL;
- }
- break;
- case HTTP_EVENT_RES_INIT:
- half_data = http_decoder_result_queue_peek_res(queue);
- if (half_data != NULL)
- {
- http_decoder_result_queue_inc_res_index(queue);
- }
-
- half_data = http_decoder_result_queue_peek_res(queue);
- if (half_data != NULL)
- {
- half_data = http_decoder_result_queue_pop_res(queue);
- http_decoder_half_data_free(mempool, half_data);
- half_data = NULL;
- }
-
- half_data = http_decoder_half_data_new(mempool);
- 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;
- }
- *data = half_data;
- break;
- case HTTP_EVENT_RES_LINE:
- queue_idx = http_decoder_result_queue_res_index(queue);
- msg = http_message_new(HTTP_MESSAGE_RES_LINE, queue, queue_idx);
- session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
- break;
- case HTTP_EVENT_RES_HDR:
- break;
- case HTTP_EVENT_RES_HDR_END:
- ret = http_decoder_half_data_has_parsed_header(*data);
- if (0 == ret)
- {
- break;
- }
-
- queue_idx = http_decoder_result_queue_res_index(queue);
- msg = http_message_new(HTTP_MESSAGE_RES_HEADER, queue, queue_idx);
- session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
- break;
- case HTTP_EVENT_RES_BODY_BEGIN:
- break;
- case HTTP_EVENT_RES_BODY_DATA:
- queue_idx = http_decoder_result_queue_res_index(queue);
- msg = http_message_new(HTTP_MESSAGE_RES_BODY, queue, queue_idx);
- session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
- break;
- case HTTP_EVENT_RES_BODY_END:
- break;
- case HTTP_EVENT_RES_END:
- http_decoder_result_queue_inc_res_index(queue);
- half_data = http_decoder_result_queue_pop_res(queue);
- if (half_data != NULL)
- {
- http_decoder_half_data_free(mempool, half_data);
- half_data = NULL;
- }
- break;
- default:
- assert(0);
- break;
- }
-}
-
-static struct http_decoder *
-http_decoder_new(nmx_pool_t *mempool, http_event_cb *ev_cb,
- int decompress_switch)
-{
- 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);
-
- return decoder;
-}
-
-static void
-http_decoder_free(nmx_pool_t *mempool, struct http_decoder *decoder)
-{
- if (NULL == decoder)
- {
- return;
- }
-
- if (decoder->c2s_half != NULL)
- {
- http_decoder_half_free(mempool, decoder->c2s_half);
- decoder->c2s_half = NULL;
- }
-
- if (decoder->s2c_half != NULL)
- {
- http_decoder_half_free(mempool, decoder->s2c_half);
- decoder->s2c_half = NULL;
- }
-
- MEMPOOL_FREE(mempool, decoder);
-}
-
-static struct http_decoder_exdata *
-http_decoder_exdata_new(size_t mempool_size, size_t queue_size,
- int decompress_switch)
-{
- 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->queue = http_decoder_result_queue_new(ex_data->mempool, queue_size);
-
- return ex_data;
-}
-
-static void http_decoder_exdata_free(struct http_decoder_exdata *ex_data)
-{
- if (NULL == ex_data)
- {
- return;
- }
-
- if (ex_data->decoder != NULL)
- {
- http_decoder_free(ex_data->mempool, ex_data->decoder);
- ex_data->decoder = NULL;
- }
-
- if (ex_data->queue != NULL)
- {
- http_decoder_result_queue_free(ex_data->mempool, ex_data->queue);
- ex_data->queue = NULL;
- }
-
- nmx_destroy_pool(ex_data->mempool);
-
- FREE(ex_data);
-}
-
-static int http_protocol_identify(const char *data, size_t data_len)
-{
- llhttp_t parser;
- llhttp_settings_t settings;
- enum llhttp_errno error;
-
- llhttp_settings_init(&settings);
- llhttp_init(&parser, HTTP_BOTH, &settings);
-
- error = llhttp_execute(&parser, data, data_len);
- if (error != HPE_OK)
- {
- return -1;
- }
-
- return 0;
-}
-
-static int
-http_decoder_stat_init(struct http_decoder_context *ctx, int thread_num)
-{
- 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;
- }
-
- 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;
- }
-
- ctx->fs_err_pkts_id = fieldstat_easy_register_counter(ctx->fse, "err_pkts");
- if (ctx->fs_err_pkts_id < 0)
- {
- fprintf(stderr, "fieldstat_easy_register_counter err_pkts failed.");
- return -1;
- }
-
- int stat_output_interval = DEFAULT_STAT_OUTPUT_INTERVAL;
- if (ctx->hd_cfg.stat_output_interval > 0)
- {
- stat_output_interval = ctx->hd_cfg.stat_output_interval;
- }
-
- int ret = fieldstat_easy_enable_auto_output(ctx->fse, fs_file_name,
- stat_output_interval);
- if (ret < 0)
- {
- fprintf(stderr, "fieldstat_easy_enable_auto_output failed.");
- return -1;
- }
-
- sleep(1);
-
- return 0;
-}
-
-static void
-http_decoder_stat_output(struct http_decoder_context *ctx, int thread_id)
-{
- if (NULL == ctx || thread_id < 0)
- {
- return;
- }
-
- 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;
- }
-}
-
-int http_decoder_entry(struct session *sess, int events,
- const struct packet *pkt, void *cb_arg)
-{
- struct http_decoder_context *ctx = (struct http_decoder_context *)cb_arg;
- size_t payload_len = 0;
- uint64_t inner_flag = 0;
-
- int ret = session_is_inner_most(sess, &inner_flag);
- if (0 == ret)
- {
- return 0;
- }
-
- struct http_decoder_exdata *ex_data =
- session_get_ex_data(sess, ctx->ex_data_idx);
-
- if (events & SESS_EV_CLOSING)
- {
- if (ex_data != NULL)
- {
- http_decoder_exdata_free(ex_data);
- session_set_ex_data(sess, ctx->ex_data_idx, NULL);
- }
-
- return 0;
- }
-
- const char *payload = session_get0_current_payload(sess, &payload_len);
-
- if (events & SESS_EV_OPENING)
- {
- assert(ex_data == NULL);
-
- // If not http, ignore this session
- if (payload_len > 0)
- {
- size_t http_identify_len = payload_len > HTTP_IDENTIFY_LEN
- ? HTTP_IDENTIFY_LEN
- : payload_len;
-
- ret = http_protocol_identify(payload, http_identify_len);
- if (ret < 0)
- {
- // ignore this session's event
- struct session_event *s_event =
- session_get_intrinsic_event(sess, ctx->plugin_id);
-
- session_event_assign(s_event, ctx->st, sess, 0,
- http_decoder_entry, ctx);
- return 0;
- }
- }
-
- ex_data = http_decoder_exdata_new(ctx->hd_cfg.mempool_size,
- ctx->hd_cfg.result_queue_len,
- ctx->hd_cfg.decompress_switch);
- session_set_ex_data(sess, ctx->ex_data_idx, ex_data);
- }
-
- if (0 == payload_len || NULL == ex_data)
- {
- return 0;
- }
-
- int dir = packet_get_direction(pkt);
- if (dir < 0)
- {
- return -1;
- }
-
- int thread_id = session_get_current_thread_id(sess);
- struct http_decoder_half *cur_half = NULL;
-
- if (dir == PACKET_DIRECTION_C2S)
- {
- cur_half = ex_data->decoder->c2s_half;
- }
- else
- {
- cur_half = ex_data->decoder->s2c_half;
- }
-
- http_decoder_half_reinit(cur_half, ctx->topic_id, ex_data->queue,
- ex_data->mempool, sess);
- ret = http_decoder_half_parse(cur_half, payload, payload_len);
- if (ret < 0)
- {
- _th_stat.err_pkts += 1;
- }
-
- _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(ctx, thread_id);
-
- return 0;
-}
-
-static void _http_decoder_context_free(struct http_decoder_context *ctx)
-{
- if (NULL == ctx)
- {
- return;
- }
-
- if (ctx->fse != NULL)
- {
- fieldstat_easy_free(ctx->fse);
- ctx->fse = NULL;
- }
-
- if (ctx->topic_id >= 0)
- {
- session_mq_destroy_topic(ctx->st, ctx->topic_id);
- ctx->topic_id = -1;
- }
-
- FREE(ctx);
-}
-
-static void http_decoder_ex_data_free(struct session *s, int idx,
- void *ex_data, void *arg)
-{
- if (NULL == ex_data)
- {
- return;
- }
-
- struct http_decoder_exdata *exdata = (struct http_decoder_exdata *)ex_data;
- http_decoder_exdata_free(exdata);
-}
-
-static int load_http_decoder_config(const char *cfg_path,
- struct http_decoder_config *hd_cfg)
-{
- FILE *fp = fopen(cfg_path, "r");
- if (NULL == fp)
- {
- fprintf(stderr, "[%s:%d]Can't open config file:%s",
- __FUNCTION__, __LINE__, cfg_path);
- return -1;
- }
-
- int ret = 0;
- char errbuf[256] = {0};
-
- toml_table_t *root = toml_parse_file(fp, errbuf, sizeof(errbuf));
- fclose(fp);
-
- 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);
- ret = -1;
- goto next;
- }
-
- toml_datum_t int_val = toml_int_in(basic_sec_tbl, "decompress");
- if (int_val.ok != 0)
- {
- hd_cfg->decompress_switch = int_val.u.b;
- }
-
- int_val = toml_int_in(basic_sec_tbl, "mempool_size");
- if (int_val.ok != 0)
- {
- hd_cfg->mempool_size = int_val.u.i;
- }
- else
- {
- hd_cfg->mempool_size = DEFAULT_MEMPOOL_SIZE;
- }
-
- int_val = toml_int_in(basic_sec_tbl, "result_queue_len");
- if (int_val.ok != 0)
- {
- hd_cfg->result_queue_len = int_val.u.i;
- }
- else
- {
- hd_cfg->result_queue_len = HD_RESULT_QUEUE_LEN;
- }
-
- int_val = toml_int_in(basic_sec_tbl, "stat_interval_pkts");
- if (int_val.ok != 0)
- {
- hd_cfg->stat_interval_pkts = int_val.u.i;
- }
- else
- {
- hd_cfg->stat_interval_pkts = DEFAULT_STAT_INTERVAL_PKTS;
- }
-
- int_val = toml_int_in(basic_sec_tbl, "stat_output_interval");
- if (int_val.ok != 0)
- {
- hd_cfg->stat_output_interval = int_val.u.i;
- }
- else
- {
- hd_cfg->stat_output_interval = DEFAULT_STAT_OUTPUT_INTERVAL;
- }
-
-next:
- toml_free(root);
- return ret;
-}
-
-void *http_decoder_init(struct stellar *st)
-{
- int plugin_id = -1;
- int topic_id = -1;
- int thread_num = 0;
-
- struct http_decoder_context *ctx = CALLOC(struct http_decoder_context, 1);
-
- int ret = load_http_decoder_config(g_hd_cfg_path, &ctx->hd_cfg);
- if (ret < 0)
- {
- goto failed;
- }
-
- ctx->st = st;
- ctx->ex_data_idx = stellar_session_get_ex_new_index(st, "HTTP_DECODER",
- http_decoder_ex_data_free,
- NULL);
-
- plugin_id = stellar_plugin_register(st, SESS_EV_TCP | SESS_EV_CLOSING,
- http_decoder_entry, ctx);
- if (plugin_id < 0)
- {
- goto failed;
- }
-
- ctx->plugin_id = plugin_id;
-
- topic_id = session_mq_get_topic_id(st, http_decoder_topic);
- if (topic_id < 0)
- {
- topic_id = session_mq_create_topic(st, http_decoder_topic,
- http_message_free, NULL);
- }
-
- ctx->topic_id = topic_id;
-
- thread_num = stellar_get_worker_thread_num(st);
-
- if (http_decoder_stat_init(ctx, thread_num) < 0)
- {
- goto failed;
- }
-
- // printf("http_decoder_init: ex_data_idx:%d, plugin_id:%d, topic_id:%d\n",
- // ctx->ex_data_idx, ctx->plugin_id, ctx->topic_id);
- return ctx;
-
-failed:
- _http_decoder_context_free(ctx);
- return NULL;
-}
-
-void http_decoder_exit(void *decoder_ctx)
-{
- if (NULL == decoder_ctx)
- {
- return;
- }
-
- struct http_decoder_context *ctx =
- (struct http_decoder_context *)decoder_ctx;
-
- _http_decoder_context_free(ctx);
-}
-
-enum http_message_type http_message_type(struct http_message *msg)
-{
- if (NULL == msg)
- {
- return HTTP_MESSAGE_MAX;
- }
-
- return msg->type;
-}
-
-int http_message_get_request_line(struct http_message *msg,
- struct http_request_line *line)
-{
- if (NULL == msg || msg->type != HTTP_MESSAGE_REQ_LINE ||
- NULL == line)
- {
- return -1;
- }
-
- 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;
-
- return http_decoder_half_data_get_request_line(req_data, line);
-}
-
-int http_message_get_response_line(struct http_message *msg,
- struct http_response_line *line)
-{
- if (NULL == msg || msg->type != HTTP_MESSAGE_RES_LINE ||
- NULL == line)
- {
- return -1;
- }
-
- 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;
-
- return http_decoder_half_data_get_response_line(res_data, line);
-}
-
-static int http_msg_get_request_header(struct http_message *msg, struct hstring *key,
- struct http_header *hdr_result)
-{
- 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, key, hdr_result);
-}
-
-static int http_msg_get_response_header(struct http_message *msg, struct hstring *key,
- struct http_header *hdr_result)
-{
- 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, key, hdr_result);
-}
-
-int http_message_get_header(struct http_message *msg, struct hstring *key,
- struct http_header *hdr_result)
-{
- if (NULL == msg || NULL == key || NULL == hdr_result)
- {
- return -1;
- }
- assert(msg->ref_queue);
- assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- if (HTTP_MESSAGE_REQ_HEADER == msg->type)
- {
- return http_msg_get_request_header(msg, key, hdr_result);
- }
- else if (HTTP_MESSAGE_RES_HEADER == msg->type)
- {
- return http_msg_get_response_header(msg, key, hdr_result);
- }
-
- return -1;
-}
-
-static int http_msg_request_header_next(struct http_message *msg,
- struct http_header *hdr)
-{
- struct http_decoder_half_data *req_data =
- msg->ref_queue->array[msg->queue_index].req_data;
- return http_decoder_half_data_iter_header(req_data, hdr);
-}
-
-static int http_msg_response_header_next(struct http_message *msg,
- struct http_header *hdr)
-{
- struct http_decoder_half_data *res_data =
- msg->ref_queue->array[msg->queue_index].res_data;
- return http_decoder_half_data_iter_header(res_data, hdr);
-}
-
-int http_message_header_next(struct http_message *msg,
- struct http_header *header)
-{
- if (NULL == msg || NULL == header)
- {
- return -1;
- }
- assert(msg->ref_queue);
- assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- if (HTTP_MESSAGE_REQ_HEADER == msg->type)
- {
- return http_msg_request_header_next(msg, header);
- }
- else if (HTTP_MESSAGE_RES_HEADER == msg->type)
- {
- return http_msg_response_header_next(msg, header);
- }
-
- return -1;
-}
-
-int http_message_reset_header_iter(struct http_message *msg)
-{
- if (NULL == msg)
- {
- return -1;
- }
- assert(msg->ref_queue);
- assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- if (HTTP_MESSAGE_REQ_HEADER == 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);
- }
- else if (HTTP_MESSAGE_RES_HEADER == 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);
- }
-
- return -1;
-}
-
-static int http_msg_get_request_raw_body(struct http_message *msg,
- struct hstring *body)
-{
- 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(struct http_message *msg,
- struct hstring *body)
-{
- 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);
-}
-
-int http_message_get_raw_body(struct http_message *msg,
- struct hstring *body)
-{
- if (NULL == msg || NULL == body)
- {
- return -1;
- }
- assert(msg->ref_queue);
- assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
-
- if (HTTP_MESSAGE_REQ_BODY == msg->type)
- {
- return http_msg_get_request_raw_body(msg, body);
- }
- else if (HTTP_MESSAGE_RES_BODY == msg->type)
- {
- return http_msg_get_response_raw_body(msg, body);
- }
-
- return -1;
-}
-
-int http_msg_get_request_decompress_body(struct http_message *msg,
- struct hstring *body)
-{
- 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);
-}
-
-int http_msg_get_response_decompress_body(struct http_message *msg,
- struct hstring *body)
-{
- 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);
-}
-
-int http_message_get_decompress_body(struct http_message *msg,
- struct hstring *body)
-{
- if (NULL == msg || NULL == body)
- {
- return -1;
- }
-
- assert(msg->ref_queue);
- assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
-
- if (HTTP_MESSAGE_REQ_BODY == msg->type)
- {
- return http_msg_get_request_decompress_body(msg, body);
- }
- else if (HTTP_MESSAGE_RES_BODY == msg->type)
- {
- return http_msg_get_response_decompress_body(msg, body);
- }
-
- return -1;
-}
-
-int http_message_get_url(struct http_message *msg, struct hstring *url)
-{
- if (NULL == msg || NULL == url)
- {
- return -1;
- }
-
- 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;
-
- return http_half_data_get_url(req_data, url);
-}
-
-int http_message_get_transaction_seq(struct http_message *msg)
-{
- if (NULL == msg)
- {
- return -1;
- }
- assert(msg->ref_queue);
- assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
- struct http_decoder_half_data *hf_data;
- if (HTTP_MESSAGE_REQ_LINE == msg->type || HTTP_MESSAGE_REQ_HEADER == msg->type || HTTP_MESSAGE_REQ_BODY == msg->type)
- {
- hf_data = msg->ref_queue->array[msg->queue_index].req_data;
- }
- else
- {
- hf_data = msg->ref_queue->array[msg->queue_index].res_data;
- }
- return http_half_data_get_transaction_seq(hf_data);
- ;
-} \ No newline at end of file
diff --git a/src/http_decoder.cpp b/src/http_decoder.cpp
new file mode 100644
index 0000000..750a739
--- /dev/null
+++ b/src/http_decoder.cpp
@@ -0,0 +1,833 @@
+#include <assert.h>
+#include <stdio.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)
+{
+ struct http_message *msg = CALLOC(struct http_message, 1);
+ msg->type = type;
+ msg->ref_queue = queue;
+ msg->queue_index = queue_index;
+ msg->flow_type = flow_type;
+ return msg;
+}
+
+static void http_message_free(struct session *sess, void *http_msg, void *cb_arg)
+{
+ if (http_msg)
+ {
+ FREE(http_msg);
+ }
+}
+
+static void http_event_handler(enum http_event event, struct http_decoder_half_data **data,
+ struct http_event_context *ev_ctx)
+{
+ assert(ev_ctx);
+
+ size_t queue_idx = 0;
+ nmx_pool_t *mempool = ev_ctx->ref_mempool;
+ struct http_decoder_result_queue *queue = ev_ctx->ref_queue;
+ struct http_message *msg = NULL;
+ struct http_decoder_half_data *half_data = NULL;
+ int ret = 0;
+ u_int8_t flow_flag = 0;
+
+ if(http_event_is_req(event)){
+ queue_idx = http_decoder_result_queue_req_index(queue);
+ }else{
+ queue_idx = http_decoder_result_queue_res_index(queue);
+ }
+
+ switch (event)
+ {
+ case HTTP_EVENT_REQ_INIT:
+ half_data = http_decoder_result_queue_peek_req(queue);
+ if (half_data != NULL)
+ {
+ http_decoder_result_queue_inc_req_index(queue);
+ }
+
+ half_data = http_decoder_result_queue_peek_req(queue);
+ if (half_data != NULL)
+ {
+ half_data = http_decoder_result_queue_pop_req(queue);
+ http_decoder_half_data_free(mempool, half_data);
+ half_data = NULL;
+ }
+
+ half_data = http_decoder_half_data_new(mempool);
+ 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;
+ }
+ *data = half_data;
+ queue_idx = http_decoder_result_queue_req_index(queue); //get the index after inc
+ 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);
+ 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, ev_ctx->topic_id, msg);
+ 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, ev_ctx->topic_id, msg);
+ break;
+ case HTTP_EVENT_REQ_HDR_END:
+ {
+ http_decoder_join_url_finally(ev_ctx, http_decoder_result_queue_peek_req(queue), mempool);
+ /* maybe some parsed headers in buffer, but has not pushed to plugins yet */
+ half_data = http_decoder_result_queue_peek_req(queue);
+ if(http_decoder_half_data_has_parsed_header(half_data)){
+ msg = http_message_new(HTTP_MESSAGE_REQ_HEADER, queue, queue_idx, HTTP_REQUEST);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->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, ev_ctx->topic_id, msg);
+ }
+ break;
+ case HTTP_EVENT_REQ_BODY_BEGIN:
+ //do nothing, in BODY_DATA event
+ break;
+ case HTTP_EVENT_REQ_BODY_DATA:
+ msg = http_message_new(HTTP_MESSAGE_REQ_BODY, queue, queue_idx, HTTP_REQUEST);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ break;
+ case HTTP_EVENT_REQ_BODY_END:
+ msg = http_message_new(HTTP_MESSAGE_REQ_BODY_END, queue, queue_idx, HTTP_REQUEST);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ 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);
+ }
+ }
+ http_decoder_result_queue_inc_req_index(queue);
+ half_data = http_decoder_result_queue_pop_req(queue);
+ if (half_data != NULL)
+ {
+ http_decoder_half_data_free(mempool, half_data);
+ half_data = NULL;
+ }
+ }
+ break;
+
+ case HTTP_EVENT_RES_INIT:
+ half_data = http_decoder_result_queue_peek_res(queue);
+ if (half_data != NULL)
+ {
+ http_decoder_result_queue_inc_res_index(queue);
+ }
+
+ half_data = http_decoder_result_queue_peek_res(queue);
+ if (half_data != NULL)
+ {
+ half_data = http_decoder_result_queue_pop_res(queue);
+ http_decoder_half_data_free(mempool, half_data);
+ half_data = NULL;
+ }
+
+ half_data = http_decoder_half_data_new(mempool);
+ 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;
+ }
+ queue_idx = http_decoder_result_queue_res_index(queue); //get the index after inc
+ *data = half_data;
+ if(0 == session_is_symmetric(ev_ctx->ref_session, &flow_flag)){
+ if(SESSION_SEEN_S2C_FLOW == flow_flag){
+ msg = http_message_new(HTTP_TRANSACTION_NEW, queue, queue_idx, HTTP_RESPONSE);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ }
+ }
+ 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, ev_ctx->topic_id, msg);
+ break;
+ case HTTP_EVENT_RES_HDR:
+ msg = http_message_new(HTTP_MESSAGE_RES_HEADER, queue, queue_idx, HTTP_REQUEST);
+ 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)){
+ 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);
+ }
+ 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);
+ break;
+ case HTTP_EVENT_RES_BODY_BEGIN:
+ break;
+ case HTTP_EVENT_RES_BODY_DATA:
+ msg = http_message_new(HTTP_MESSAGE_RES_BODY, queue, queue_idx, HTTP_RESPONSE);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ break;
+ case HTTP_EVENT_RES_BODY_END:
+ msg = http_message_new(HTTP_MESSAGE_RES_BODY_END, queue, queue_idx, HTTP_RESPONSE);
+ session_mq_publish_message(ev_ctx->ref_session, ev_ctx->topic_id, msg);
+ break;
+ 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_result_queue_inc_res_index(queue);
+ half_data = http_decoder_result_queue_pop_res(queue);
+ if (half_data != NULL)
+ {
+ http_decoder_half_data_free(mempool, half_data);
+ half_data = NULL;
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
+static struct http_decoder *http_decoder_new(nmx_pool_t *mempool, http_event_cb *ev_cb, int decompress_switch)
+{
+ 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);
+ return decoder;
+}
+
+static void http_decoder_free(nmx_pool_t *mempool, struct http_decoder *decoder)
+{
+ if (NULL == decoder)
+ {
+ return;
+ }
+ if (decoder->c2s_half != NULL)
+ {
+ http_decoder_half_free(mempool, decoder->c2s_half);
+ decoder->c2s_half = NULL;
+ }
+ if (decoder->s2c_half != NULL)
+ {
+ http_decoder_half_free(mempool, decoder->s2c_half);
+ decoder->s2c_half = NULL;
+ }
+ MEMPOOL_FREE(mempool, decoder);
+}
+
+static struct http_decoder_exdata *http_decoder_exdata_new(size_t mempool_size, size_t queue_size,int decompress_switch)
+{
+ 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->queue = http_decoder_result_queue_new(ex_data->mempool, queue_size);
+ return ex_data;
+}
+
+static void http_decoder_exdata_free(struct http_decoder_exdata *ex_data)
+{
+ if (unlikely(NULL == ex_data))
+ {
+ return;
+ }
+ if (ex_data->decoder != NULL)
+ {
+ http_decoder_free(ex_data->mempool, ex_data->decoder);
+ ex_data->decoder = NULL;
+ }
+ if (ex_data->queue != NULL)
+ {
+ http_decoder_result_queue_free(ex_data->mempool, ex_data->queue);
+ ex_data->queue = NULL;
+ }
+
+ nmx_destroy_pool(ex_data->mempool);
+ FREE(ex_data);
+}
+
+static int http_protocol_identify(const char *data, size_t data_len)
+{
+ llhttp_t parser;
+ llhttp_settings_t settings;
+ enum llhttp_errno error;
+
+ llhttp_settings_init(&settings);
+ llhttp_init(&parser, HTTP_BOTH, &settings);
+
+ error = llhttp_execute(&parser, data, data_len);
+ if (error != HPE_OK)
+ {
+ return -1;
+ }
+ return 0;
+}
+
+static void _http_decoder_context_free(struct http_decoder_context *ctx)
+{
+ if (NULL == ctx)
+ {
+ return;
+ }
+
+ if (ctx->fse != NULL)
+ {
+ fieldstat_easy_free(ctx->fse);
+ ctx->fse = NULL;
+ }
+
+ if (ctx->httpd_msg_topic_id >= 0)
+ {
+ stellar_session_mq_destroy_topic(ctx->st, ctx->httpd_msg_topic_id);
+ ctx->httpd_msg_topic_id = -1;
+ }
+
+ FREE(ctx);
+}
+
+static int load_http_decoder_config(const char *cfg_path,
+ struct http_decoder_config *hd_cfg)
+{
+ FILE *fp = fopen(cfg_path, "r");
+ if (NULL == fp)
+ {
+ fprintf(stderr, "[%s:%d]Can't open config file:%s",
+ __FUNCTION__, __LINE__, cfg_path);
+ return -1;
+ }
+
+ int ret = 0;
+ char errbuf[256] = {0};
+
+ toml_table_t *root = toml_parse_file(fp, errbuf, sizeof(errbuf));
+ fclose(fp);
+
+ 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);
+ toml_free(root);
+ return -1;
+ }
+
+ toml_datum_t int_val = toml_int_in(basic_sec_tbl, "decompress");
+ if (int_val.ok != 0)
+ {
+ hd_cfg->decompress_switch = int_val.u.b;
+ }
+
+ int_val = toml_int_in(basic_sec_tbl, "mempool_size");
+ if (int_val.ok != 0)
+ {
+ hd_cfg->mempool_size = int_val.u.i;
+ }
+ else
+ {
+ hd_cfg->mempool_size = DEFAULT_MEMPOOL_SIZE;
+ }
+
+ int_val = toml_int_in(basic_sec_tbl, "result_queue_len");
+ if (int_val.ok != 0)
+ {
+ hd_cfg->result_queue_len = int_val.u.i;
+ }
+ else
+ {
+ hd_cfg->result_queue_len = HD_RESULT_QUEUE_LEN;
+ }
+
+ int_val = toml_int_in(basic_sec_tbl, "stat_interval_pkts");
+ if (int_val.ok != 0)
+ {
+ hd_cfg->stat_interval_pkts = int_val.u.i;
+ }
+ else
+ {
+ hd_cfg->stat_interval_pkts = DEFAULT_STAT_INTERVAL_PKTS;
+ }
+
+ int_val = toml_int_in(basic_sec_tbl, "stat_output_interval");
+ if (int_val.ok != 0)
+ {
+ hd_cfg->stat_output_interval = int_val.u.i;
+ }
+ else
+ {
+ hd_cfg->stat_output_interval = DEFAULT_STAT_OUTPUT_INTERVAL;
+ }
+
+ toml_free(root);
+ return ret;
+}
+
+static int http_msg_get_request_header(const struct http_message *msg, const struct hstring *key,
+ struct http_header *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, key, hdr_result);
+}
+
+static int http_msg_get_response_header(const struct http_message *msg, const struct hstring *key,
+ struct http_header *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, key, hdr_result);
+}
+
+static int http_msg_request_header_next(const struct http_message *msg,
+ struct http_header *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 *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);
+}
+
+static int http_msg_get_request_raw_body(const struct http_message *msg,
+ struct 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,
+ struct 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,
+ struct 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,
+ struct 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);
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ void _httpd_ex_data_free_cb(struct session *s, int idx,
+ void *ex_data, void *arg)
+ {
+ if (NULL == ex_data)
+ {
+ return;
+ }
+ struct http_decoder_exdata *exdata = (struct http_decoder_exdata *)ex_data;
+ http_decoder_exdata_free(exdata);
+ }
+
+ void *_httpd_session_ctx_new_cb(struct session *sess, void *plugin_env)
+ {
+ // If not http, ignore this session
+ size_t payload_len;
+ const struct http_decoder_context *httpd_env = (struct http_decoder_context *)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;
+
+ int ret = http_protocol_identify(payload, http_identify_len);
+ if (ret < 0)
+ {
+ stellar_session_plugin_dettach_current_session(sess);
+ return NULL;
+ }
+ }
+
+ 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);
+ session_exdata_set(sess, httpd_env->ex_data_idx, ex_data);
+ 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()
+ }
+
+ 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_exdata *ex_data = (struct http_decoder_exdata *)session_exdata_get(sess, httpd_env->ex_data_idx);
+ size_t payload_len;
+
+ const char *payload = session_get0_current_payload(sess, &payload_len);
+ if (unlikely(0 == payload_len || NULL == ex_data))
+ {
+ return;
+ }
+
+ int thread_id = stellar_get_current_thread_id(httpd_env->st);
+ struct http_decoder_half *cur_half = NULL;
+
+ if (PACKET_DIRECTION_C2S == packet_get_direction(session_get0_current_packet(sess)))
+ {
+ cur_half = ex_data->decoder->c2s_half;
+ }
+ else
+ {
+ cur_half = ex_data->decoder->s2c_half;
+ }
+
+ http_decoder_half_reinit(cur_half, httpd_env->httpd_msg_topic_id, ex_data->queue,
+ ex_data->mempool, sess);
+ int ret = http_decoder_half_parse(cur_half, payload, payload_len);
+ if (ret < 0)
+ {
+ _th_stat.err_pkts += 1;
+ }
+ _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;
+ }
+
+ void *http_decoder_init(struct stellar *st)
+ {
+ 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);
+ int ret = load_http_decoder_config(HTTPD_CFG_FILE, &httpd_env->hd_cfg);
+ if (ret < 0)
+ {
+ goto failed;
+ }
+ httpd_env->st = st;
+ httpd_env->ex_data_idx = stellar_session_exdata_new_index(st, "HTTP_DECODER",
+ _httpd_ex_data_free_cb,
+ NULL);
+ httpd_env->plugin_id = stellar_session_plugin_register(st, _httpd_session_ctx_new_cb,
+ _httpd_session_ctx_free_cb, (void *)httpd_env);
+ if (httpd_env->plugin_id < 0)
+ {
+ goto failed;
+ }
+
+ httpd_msg_topic_id = stellar_session_mq_get_topic_id(st, HTTP_DECODER_TOPIC);
+ if (httpd_msg_topic_id < 0)
+ {
+ httpd_msg_topic_id = stellar_session_mq_create_topic(st, HTTP_DECODER_TOPIC,
+ http_message_free, NULL);
+ }
+ httpd_env->httpd_msg_topic_id = httpd_msg_topic_id;
+
+ tcp_stream_topic_id = stellar_session_mq_get_topic_id(st, TOPIC_TCP_STREAM);
+ assert(tcp_stream_topic_id >= 0);
+ stellar_session_mq_subscribe(st, tcp_stream_topic_id, http_decoder_tcp_stream_msg_cb, httpd_env->plugin_id);
+
+ thread_num = stellar_get_worker_thread_num(st);
+ assert(thread_num >= 1);
+ if (http_decoder_stat_init(httpd_env, thread_num) < 0)
+ {
+ goto failed;
+ }
+
+ printf("http_decoder_init succ: ex_data_idx:%d, plugin_id:%d, topic_id:%d\n",
+ httpd_env->ex_data_idx, httpd_env->plugin_id, httpd_env->httpd_msg_topic_id);
+ return httpd_env;
+
+ failed:
+ fprintf(stderr, "http_decoder_init fail!\n");
+ _http_decoder_context_free(httpd_env);
+ return NULL;
+ }
+
+ void http_decoder_exit(void *plugin_env)
+ {
+ if (NULL == plugin_env)
+ {
+ return;
+ }
+ struct http_decoder_context *httpd_env = (struct http_decoder_context *)plugin_env;
+ _http_decoder_context_free(httpd_env);
+ }
+
+ enum http_message_type http_message_type_get(const struct http_message *msg)
+ {
+ if (unlikely(NULL == msg))
+ {
+ return HTTP_MESSAGE_MAX;
+ }
+ return msg->type;
+ }
+
+ void http_message_get_request_line(const struct http_message *msg,
+ struct http_request_line *line)
+ {
+ if (unlikely(NULL == msg || msg->type != HTTP_MESSAGE_REQ_LINE))
+ {
+ if(line){
+ line->method.str = NULL;
+ line->uri.str = NULL;
+ line->version.str = NULL;
+ }
+ 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;
+
+ http_decoder_half_data_get_request_line(req_data, line);
+ }
+
+ void http_message_get_response_line(const struct http_message *msg,
+ struct http_response_line *line)
+ {
+ if (unlikely(NULL == msg || msg->type != HTTP_MESSAGE_RES_LINE))
+ {
+ if(line){
+ line->version.str = NULL;
+ line->status.str = NULL;
+ }
+ return;
+ }
+ 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);
+ }
+
+ void http_message_get_header(const struct http_message *msg, const struct hstring *key,
+ struct http_header *hdr_result)
+ {
+ int ret = -1;
+ if (unlikely(NULL == msg || NULL == key))
+ {
+ goto fail;
+ }
+ assert(msg->ref_queue);
+ assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
+ if (HTTP_MESSAGE_REQ_HEADER == msg->type)
+ {
+ ret = http_msg_get_request_header(msg, key, hdr_result);
+ }
+ else if (HTTP_MESSAGE_RES_HEADER == msg->type)
+ {
+ ret = http_msg_get_response_header(msg, key, hdr_result);
+ }
+ if(ret >= 0){
+ return;
+ }
+ fail:
+ if(hdr_result){
+ hdr_result->key.str = NULL;
+ hdr_result->val.str = NULL;
+ }
+ return;
+ }
+
+ int http_message_header_next(const struct http_message *msg,
+ struct http_header *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->key.str = NULL;
+ header->val.str = NULL;
+ }
+ return -1;
+ }
+
+ int http_message_reset_header_iter(struct http_message *msg)
+ {
+ if (unlikely(NULL == msg))
+ {
+ return -1;
+ }
+ assert(msg->ref_queue);
+ assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
+ if (HTTP_MESSAGE_REQ_HEADER == 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);
+ }
+ else if (HTTP_MESSAGE_RES_HEADER == 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);
+ }
+ return -1;
+ }
+
+ void http_message_get_raw_body(const struct http_message *msg,
+ struct hstring *body)
+ {
+ 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_BODY == msg->type)
+ {
+ ret = http_msg_get_request_raw_body(msg, body);
+ }
+ else if (HTTP_MESSAGE_RES_BODY == msg->type)
+ {
+ ret = http_msg_get_response_raw_body(msg, body);
+ }
+ if(ret < 0){
+ goto fail;
+ }
+ return;
+ fail:
+ if(body){
+ body->str = NULL;
+ body->str_len = 0;
+ }
+ return;
+ }
+
+ void http_message_get_decompress_body(const struct http_message *msg,
+ struct hstring *body)
+ {
+ 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_BODY == msg->type)
+ {
+ ret = http_msg_get_request_decompress_body(msg, body);
+ }
+ else if (HTTP_MESSAGE_RES_BODY == msg->type)
+ {
+ ret = http_msg_get_response_decompress_body(msg, body);
+ }
+ if(ret < 0){
+ goto fail;
+ }
+ return;
+ fail:
+ if(body){
+ body->str = NULL;
+ body->str_len = 0;
+ }
+ return;
+ }
+
+ void http_message_get_url(const struct http_message *msg, struct hstring *url)
+ {
+ if (unlikely(NULL == msg))
+ {
+ if(url){
+ url->str = NULL;
+ url->str_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_url(req_data, url) < 0){
+ goto fail;
+ }
+ return;
+
+ fail:
+ if(url){
+ url->str = NULL;
+ url->str_len = 0;
+ }
+ return;
+ }
+
+ int http_message_get_transaction_seq(const struct http_message *msg)
+ {
+ if (unlikely(NULL == msg))
+ {
+ return -1;
+ }
+ assert(msg->ref_queue);
+ assert(msg->queue_index < HD_RESULT_QUEUE_LEN);
+ struct http_decoder_half_data *hf_data = NULL;
+ if(HTTP_REQUEST == msg->flow_type)
+ {
+ hf_data = msg->ref_queue->array[msg->queue_index].req_data;
+ }
+ else
+ {
+ hf_data = msg->ref_queue->array[msg->queue_index].res_data;
+ }
+ return http_half_data_get_transaction_seq(hf_data);
+ }
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/src/http_decoder_half.c b/src/http_decoder_half.cpp
index 7af1956..d3c2ee2 100644
--- a/src/http_decoder_half.c
+++ b/src/http_decoder_half.cpp
@@ -1,27 +1,9 @@
-/*
-**********************************************************************************************
-* File: http_decoder_half.c
-* Description:
-* Authors: Liu WenTan <[email protected]>
-* Date: 2024-01-10
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
-
-#include "stellar/utils.h"
-#include "stellar/session_mq.h"
-#include "llhttp.h"
-#include "http_decoder.h"
#include "http_decoder_inc.h"
-#include "http_decoder_utils.h"
-#include "http_decoder_half.h"
-#include "http_decoder_table.h"
-#include "http_content_decompress.h"
+#include "llhttp.h"
struct http_decoder_half_data
{
@@ -46,9 +28,9 @@ struct http_decoder_half
llhttp_t parser;
llhttp_settings_t settings;
enum llhttp_errno error;
-
int decompress_switch;
+ // uint8_t is_request_flow;
enum http_event event;
http_event_cb *http_ev_cb;
struct http_event_context *http_ev_ctx;
@@ -79,7 +61,7 @@ static void printf_debug_info(const char *desc, const char *at, size_t length)
}
}
#else
-#define printf_debug_info(desc, at, length)
+#define printf_debug_info(desc, at, length)
#endif
static void
@@ -137,7 +119,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);
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); // http_event_handler()
half->trans_counter++;
half->ref_data->transaction_index = half->transaction_seq++;
@@ -148,8 +130,7 @@ 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);
+ struct http_decoder_half *half = container_of(http, struct http_decoder_half, parser);
assert(half);
if (half->parser.type == HTTP_REQUEST)
@@ -157,11 +138,7 @@ static int on_message_complete(llhttp_t *http)
if (half->event == HTTP_EVENT_REQ_BODY_DATA)
{
half->event = HTTP_EVENT_REQ_BODY_END;
- if (half->http_ev_cb != NULL)
- {
- half->http_ev_cb(half->event, &half->ref_data,
- half->http_ev_ctx);
- }
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
}
}
else
@@ -169,11 +146,7 @@ static int on_message_complete(llhttp_t *http)
if (half->event == HTTP_EVENT_RES_BODY_DATA)
{
half->event = HTTP_EVENT_RES_BODY_END;
- if (half->http_ev_cb != NULL)
- {
- half->http_ev_cb(half->event, &half->ref_data,
- half->http_ev_ctx);
- }
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
}
}
@@ -181,18 +154,12 @@ static int on_message_complete(llhttp_t *http)
if (half->parser.type == HTTP_REQUEST)
{
half->event = HTTP_EVENT_REQ_END;
- if (half->http_ev_cb != NULL)
- {
- 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);
}
else
{
half->event = HTTP_EVENT_RES_END;
- if (half->http_ev_cb != NULL)
- {
- 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);
}
return 0;
@@ -205,10 +172,10 @@ static int on_reset(llhttp_t *http)
return 0;
}
-static inline int is_line_eof(struct http_decoder_half *half)
+static inline int is_line_crlf(struct http_decoder_half *half)
{
- const char *chr_r = memrchr(half->data, '\r', half->data_len);
- const char *chr_n = memrchr(half->data, '\n', half->data_len);
+ 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))
{
return 1;
@@ -238,7 +205,7 @@ static int on_method_complete(llhttp_t *http)
container_of(http, struct http_decoder_half, parser);
assert(half);
- if (is_line_eof(half) == 0)
+ if (is_line_crlf(half) == 0)
{
http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_METHOD);
}
@@ -291,7 +258,7 @@ static int on_uri_complete(llhttp_t *http)
container_of(http, struct http_decoder_half, parser);
assert(half);
- if (is_line_eof(half) == 0)
+ if (is_line_crlf(half) == 0)
{
http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_URI);
}
@@ -329,7 +296,7 @@ static int on_version_complete(llhttp_t *http)
container_of(http, struct http_decoder_half, parser);
assert(half);
- if (is_line_eof(half) == 0)
+ if (is_line_crlf(half) == 0)
{
http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_VERSION);
}
@@ -342,7 +309,7 @@ static int on_version_complete(llhttp_t *http)
if (half->parser.type == HTTP_REQUEST)
{
half->event = HTTP_EVENT_REQ_LINE;
- if (half->http_ev_cb)
+ if (half->http_ev_cb) // http_event_handler()
{
half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
}
@@ -374,7 +341,7 @@ static int on_status_complete(llhttp_t *http)
container_of(http, struct http_decoder_half, parser);
assert(half);
- if (is_line_eof(half) == 0)
+ if (is_line_crlf(half) == 0)
{
http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_STATUS);
}
@@ -385,7 +352,7 @@ static int on_status_complete(llhttp_t *http)
if (half->parser.type == HTTP_RESPONSE)
{
half->event = HTTP_EVENT_RES_LINE;
- if (half->http_ev_cb != NULL)
+ if (half->http_ev_cb != NULL) // http_event_handler()
{
half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
}
@@ -459,8 +426,7 @@ static int on_header_value_complete(llhttp_t *http)
struct http_header http_hdr = {0};
struct hstring key = {.str = (char *)"Content-Encoding", .str_len = 16};
- if (http_decoder_table_get_header(half->ref_data->table, &key,
- &http_hdr) == 0)
+ if (http_decoder_table_get_header(half->ref_data->table, &key, &http_hdr) == 0)
{
char encoding_str[MAX_ENCODING_STR_LEN + 1] = {0};
size_t str_len = http_hdr.val.str_len;
@@ -520,20 +486,12 @@ static int on_headers_complete(llhttp_t *http)
if (half->parser.type == HTTP_REQUEST)
{
half->event = HTTP_EVENT_REQ_HDR_END;
- if (half->http_ev_cb)
- {
- half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx);
- }
}
-
- if (half->parser.type == HTTP_RESPONSE)
+ else
{
half->event = HTTP_EVENT_RES_HDR_END;
- if (half->http_ev_cb)
- {
- 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); // http_event_handler()
return 0;
}
@@ -553,11 +511,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;
- if (half->http_ev_cb)
- {
- 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); // http_event_handler()
}
}
else
@@ -565,11 +519,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;
- if (half->http_ev_cb)
- {
- 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);
}
}
@@ -595,35 +545,24 @@ 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;
- if (half->http_ev_cb)
- {
- 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); // http_event_handler()
}
else
{
half->event = HTTP_EVENT_RES_BODY_DATA;
- if (half->http_ev_cb)
- {
- 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);
}
return 0;
}
-static void
-http_decoder_half_init(struct http_decoder_half *half,
- http_event_cb *http_ev_cb, int type)
+static void http_decoder_half_init(struct http_decoder_half *half,
+ http_event_cb *http_ev_cb, enum llhttp_type type)
{
- if (NULL == half)
- {
- return;
- }
-
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;
@@ -653,14 +592,12 @@ http_decoder_half_init(struct http_decoder_half *half,
half->settings.on_body = on_body;
half->error = HPE_OK;
-
- half->http_ev_cb = http_ev_cb;
-
+ half->http_ev_cb = http_ev_cb; // http_event_handler()
half->ref_data = NULL;
}
struct http_decoder_half *
-http_decoder_half_new(nmx_pool_t *mempool, http_event_cb *ev_cb, int http_type,
+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 *half = MEMPOOL_CALLOC(mempool, struct http_decoder_half, 1);
@@ -694,7 +631,6 @@ void http_decoder_half_reinit(struct http_decoder_half *half, int topic_id,
nmx_pool_t *mempool, struct session *sess)
{
assert(half != NULL);
-
if (half->ref_data != NULL)
{
http_decoder_table_reinit(half->ref_data->table);
@@ -712,31 +648,13 @@ static void publish_message_for_parsed_header(struct http_decoder_half *half)
{
return;
}
-
- // publish complete kv-header message
- struct http_message *msg = NULL;
- size_t queue_idx = 0;
- struct http_decoder_result_queue *queue = half->http_ev_ctx->ref_queue;
-
- if (half->parser.type == HTTP_REQUEST)
- {
- queue_idx = http_decoder_result_queue_req_index(queue);
-
- msg = http_message_new(HTTP_MESSAGE_REQ_HEADER, queue, queue_idx);
-
- session_mq_publish_message(half->http_ev_ctx->ref_session,
- half->http_ev_ctx->topic_id, msg);
- }
- else
- {
- // http response
- queue_idx = http_decoder_result_queue_res_index(queue);
-
- msg = http_message_new(HTTP_MESSAGE_RES_HEADER, queue, queue_idx);
-
- session_mq_publish_message(half->http_ev_ctx->ref_session,
- half->http_ev_ctx->topic_id, msg);
+ if (half->parser.type == HTTP_REQUEST){
+ half->event = HTTP_EVENT_REQ_HDR;
+ }else{
+ half->event = HTTP_EVENT_RES_HDR;
}
+ half->http_ev_cb(half->event, &half->ref_data, half->http_ev_ctx); // http_event_handler();
+ return;
}
int http_decoder_half_parse(struct http_decoder_half *half, const char *data,
@@ -752,7 +670,7 @@ int http_decoder_half_parse(struct http_decoder_half *half, const char *data,
half->error = llhttp_execute(&half->parser, data, data_len);
int ret = 0;
- uint8_t type = 0;
+ enum llhttp_type type = HTTP_BOTH;
struct http_decoder_half_data *half_data = NULL;
switch (half->error)
@@ -767,7 +685,7 @@ int http_decoder_half_parse(struct http_decoder_half *half, const char *data,
ret = 0;
break;
default:
- type = half->parser.type;
+ type = (enum llhttp_type)half->parser.type;
llhttp_init(&half->parser, type, &half->settings);
ret = -1;
break;
@@ -807,8 +725,9 @@ int http_decoder_half_parse(struct http_decoder_half *half, const char *data,
{
http_decoder_table_reset_header_complete(half->ref_data->table);
}
- else
+ else
{
+ //if headers are not completed with EOF \r\n\r\n, push the parsed headers so far
publish_message_for_parsed_header(half);
}
@@ -926,11 +845,6 @@ void http_decoder_half_data_free(nmx_pool_t *mempool,
int http_decoder_half_data_get_request_line(struct http_decoder_half_data *data,
struct http_request_line *line)
{
- if (NULL == data || NULL == line)
- {
- return -1;
- }
-
http_decoder_table_get_method(data->table, &line->method);
http_decoder_table_get_uri(data->table, &line->uri);
http_decoder_table_get_version(data->table, &line->version);
@@ -944,11 +858,6 @@ int 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)
{
- if (NULL == data || NULL == line)
- {
- return -1;
- }
-
http_decoder_table_get_version(data->table, &line->version);
http_decoder_table_get_status(data->table, &line->status);
@@ -959,25 +868,17 @@ int http_decoder_half_data_get_response_line(struct http_decoder_half_data *data
return 0;
}
-int http_decoder_half_data_get_header(struct http_decoder_half_data *data,
- struct hstring *key,
+int http_decoder_half_data_get_header(const struct http_decoder_half_data *data,
+ const struct hstring *key,
struct http_header *hdr_result)
{
- if (NULL == data || NULL == key || NULL == hdr_result)
- {
- return -1;
- }
return http_decoder_table_get_header(data->table, key, hdr_result);
}
int http_decoder_half_data_iter_header(struct http_decoder_half_data *data,
struct http_header *header)
{
- if (NULL == data || NULL == header)
- {
- return -1;
- }
- return http_decoder_table_iter_header(data->table, 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)
@@ -998,7 +899,7 @@ int http_decoder_half_data_has_parsed_header(struct http_decoder_half_data *data
return http_decoder_table_has_parsed_header(data->table);
}
-int http_decoder_half_data_get_raw_body(struct http_decoder_half_data *data,
+int http_decoder_half_data_get_raw_body(const struct http_decoder_half_data *data,
struct hstring *body)
{
if (NULL == data || NULL == body)
@@ -1008,14 +909,9 @@ int http_decoder_half_data_get_raw_body(struct http_decoder_half_data *data,
return http_decoder_table_get_body(data->table, body);
}
-int http_decoder_half_data_get_decompress_body(struct http_decoder_half_data *data,
+int http_decoder_half_data_get_decompress_body(const struct http_decoder_half_data *data,
struct hstring *body)
{
- if (NULL == data || NULL == body)
- {
- return -1;
- }
-
if (HTTP_CONTENT_ENCODING_NONE == data->content_encoding)
{
return http_decoder_table_get_body(data->table, body);
@@ -1115,7 +1011,7 @@ int http_decoder_join_url_finally(struct http_event_context *ev_ctx,
void http_decoder_get_host_feed_url(struct http_decoder_half *half)
{
struct http_header host_result = {};
- struct hstring host_key = {"Host", 4};
+ struct hstring host_key = {(char *)"Host", 4};
const char *host_refer_str = NULL;
int host_refer_len = 0;
@@ -1140,14 +1036,17 @@ int http_half_data_get_url(struct http_decoder_half_data *res_data, struct hstri
{
return -1;
}
-
url->str = res_data->joint_url.str;
url->str_len = res_data->joint_url.str_len;
-
return 0;
}
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)
+{
+ http_decoder_table_update_commit_index(half_data->table);
} \ No newline at end of file
diff --git a/src/http_decoder_half.h b/src/http_decoder_half.h
index a2ff5f8..362708a 100644
--- a/src/http_decoder_half.h
+++ b/src/http_decoder_half.h
@@ -1,28 +1,12 @@
-/*
-**********************************************************************************************
-* File: http_decoder_half.h
-* Description:
-* Authors: Liu WenTan <[email protected]>
-* Date: 2024-01-10
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
-
#ifndef _HTTP_DECODER_HALF_H_
#define _HTTP_DECODER_HALF_H_
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
#include <stddef.h>
-
#include "stellar/session.h"
#include "http_decoder.h"
#include "http_content_decompress.h"
#include "http_decoder_result_queue.h"
+#include "llhttp.h"
// only one http event is fired at a time
enum http_event {
@@ -59,7 +43,7 @@ typedef void http_event_cb(enum http_event event, struct http_decoder_half_data
struct http_event_context *ev_ctx);
struct http_decoder_half *
-http_decoder_half_new(nmx_pool_t *mempool, http_event_cb *event_cb, int http_type,
+http_decoder_half_new(nmx_pool_t *mempool, http_event_cb *event_cb, enum llhttp_type http_type,
int decompress_switch);
void http_decoder_half_free(nmx_pool_t *mempool, struct http_decoder_half *half);
@@ -86,18 +70,18 @@ int 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);
-int http_decoder_half_data_get_header(struct http_decoder_half_data *data,
- struct hstring *key, struct http_header *hdr_res);
+int http_decoder_half_data_get_header(const struct http_decoder_half_data *data,
+ const struct hstring *key, struct http_header *hdr_res);
int http_decoder_half_data_iter_header(struct http_decoder_half_data *data,
struct http_header *header);
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(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_decompress_body(struct http_decoder_half_data *data,
+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);
@@ -112,8 +96,5 @@ int http_decoder_join_url_finally(struct http_event_context *ev_ctx,
int http_half_data_get_url(struct http_decoder_half_data *res_data, struct hstring *url);
int http_half_data_get_transaction_seq(struct http_decoder_half_data *hf_data);
-#ifdef __cplusplus
-}
-#endif
-
+void http_half_data_update_commit_index(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 2d6a5c0..3e2939d 100644
--- a/src/http_decoder_inc.h
+++ b/src/http_decoder_inc.h
@@ -15,36 +15,114 @@
extern "C"
{
#endif
+#include "stellar/stellar.h"
+#include "stellar/utils.h"
+#include "stellar/session.h"
+#include "stellar/session_mq.h"
+#include "stellar/session_exdata.h"
#include "mempool/nmx_palloc.h"
#include "stellar/utils.h"
#include "http_decoder.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"
+#include "fieldstat/fieldstat_easy.h"
+#include "toml/toml.h"
+#ifndef likely
+#define likely(x) __builtin_expect((x), 1)
+#endif
+#ifndef unlikely
+#define unlikely(x) __builtin_expect((x), 0)
+#endif
#define MEMPOOL_CALLOC(pool, type, number) ((type *)nmx_pcalloc(pool, sizeof(type) * number))
#define MEMPOOL_REALLOC(pool)
#define MEMPOOL_FREE(pool, p) nmx_pfree(pool, p)
+#define ENABLE_MEMPOOL 1
#ifdef ENABLE_MEMPOOL
-
#define HD_CALLOC(pool, type, number) MEMPOOL_CALLOC(pool, number, type)
#define HD_FREE(pool, p) MEMPOOL_FREE(pool, p)
-
#else
-
#define HD_CALLOC(pool, type, number) CALLOC(type, number)
#define HD_FREE(pool, p) FREE(p)
-
#endif
+#define HTTP_IDENTIFY_LEN 16
+#define HD_RESULT_QUEUE_LEN 16
+
+#define DEFAULT_STAT_OUTPUT_INTERVAL 1
+#define DEFAULT_STAT_INTERVAL_PKTS 1000
+#define DEFAULT_MEMPOOL_SIZE (32 * 1024)
+
+#define HTTPD_CFG_FILE "./etc/http/http_decoder.toml"
+#define FILEDSTAT_OUTPUT_FILE "./http_decoder.fs"
+
+struct http_decoder_config
+{
+ int decompress_switch;
+ int stat_interval_pkts; // call fieldstat_incrby every stat_interval_pkts
+ int stat_output_interval;
+ size_t result_queue_len; // per session result queue length
+ size_t mempool_size; // per session mempool size
+};
+
+/**
+ * NOTE: http_message don't have the ownership of data
+ */
+struct http_message
+{
+ uint8_t flow_type;
+ enum http_message_type type;
+ size_t queue_index;
+ struct http_decoder_result_queue *ref_queue;
+};
+
+struct http_decoder
+{
+ struct http_decoder_half *c2s_half;
+ struct http_decoder_half *s2c_half;
+};
+
+struct http_decoder_exdata
+{
+ struct http_decoder_result_queue *queue;
+ struct http_decoder *decoder;
+ 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
+{
+ 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_message;
-struct http_message *
-http_message_new(enum http_message_type type,
- struct http_decoder_result_queue *queue,
- int queue_index);
+struct http_message *http_message_new(enum http_message_type type, struct http_decoder_result_queue *queue,
+ int queue_index, unsigned char flow_type);
#ifdef __cplusplus
}
diff --git a/src/http_decoder_result_queue.c b/src/http_decoder_result_queue.cpp
index 9a60d15..32d2895 100644
--- a/src/http_decoder_result_queue.c
+++ b/src/http_decoder_result_queue.cpp
@@ -7,13 +7,8 @@
* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
***********************************************************************************************
*/
-
#include <assert.h>
-
-#include "stellar/utils.h"
-#include "http_decoder_half.h"
#include "http_decoder_inc.h"
-#include "http_decoder_result_queue.h"
struct http_decoder_result_queue *
http_decoder_result_queue_new(nmx_pool_t *mempool, size_t queue_size)
@@ -25,11 +20,9 @@ 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);
assert(queue->array);
-
return queue;
}
@@ -52,17 +45,14 @@ void http_decoder_result_queue_free(nmx_pool_t *mempool,
queue->array[i].res_data = NULL;
}
}
-
MEMPOOL_FREE(mempool, queue->array);
}
-
MEMPOOL_FREE(mempool, queue);
}
void http_decoder_result_queue_inc_req_index(struct http_decoder_result_queue *queue)
{
assert(queue);
-
queue->req_index++;
queue->req_index = queue->req_index % queue->queue_size;
}
@@ -70,7 +60,6 @@ void http_decoder_result_queue_inc_req_index(struct http_decoder_result_queue *q
void http_decoder_result_queue_inc_res_index(struct http_decoder_result_queue *queue)
{
assert(queue);
-
queue->res_index++;
queue->res_index = queue->res_index % queue->queue_size;
}
@@ -78,14 +67,12 @@ void http_decoder_result_queue_inc_res_index(struct http_decoder_result_queue *q
size_t http_decoder_result_queue_req_index(struct http_decoder_result_queue *queue)
{
assert(queue);
-
return queue->req_index;
}
size_t http_decoder_result_queue_res_index(struct http_decoder_result_queue *queue)
{
assert(queue);
-
return queue->res_index;
}
@@ -95,12 +82,10 @@ int http_decoder_result_queue_push_req(struct http_decoder_result_queue *queue,
if (NULL == queue || NULL == req_data) {
return -1;
}
-
assert(queue->array[queue->req_index].req_data == NULL);
if (queue->array[queue->req_index].req_data != NULL) {
return -1;
}
-
queue->array[queue->req_index].req_data = req_data;
return 0;
}
@@ -111,7 +96,6 @@ int http_decoder_result_queue_push_res(struct http_decoder_result_queue *queue,
if (NULL == queue || NULL == res_data) {
return -1;
}
-
assert(queue->array[queue->res_index].res_data == NULL);
if (queue->array[queue->res_index].res_data != NULL) {
return -1;
@@ -127,7 +111,6 @@ 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;
queue->array[queue->req_index].req_data = NULL;
@@ -155,7 +138,6 @@ http_decoder_result_queue_peek_req(struct http_decoder_result_queue *queue)
if (NULL == queue) {
return NULL;
}
-
assert(queue->req_index < queue->queue_size);
return queue->array[queue->req_index].req_data;
}
@@ -166,7 +148,6 @@ http_decoder_result_queue_peek_res(struct http_decoder_result_queue *queue)
if (NULL == queue) {
return NULL;
}
-
assert(queue->res_index < queue->queue_size);
return queue->array[queue->res_index].res_data;
} \ No newline at end of file
diff --git a/src/http_decoder_result_queue.h b/src/http_decoder_result_queue.h
index cd2163a..4d024eb 100644
--- a/src/http_decoder_result_queue.h
+++ b/src/http_decoder_result_queue.h
@@ -7,18 +7,10 @@
* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
***********************************************************************************************
*/
-
-
#ifndef _HTTP_DECODER_RESULT_QUEUE_H_
#define _HTTP_DECODER_RESULT_QUEUE_H_
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
#include <stddef.h>
-
#include "mempool/nmx_palloc.h"
#include "http_decoder_half.h"
@@ -66,8 +58,4 @@ http_decoder_result_queue_peek_req(struct http_decoder_result_queue *queue);
struct http_decoder_half_data *
http_decoder_result_queue_peek_res(struct http_decoder_result_queue *queue);
-#ifdef __cplusplus
-}
-#endif
-
#endif \ No newline at end of file
diff --git a/src/http_decoder_stat.cpp b/src/http_decoder_stat.cpp
new file mode 100644
index 0000000..ffa01eb
--- /dev/null
+++ b/src/http_decoder_stat.cpp
@@ -0,0 +1,99 @@
+#include <assert.h>
+#include <stdio.h>
+#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)
+{
+ 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;
+ }
+
+ 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;
+ }
+
+ ctx->fs_err_pkts_id = fieldstat_easy_register_counter(ctx->fse, "err_pkts");
+ if (ctx->fs_err_pkts_id < 0)
+ {
+ fprintf(stderr, "fieldstat_easy_register_counter err_pkts failed.");
+ return -1;
+ }
+
+ int stat_output_interval = DEFAULT_STAT_OUTPUT_INTERVAL;
+ if (ctx->hd_cfg.stat_output_interval > 0)
+ {
+ stat_output_interval = ctx->hd_cfg.stat_output_interval;
+ }
+
+ int ret = fieldstat_easy_enable_auto_output(ctx->fse, FILEDSTAT_OUTPUT_FILE,
+ stat_output_interval);
+ if (ret < 0)
+ {
+ fprintf(stderr, "fieldstat_easy_enable_auto_output failed.");
+ return -1;
+ }
+
+ return 0;
+}
+
+void http_decoder_stat_output(struct http_decoder_context *ctx, int thread_id)
+{
+ 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;
+ }
+}
diff --git a/src/http_decoder_stat.h b/src/http_decoder_stat.h
new file mode 100644
index 0000000..dbf245f
--- /dev/null
+++ b/src/http_decoder_stat.h
@@ -0,0 +1,5 @@
+#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);
+#endif \ No newline at end of file
diff --git a/src/http_decoder_string.c b/src/http_decoder_string.cpp
index 5414c5b..e10b4a0 100644
--- a/src/http_decoder_string.c
+++ b/src/http_decoder_string.cpp
@@ -1,21 +1,8 @@
-/*
-**********************************************************************************************
-* File: http_decoder_string.h
-* Description:
-* Authors: LuWenPeng <[email protected]>
-* Date: 2022-10-31
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
-
-#include "stellar/utils.h"
-#include "http_decoder_utils.h"
-#include "http_decoder_string.h"
+#include "http_decoder_inc.h"
static const char *string_state_to_desc(enum string_state state)
{
@@ -64,7 +51,6 @@ static void string_refer2cache(struct http_decoder_string *rstr)
if (0 == rstr->refer.str_len) {
return;
}
-
if (rstr->cache.str_len >= rstr->max_cache_size) {
return;
}
@@ -84,7 +70,6 @@ static void string_refer2cache(struct http_decoder_string *rstr)
}
rstr->cache.str_len = length;
-
rstr->refer.str = NULL;
rstr->refer.str_len = 0;
}
@@ -93,7 +78,6 @@ static void string_commit2cache(struct http_decoder_string *rstr)
{
if (rstr->cache.str_len == rstr->commit.str_len &&
rstr->cache.str == rstr->commit.str) {
-
rstr->commit.str = NULL;
rstr->commit.str_len = 0;
return;
@@ -141,7 +125,6 @@ void http_decoder_string_cache(struct http_decoder_string *rstr)
abort();
break;
}
-
rstr->state = STRING_STATE_CACHE;
}
@@ -226,19 +209,17 @@ void http_decoder_string_reinit(struct http_decoder_string *rstr)
rstr->refer.str = NULL;
rstr->refer.str_len = 0;
-
rstr->commit.str = NULL;
rstr->commit.str_len = 0;
-
rstr->state = STRING_STATE_INIT;
}
-enum string_state http_decoder_string_state(struct http_decoder_string *rstr)
+enum string_state http_decoder_string_state(const struct http_decoder_string *rstr)
{
return rstr->state;
}
-int http_decoder_string_get(struct http_decoder_string *rstr, struct hstring *out)
+int http_decoder_string_get(const struct http_decoder_string *rstr, struct hstring *out)
{
if (NULL == rstr || NULL == out) {
return -1;
diff --git a/src/http_decoder_string.h b/src/http_decoder_string.h
index f9d81dd..4c95960 100644
--- a/src/http_decoder_string.h
+++ b/src/http_decoder_string.h
@@ -1,24 +1,8 @@
-/*
-**********************************************************************************************
-* File: http_decoder_string.h
-* Description:
-* Authors: LuWenPeng <[email protected]>
-* Date: 2022-10-31
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
#ifndef _HTTP_DECODER_STRING_H_
#define _HTTP_DECODER_STRING_H_
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
#include "http_decoder.h"
-
enum string_state {
STRING_STATE_INIT,
STRING_STATE_REFER,
@@ -82,14 +66,9 @@ void http_decoder_string_init(struct http_decoder_string *rstr,
void http_decoder_string_reinit(struct http_decoder_string *rstr);
-enum string_state http_decoder_string_state(struct http_decoder_string *rstr);
+enum string_state http_decoder_string_state(const struct http_decoder_string *rstr);
-int http_decoder_string_get(struct http_decoder_string *rstr, struct hstring *out);
+int http_decoder_string_get(const struct http_decoder_string *rstr, struct hstring *out);
void http_decoder_string_dump(struct http_decoder_string *rstr, const char *desc);
-
-#ifdef __cplusplus
-}
-#endif
-
#endif \ No newline at end of file
diff --git a/src/http_decoder_table.c b/src/http_decoder_table.cpp
index cc3e7cb..b11e1b9 100644
--- a/src/http_decoder_table.c
+++ b/src/http_decoder_table.cpp
@@ -1,22 +1,7 @@
-/*
-**********************************************************************************************
-* File: http_decoder_table.c
-* Description:
-* Authors: LuWenPeng <[email protected]>
-* Date: 2022-10-31
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
-
#include <assert.h>
#include <stdlib.h>
#include <string.h>
-
-#include "http_decoder_table.h"
-#include "http_decoder.h"
-#include "http_decoder_string.h"
-#include "stellar/utils.h"
+#include "http_decoder_inc.h"
#define INIT_HEADER_CNT 16
#define MAX_URI_CACHE_SIZE 2048
@@ -41,8 +26,9 @@ struct http_decoder_table {
nmx_pool_t *ref_mempool;
int header_complete; // flag for all headers parsed completely
size_t header_cnt;
- size_t header_index;
- size_t header_iter;
+ 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_header_next()
struct http_decoder_header *headers;
};
@@ -79,7 +65,7 @@ struct http_decoder_table *http_decoder_table_new(nmx_pool_t *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;
@@ -90,23 +76,18 @@ void http_decoder_table_free(struct http_decoder_table *table)
if (NULL == table) {
return;
}
-
if (table->uri.cache.str != NULL) {
FREE(table->uri.cache.str);
}
-
if (table->status.cache.str != NULL) {
FREE(table->status.cache.str);
}
-
if (table->method.cache.str != NULL) {
FREE(table->method.cache.str);
}
-
if (table->version.cache.str != NULL) {
FREE(table->version.cache.str);
}
-
if (table->body.cache.str != NULL) {
FREE(table->body.cache.str);
}
@@ -125,7 +106,6 @@ void http_decoder_table_free(struct http_decoder_table *table)
MEMPOOL_FREE(table->ref_mempool, table->headers);
table->headers = NULL;
}
-
MEMPOOL_FREE(table->ref_mempool, table);
}
@@ -135,7 +115,6 @@ 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);
@@ -361,18 +340,16 @@ void http_decoder_table_reset(struct http_decoder_table *table, enum http_item t
void http_decoder_table_reinit(struct http_decoder_table *table)
{
- if (NULL == table) {
- return;
- }
-
- struct http_decoder_header *header = NULL;
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->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);
@@ -404,60 +381,51 @@ void http_decoder_table_dump(struct http_decoder_table *table)
}
}
-int http_decoder_table_get_uri(struct http_decoder_table *table, struct hstring *out)
+int http_decoder_table_get_uri(const struct http_decoder_table *table, struct hstring *out)
{
if (NULL == table || NULL == out) {
return -1;
}
-
return http_decoder_string_get(&table->uri, out);
}
-int http_decoder_table_get_method(struct http_decoder_table *table, struct hstring *out)
+int http_decoder_table_get_method(const struct http_decoder_table *table, struct hstring *out)
{
if (NULL == table || NULL == out) {
return -1;
}
-
return http_decoder_string_get(&table->method, out);
}
-int http_decoder_table_get_status(struct http_decoder_table *table, struct hstring *out)
+int http_decoder_table_get_status(const struct http_decoder_table *table, struct hstring *out)
{
if (NULL == table || NULL == out) {
return -1;
}
-
return http_decoder_string_get(&table->status, out);
}
-int http_decoder_table_get_version(struct http_decoder_table *table, struct hstring *out)
+int http_decoder_table_get_version(const struct http_decoder_table *table, struct hstring *out)
{
if (NULL == table || NULL == out) {
return -1;
}
-
return http_decoder_string_get(&table->version, out);
}
-int http_decoder_table_get_body(struct http_decoder_table *table, struct hstring *out)
+int http_decoder_table_get_body(const struct http_decoder_table *table, struct hstring *out)
{
if (NULL == table || NULL == out) {
return -1;
}
-
return http_decoder_string_get(&table->body, out);
}
-int http_decoder_table_get_header(struct http_decoder_table *table, struct hstring *key,
+int http_decoder_table_get_header(const struct http_decoder_table *table, const struct hstring *key,
struct http_header *hdr_result)
{
- if (NULL == table || NULL == key->str || 0 == key->str_len || NULL == hdr_result) {
- return -1;
- }
-
for (size_t i = 0; i < table->header_cnt; i++) {
- struct http_decoder_header *tmp_header = &table->headers[i];
+ const struct http_decoder_header *tmp_header = &table->headers[i];
if (tmp_header->key.commit.str_len != key->str_len) {
continue;
}
@@ -475,7 +443,6 @@ int http_decoder_table_get_header(struct http_decoder_table *table, struct hstri
}
}
}
-
return -1;
}
@@ -485,7 +452,6 @@ int http_decoder_table_iter_header(struct http_decoder_table *table,
if (NULL == table || NULL == hdr) {
return -1;
}
-
if (table->header_iter >= table->header_cnt) {
return -1;
}
@@ -498,13 +464,12 @@ int http_decoder_table_iter_header(struct http_decoder_table *table,
http_decoder_string_get(&tmp_header->key, &hdr->key);
http_decoder_string_get(&tmp_header->val, &hdr->val);
table->header_iter++;
- return 0;
+ return 1;
}
}
hdr->key.str = NULL;
hdr->key.str_len = 0;
-
hdr->val.str = NULL;
hdr->val.str_len = 0;
@@ -519,13 +484,15 @@ int http_decoder_table_reset_header_iter(struct http_decoder_table *table)
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->header_iter == table->header_index)) {
+ if (NULL == table || (table->commit_header_index == table->header_index)) {
return 0;
}
- 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) {
+ 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;
}
@@ -537,7 +504,6 @@ int http_decoder_table_header_complete(struct http_decoder_table *table)
if (NULL == table) {
return -1;
}
-
return table->header_complete;
}
@@ -546,7 +512,6 @@ void http_decoder_table_set_header_complete(struct http_decoder_table *table)
if (NULL == table) {
return;
}
-
table->header_complete = 1;
}
@@ -555,6 +520,10 @@ 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;
} \ No newline at end of file
diff --git a/src/http_decoder_table.h b/src/http_decoder_table.h
index 906a28d..ce79d46 100644
--- a/src/http_decoder_table.h
+++ b/src/http_decoder_table.h
@@ -1,23 +1,6 @@
-/*
-**********************************************************************************************
-* File: http_decoder_table.h
-* Description:
-* Authors: LuWenPeng <[email protected]>
-* Date: 2022-10-31
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
-
#ifndef _HTTP_DECODER_TABLE_H_
#define _HTTP_DECODER_TABLE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <stddef.h>
-
#include "http_decoder.h"
#include "http_decoder_inc.h"
#include "http_decoder_string.h"
@@ -53,18 +36,18 @@ 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(struct http_decoder_table *table, struct hstring *out);
+int http_decoder_table_get_uri(const struct http_decoder_table *table, struct hstring *out);
-int http_decoder_table_get_method(struct http_decoder_table *table, struct hstring *out);
+int http_decoder_table_get_method(const struct http_decoder_table *table, struct hstring *out);
-int http_decoder_table_get_status(struct http_decoder_table *table, struct hstring *out);
+int http_decoder_table_get_status(const struct http_decoder_table *table, struct hstring *out);
-int http_decoder_table_get_version(struct http_decoder_table *table, struct hstring *out);
+int http_decoder_table_get_version(const struct http_decoder_table *table, struct hstring *out);
-int http_decoder_table_get_body(struct http_decoder_table *table, struct hstring *out);
+int http_decoder_table_get_body(const struct http_decoder_table *table, struct hstring *out);
-int http_decoder_table_get_header(struct http_decoder_table *table,
- struct hstring *key,
+int http_decoder_table_get_header(const struct http_decoder_table *table,
+ const struct hstring *key,
struct http_header *hdr_res);
int http_decoder_table_iter_header(struct http_decoder_table *table,
@@ -91,8 +74,6 @@ void http_decoder_table_set_header_complete(struct http_decoder_table *table);
void http_decoder_table_reset_header_complete(struct http_decoder_table *table);
-#ifdef __cplusplus
-}
-#endif
+void http_decoder_table_update_commit_index(struct http_decoder_table *table);
#endif \ No newline at end of file
diff --git a/src/http_decoder_utils.c b/src/http_decoder_utils.c
deleted file mode 100644
index a5dfbe1..0000000
--- a/src/http_decoder_utils.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-**********************************************************************************************
-* File: http_decoder_utils.c
-* Description:
-* Authors: LuWenPeng <[email protected]>
-* Date: 2022-10-31
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
-#include <string.h>
-
-#include "stellar/utils.h"
-
-char *safe_dup(const char *str, size_t len)
-{
- if (str == NULL || len == 0) {
- return NULL;
- }
-
- char *dup = CALLOC(char, len + 1);
- memcpy(dup, str, len);
-
- return dup;
-} \ No newline at end of file
diff --git a/src/http_decoder_utils.cpp b/src/http_decoder_utils.cpp
new file mode 100644
index 0000000..5686e2d
--- /dev/null
+++ b/src/http_decoder_utils.cpp
@@ -0,0 +1,137 @@
+#include <string.h>
+#include <assert.h>
+#include "http_decoder_inc.h"
+
+char *safe_dup(const char *str, size_t len)
+{
+ if (str == NULL || len == 0) {
+ return NULL;
+ }
+ char *dup = CALLOC(char, len + 1);
+ memcpy(dup, str, len);
+ return dup;
+}
+
+const char *http_message_type_to_string(enum http_message_type type)
+{
+ const char *sname = "unknown_msg_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";
+ break;
+ case HTTP_MESSAGE_REQ_BODY:
+ sname = "HTTP_MESSAGE_REQ_BODY";
+ break;
+ 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";
+ break;
+ case HTTP_MESSAGE_RES_BODY:
+ sname = "HTTP_MESSAGE_RES_BODY";
+ break;
+ case HTTP_MESSAGE_RES_BODY_END:
+ sname = "HTTP_MESSAGE_RES_BODY_END";
+ break;
+ case HTTP_TRANSACTION_NEW:
+ sname = "HTTP_TRANSACTION_NEW";
+ break;
+ case HTTP_TRANSACTION_FREE:
+ sname = "HTTP_TRANSACTION_FREE";
+ break;
+
+ default:
+ break;
+ }
+
+ return sname;
+}
+
+int http_message_type_is_req(struct session *sess, enum http_message_type msg_type)
+{
+ int is_req_msg = 0;
+
+ switch(msg_type){
+ case HTTP_MESSAGE_REQ_LINE:
+ case HTTP_MESSAGE_REQ_HEADER:
+ case HTTP_MESSAGE_REQ_HEADER_END:
+ 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_BODY:
+ case HTTP_MESSAGE_RES_BODY_END:
+ is_req_msg = 0;
+ break;
+
+ case HTTP_TRANSACTION_NEW:
+ case HTTP_TRANSACTION_FREE:
+ {
+ int cur_dir = packet_get_direction(session_get0_current_packet(sess));
+ if(PACKET_DIRECTION_C2S == cur_dir){
+ is_req_msg = 1;
+ }else{
+ is_req_msg = 0;
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+ fprintf(stderr, "unknow message type:%d\n", (int)msg_type);
+ break;
+ }
+ return is_req_msg;
+}
+
+int http_event_is_req(enum http_event event)
+{
+ switch(event){
+ case HTTP_EVENT_REQ_INIT:
+ case HTTP_EVENT_REQ_LINE:
+ case HTTP_EVENT_REQ_HDR:
+ case HTTP_EVENT_REQ_HDR_END:
+ case HTTP_EVENT_REQ_BODY_BEGIN:
+ case HTTP_EVENT_REQ_BODY_DATA:
+ case HTTP_EVENT_REQ_BODY_END:
+ case HTTP_EVENT_REQ_END:
+ return 1;
+ break;
+
+ case HTTP_EVENT_RES_INIT:
+ case HTTP_EVENT_RES_LINE:
+ case HTTP_EVENT_RES_HDR:
+ case HTTP_EVENT_RES_HDR_END:
+ case HTTP_EVENT_RES_BODY_BEGIN:
+ case HTTP_EVENT_RES_BODY_DATA:
+ case HTTP_EVENT_RES_BODY_END:
+ case HTTP_EVENT_RES_END:
+ return 0;
+ break;
+
+ default:
+ assert(0);
+ fprintf(stderr, "unknow event type:%d\n", (int)event);
+ break;
+ }
+ return -1;
+} \ No newline at end of file
diff --git a/src/http_decoder_utils.h b/src/http_decoder_utils.h
index 9c031a3..0661641 100644
--- a/src/http_decoder_utils.h
+++ b/src/http_decoder_utils.h
@@ -1,28 +1,13 @@
-/*
-**********************************************************************************************
-* File: http_decoder_utils.h
-* Description:
-* Authors: LuWenPeng <[email protected]>
-* Date: 2022-10-31
-* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
-***********************************************************************************************
-*/
-
-
#ifndef _HTTP_DECODER_UTILS_H_
#define _HTTP_DECODER_UTILS_H_
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
#include <stdlib.h>
#include <stdio.h>
-
char *safe_dup(const char *str, size_t len);
-
+const char *http_message_type_to_string(enum http_message_type type);
+int http_message_type_is_req(struct session *sess, enum http_message_type msg_type);
+int http_event_is_req(enum http_event event);
/******************************************************************************
* Logger
******************************************************************************/
@@ -58,9 +43,4 @@ enum http_decoder_log_level {
} \
}
#endif
-
-#ifdef __cplusplus
-}
-#endif
-
#endif \ No newline at end of file
diff --git a/src/version.map b/src/version.map
index 4b8c6d0..be433c2 100644
--- a/src/version.map
+++ b/src/version.map
@@ -3,8 +3,8 @@ global:
extern "C" {
http_message_*;
http_decoder_init;
- http_decoder_entry;
http_decoder_exit;
+ http_decoder_tcp_stream_msg_cb;
};
local: *;
}; \ No newline at end of file