summaryrefslogtreecommitdiff
path: root/test/http_decoder_gtest.cpp
diff options
context:
space:
mode:
authorlijia <[email protected]>2024-06-18 16:45:35 +0800
committerlijia <[email protected]>2024-06-20 18:51:47 +0800
commit05e8c9db6912dc95de9691e9b90e549a4c3beffe (patch)
treeed5d4b3392bdd577986d26ac8d5c6da21f9c2b2a /test/http_decoder_gtest.cpp
parent7d6170a23027aff0ebf2e7832dc11e4bbdce57ea (diff)
feat: TSG-20446, support http tunnel with CONNECT method.
Diffstat (limited to 'test/http_decoder_gtest.cpp')
-rw-r--r--test/http_decoder_gtest.cpp156
1 files changed, 110 insertions, 46 deletions
diff --git a/test/http_decoder_gtest.cpp b/test/http_decoder_gtest.cpp
index b2677fc..27fb0e6 100644
--- a/test/http_decoder_gtest.cpp
+++ b/test/http_decoder_gtest.cpp
@@ -17,6 +17,7 @@ extern "C"
int commit_test_result_json(cJSON *node, const char *name);
extern void http_decoder_test_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env);
extern void http_decoder_test_state_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env);
+ extern void http_decoder_tunnel_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env);
static on_session_msg_cb_func *g_entry_fun = http_decoder_test_entry;
}
#endif
@@ -32,6 +33,7 @@ struct plug_entry_t{
static struct plug_entry_t g_entry_tbl[] = {
{"http_decoder_test_entry", http_decoder_test_entry},
{"http_decoder_test_state_entry", http_decoder_test_state_entry},
+ {"http_decoder_tunnel_entry", http_decoder_tunnel_entry},
{NULL, NULL}
};
@@ -61,26 +63,26 @@ static int g_topic_id = -1;
void output_http_req_line(struct http_request_line *req_line)
{
char tmp_str[MAX_KEY_STR_LEN] = {0};
- memcpy(tmp_str, req_line->method.str, req_line->method.str_len);
+ memcpy(tmp_str, req_line->method.iov_base, req_line->method.iov_len);
printf("req_method:%s\n", tmp_str);
memset(tmp_str, 0, sizeof(tmp_str));
- memcpy(tmp_str, req_line->uri.str, req_line->uri.str_len);
+ memcpy(tmp_str, req_line->uri.iov_base, req_line->uri.iov_len);
printf("req_uri:%s\n", tmp_str);
memset(tmp_str, 0, sizeof(tmp_str));
- memcpy(tmp_str, req_line->version.str, req_line->version.str_len);
+ memcpy(tmp_str, req_line->version.iov_base, req_line->version.iov_len);
printf("req_version:%s\n", tmp_str);
}
void output_http_res_line(struct http_response_line *res_line)
{
char tmp_str[MAX_KEY_STR_LEN] = {0};
- memcpy(tmp_str, res_line->version.str, res_line->version.str_len);
+ memcpy(tmp_str, res_line->version.iov_base, res_line->version.iov_len);
printf("res_version:%s\n", tmp_str);
memset(tmp_str, 0, sizeof(tmp_str));
- memcpy(tmp_str, res_line->status.str, res_line->status.str_len);
+ memcpy(tmp_str, res_line->status.iov_base, res_line->status.iov_len);
printf("res_status:%s\n", tmp_str);
}
@@ -89,42 +91,42 @@ void output_http_header(struct http_header *header)
char tmp_key[MAX_KEY_STR_LEN] = {0};
char tmp_val[MAX_KEY_STR_LEN] = {0};
- memcpy(tmp_key, header->key.str, header->key.str_len);
- memcpy(tmp_val, header->val.str, header->val.str_len);
+ memcpy(tmp_key, header->key.iov_base, header->key.iov_len);
+ memcpy(tmp_val, header->val.iov_base, header->val.iov_len);
printf("<%s:%s>\n", tmp_key, tmp_val);
}
-void output_http_body(struct hstring *body, int decompress_flag)
+void output_http_body(hstring *body, int decompress_flag)
{
int counter = 0;
if (1 == decompress_flag)
{
printf("\n\n----------------decompress body len:%zu---------------\n",
- body->str_len);
+ body->iov_len);
}
else
{
printf("\n\n----------------raw body len:%zu---------------\n",
- body->str_len);
+ body->iov_len);
}
- for (size_t i = 0; i < body->str_len; i++)
+ for (size_t i = 0; i < body->iov_len; i++)
{
if (counter % 16 == 0)
{
printf("\n");
}
- printf("%02x ", (unsigned char)body->str[i]);
+ printf("%02x ", (unsigned char)body->iov_base[i]);
counter++;
}
printf("\n");
}
#endif
-static void append_http_payload(struct session *sess, struct gtest_plug_exdata_t *gtest_plug_exdata, const struct hstring *body, enum http_transaction_type type)
+static void append_http_payload(struct session *sess, struct gtest_plug_exdata_t *gtest_plug_exdata, const hstring *body, enum http_transaction_type type)
{
- if (NULL == body->str || 0 == body->str_len)
+ if (NULL == body->iov_base || 0 == body->iov_len)
{
return;
}
@@ -133,7 +135,7 @@ static void append_http_payload(struct session *sess, struct gtest_plug_exdata_t
gtest_plug_exdata->md5ctx[type] = MMALLOC(MD5_CTX, sizeof(MD5_CTX));
MD5Init(gtest_plug_exdata->md5ctx[type]);
}
- MD5Update(gtest_plug_exdata->md5ctx[type], (unsigned char *)body->str, body->str_len);
+ MD5Update(gtest_plug_exdata->md5ctx[type], (unsigned char *)body->iov_base, body->iov_len);
}
int http_field_to_json(cJSON *object, const char *key, char *val, size_t val_len)
@@ -158,11 +160,11 @@ void transaction_index_to_json(cJSON *ctx, int transaction_index)
void req_line_to_json(cJSON *ctx, struct http_request_line *req_line)
{
- http_field_to_json(ctx, "method", req_line->method.str,
- req_line->method.str_len);
- http_field_to_json(ctx, "uri", req_line->uri.str, req_line->uri.str_len);
- http_field_to_json(ctx, "req_version", req_line->version.str,
- req_line->version.str_len);
+ http_field_to_json(ctx, "method", (char *)req_line->method.iov_base,
+ req_line->method.iov_len);
+ http_field_to_json(ctx, "uri", (char *)req_line->uri.iov_base, req_line->uri.iov_len);
+ http_field_to_json(ctx, "req_version", (char *)req_line->version.iov_base,
+ req_line->version.iov_len);
cJSON_AddNumberToObject(ctx, "major_version", req_line->major_version);
cJSON_AddNumberToObject(ctx, "minor_version", req_line->minor_version);
@@ -170,10 +172,10 @@ void req_line_to_json(cJSON *ctx, struct http_request_line *req_line)
void res_line_to_json(cJSON *ctx, struct http_response_line *res_line)
{
- http_field_to_json(ctx, "res_version", res_line->version.str,
- res_line->version.str_len);
- http_field_to_json(ctx, "res_status", res_line->status.str,
- res_line->status.str_len);
+ http_field_to_json(ctx, "res_version", (char *)res_line->version.iov_base,
+ res_line->version.iov_len);
+ http_field_to_json(ctx, "res_status", (char *)res_line->status.iov_base,
+ res_line->status.iov_len);
cJSON_AddNumberToObject(ctx, "major_version", res_line->major_version);
cJSON_AddNumberToObject(ctx, "minor_version", res_line->minor_version);
@@ -183,25 +185,27 @@ void res_line_to_json(cJSON *ctx, struct http_response_line *res_line)
void http_header_to_json(cJSON *ctx, struct http_header *header)
{
char key[MAX_KEY_STR_LEN] = {0};
+ assert(header->key.iov_base);
+ assert(header->val.iov_base);
- memcpy(key, header->key.str, header->key.str_len);
+ memcpy(key, header->key.iov_base, header->key.iov_len);
if (cJSON_HasObjectItem(ctx, key) == FALSE)
{
- http_field_to_json(ctx, key, header->val.str, header->val.str_len);
+ http_field_to_json(ctx, key, (char *)header->val.iov_base, header->val.iov_len);
}
else
{
// ctx already has the key, so rename key by key%d
char new_key[MAX_KEY_STR_LEN] = {0};
sprintf(new_key, "%s%d", key, g_header_count++);
- http_field_to_json(ctx, new_key, header->val.str, header->val.str_len);
+ http_field_to_json(ctx, new_key, (char *)header->val.iov_base, header->val.iov_len);
}
}
void http_url_add_to_json(cJSON *ctx, struct http_message *msg)
{
- struct hstring url_result = {};
+ hstring url_result = {};
if (cJSON_GetObjectItem(ctx, GTEST_HTTP_URL_NAME))
{
@@ -209,16 +213,16 @@ void http_url_add_to_json(cJSON *ctx, struct http_message *msg)
}
http_message_get_url(msg, &url_result);
- if(url_result.str == NULL)
+ if(url_result.iov_base == NULL)
{
- // printf("url:%s\n", url_result.str);
+ // printf("url:%s\n", url_result.iov_base);
return;
}
struct http_header url_header_result = {};
- url_header_result.key.str = (char *)GTEST_HTTP_URL_NAME;
- url_header_result.key.str_len = strlen(GTEST_HTTP_URL_NAME);
+ url_header_result.key.iov_base = (char *)GTEST_HTTP_URL_NAME;
+ url_header_result.key.iov_len = strlen(GTEST_HTTP_URL_NAME);
url_header_result.val = url_result;
http_header_to_json(ctx, &url_header_result);
@@ -289,7 +293,7 @@ static void http_decoder_test_update_session_tuple4(struct session *sess, struct
}
}
-static int get_gtest_plug_entry(const char *cfg_path, char *entry_name, int max_len)
+static int get_gtest_plug_entry(const char *cfg_path, char *entry_name, int max_len, char *topic_name, int topic_max_len)
{
FILE *fp = fopen(cfg_path, "r");
if (NULL == fp)
@@ -320,6 +324,14 @@ static int get_gtest_plug_entry(const char *cfg_path, char *entry_name, int max_
strncpy(entry_name, str_val.u.s, max_len);
free(str_val.u.s);
}
+
+ toml_datum_t topic_str_val = toml_string_in(basic_sec_tbl, "topic");
+ if (str_val.ok != 0)
+ {
+ strncpy(topic_name, topic_str_val.u.s, topic_max_len);
+ free(topic_str_val.u.s);
+ }
+
toml_free(root);
return 0;
}
@@ -345,7 +357,7 @@ extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, cons
struct http_request_line req_line = {0};
struct http_response_line res_line = {0};
struct http_header header = {0};
- struct hstring body = {0};
+ hstring body = {0};
struct http_message *msg = (struct http_message *)raw_msg;
enum http_message_type msg_type = http_message_type_get(msg);
@@ -489,30 +501,83 @@ extern "C" void http_decoder_test_state_entry(struct session *sess, int topic_id
return;
}
+extern "C" void http_decoder_tunnel_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env)
+{
+ struct gtest_plug_exdata_t *gtest_plug_exdata;
+ enum http_tunnel_message_type tmsg_type = http_tunnel_message_type_get((const struct http_tunnel_message *)raw_msg);
+ static size_t req_payload_block = 0, req_payload_size = 0;
+ static size_t res_payload_block = 0, res_payload_size = 0;
+ gtest_plug_exdata = (struct gtest_plug_exdata_t *)session_exdata_get(sess, g_exdata_idx);
+
+ switch(tmsg_type){
+ case HTTP_TUNNEL_OPENING:
+ {
+ if (NULL == gtest_plug_exdata)
+ {
+ gtest_plug_exdata = (struct gtest_plug_exdata_t *)calloc(1, sizeof(struct gtest_plug_exdata_t));
+ session_exdata_set(sess, g_exdata_idx, gtest_plug_exdata);
+ }
+ const char *human_addr_cstr = session_get0_readable_addr(sess);
+ gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ] = cJSON_CreateObject();
+ gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES] = cJSON_CreateObject();
+ gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION] = cJSON_CreateObject();
+ cJSON_AddStringToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION], GTEST_HTTP_TUPLE4_NAME, human_addr_cstr);
+ commit_test_result_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION], "TUNNEL_NEW");
+ }
+ // OPENING state has payload, go on
+
+ case HTTP_TUNNEL_ACTIVE:
+ {
+ int curdir = packet_get_direction(session_get0_current_packet(sess));
+ hstring tunnel_payload = {};
+ http_tunnel_message_get_payload((const struct http_tunnel_message *)raw_msg, &tunnel_payload);
+ if(PACKET_DIRECTION_C2S == curdir){
+ req_payload_block++;
+ req_payload_size += tunnel_payload.iov_len;
+ }else{
+ res_payload_block++;
+ res_payload_size += tunnel_payload.iov_len;
+ }
+ }
+ break;
+ case HTTP_TUNNEL_CLOSING:
+ {
+ cJSON_AddStringToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], "flow", "C2S");
+ cJSON_AddStringToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], "flow", "S2C");
+ cJSON_AddNumberToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], "payload_block", req_payload_block);
+ cJSON_AddNumberToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], "payload_size", req_payload_size);
+ cJSON_AddNumberToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], "payload_block", res_payload_block);
+ cJSON_AddNumberToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], "payload_size", res_payload_size);
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
extern "C" void *http_decoder_test_init(struct stellar *st)
{
g_http_gtest_plugin_id = stellar_session_plugin_register(st, NULL, NULL, NULL);
- g_exdata_idx = stellar_session_exdata_new_index(st, "HTTP_DECODER_REQ_TEST",
- http_decoder_test_exdata_free,
- NULL);
+ g_exdata_idx = stellar_session_exdata_new_index(st, "HTTP_DECODER_GTEST_EXDATA",http_decoder_test_exdata_free, NULL);
if (g_exdata_idx < 0)
{
printf("[%s:%d]: can't get http_decoder exdata index !!!\n", __FUNCTION__, __LINE__);
return NULL;
}
- g_topic_id = stellar_session_mq_get_topic_id(st, HTTP_DECODER_TOPIC);
+ char entry_name[64] = "";
+ char topic_name[64] = "";
+ get_gtest_plug_entry(GTEST_PLUG_ENTRY_CFG, entry_name, sizeof(entry_name)-1, topic_name, sizeof(topic_name)-1);
+ set_gtest_plug_entry(entry_name);
+ g_topic_id = stellar_session_mq_get_topic_id(st, topic_name);
if (g_topic_id < 0)
{
- printf("[%s:%d]: can't get http_decoder topic id !!!\n", __FUNCTION__, __LINE__);
+ printf("[%s:%d]: can't get http_decoder topic:%s id !!!\n", __FUNCTION__, __LINE__, topic_name);
return NULL;
- }
-
- char entry_name[64] = "";
- get_gtest_plug_entry(GTEST_PLUG_ENTRY_CFG, entry_name, sizeof(entry_name)-1);
- set_gtest_plug_entry(entry_name);
+ }
stellar_session_mq_subscribe(st, g_topic_id, g_entry_fun, g_http_gtest_plugin_id);
- printf("http_decoder_test_init succ, plugin_id:%d, topic_id:%d\n", g_http_gtest_plugin_id, g_topic_id);
+ printf("http_decoder_gtest_init succ, plugin_id:%d, sub_topic_id:%d\n", g_http_gtest_plugin_id, g_topic_id);
return (void *)strdup("http_decoder_test_ctx");
}
@@ -523,6 +588,5 @@ extern "C" void http_decoder_test_exit(void *test_ctx)
{
FREE(test_ctx);
}
- // update_config_file(GTEST_PLUG_ENTRY_CFG, "name", "\\x22http_decoder_test_entry\\x22");
printf("http_decoder_test_exit OK!\n");
} \ No newline at end of file