Adjust benchmark directory,enable HTTP test,rename variables,format codes

This commit is contained in:
lijia
2024-08-16 14:58:19 +08:00
parent cd2a2360fe
commit 3cdfabb683
153 changed files with 1064 additions and 4415 deletions

View File

View File

@@ -0,0 +1,50 @@
set(DECODER_NAME http)
aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml DEPS_SRC)
add_library(${DECODER_NAME}_test SHARED http_decoder_test_plug.cpp md5.c ${DEPS_SRC})
add_dependencies(${DECODER_NAME}_test ${DECODER_NAME})
target_link_libraries(${DECODER_NAME}_test cjson-static)
set_target_properties(${DECODER_NAME}_test PROPERTIES PREFIX "")
# add_library(${DECODER_NAME}_perf SHARED http_decoder_perf_plug.cpp)
# add_dependencies(${DECODER_NAME}_perf ${DECODER_NAME})
# set_target_properties(${DECODER_NAME}_perf PROPERTIES PREFIX "")
set(TEST_RUN_DIR ${CMAKE_BINARY_DIR}/testing)
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_SOURCE_DIR}/deps)
include_directories(/opt/tsg/stellar/include/)
include_directories(/opt/tsg/framework/include/)
include_directories(${CMAKE_BINARY_DIR}/vendor/llhttp/include)
include_directories(${CMAKE_BINARY_DIR}/vendor/cjson/src/cjson/include)
include_directories(${PROJECT_SOURCE_DIR}/decoders/http)
include_directories(${PROJECT_SOURCE_DIR}/include/stellar)
aux_source_directory(${PROJECT_SOURCE_DIR}/deps/mempool PERF_TEST_DEP_SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml PERF_TEST_DEP_SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/src PERF_TEST_DEP_SRC)
add_executable(gtest_http http_decoder_gtest.cpp ${PROJECT_SOURCE_DIR}/decoders/http/http_decoder_utils.cpp)
target_link_libraries(gtest_http gtest stellar_devel)
add_executable(http_test_main plugin_test_main.cpp)
set_target_properties(http_test_main
PROPERTIES
LINK_OPTIONS
"-rdynamic"
)
set_target_properties(http_test_main
PROPERTIES
LINK_FLAGS
"-rdynamic"
)
set(LINK_FLAGS "-rdynamic")
target_link_libraries(http_test_main gtest cjson-static stellar_devel)
add_subdirectory(test_based_on_stellar)
include(GoogleTest)
gtest_discover_tests(gtest_http)

164
test/decoders/http/base64.c Normal file
View File

@@ -0,0 +1,164 @@
/* This is a public domain base64 implementation written by WEI Zhicheng. */
#include "base64.h"
#define BASE64_PAD '='
#define BASE64DE_FIRST '+'
#define BASE64DE_LAST 'z'
/* BASE 64 encode table */
static const char base64en[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
};
/* ASCII order for BASE 64 decode, 255 in unused character */
static const unsigned char base64de[] = {
/* nul, soh, stx, etx, eot, enq, ack, bel, */
255, 255, 255, 255, 255, 255, 255, 255,
/* bs, ht, nl, vt, np, cr, so, si, */
255, 255, 255, 255, 255, 255, 255, 255,
/* dle, dc1, dc2, dc3, dc4, nak, syn, etb, */
255, 255, 255, 255, 255, 255, 255, 255,
/* can, em, sub, esc, fs, gs, rs, us, */
255, 255, 255, 255, 255, 255, 255, 255,
/* sp, '!', '"', '#', '$', '%', '&', ''', */
255, 255, 255, 255, 255, 255, 255, 255,
/* '(', ')', '*', '+', ',', '-', '.', '/', */
255, 255, 255, 62, 255, 255, 255, 63,
/* '0', '1', '2', '3', '4', '5', '6', '7', */
52, 53, 54, 55, 56, 57, 58, 59,
/* '8', '9', ':', ';', '<', '=', '>', '?', */
60, 61, 255, 255, 255, 255, 255, 255,
/* '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', */
255, 0, 1, 2, 3, 4, 5, 6,
/* 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', */
7, 8, 9, 10, 11, 12, 13, 14,
/* 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', */
15, 16, 17, 18, 19, 20, 21, 22,
/* 'X', 'Y', 'Z', '[', '\', ']', '^', '_', */
23, 24, 25, 255, 255, 255, 255, 255,
/* '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', */
255, 26, 27, 28, 29, 30, 31, 32,
/* 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', */
33, 34, 35, 36, 37, 38, 39, 40,
/* 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', */
41, 42, 43, 44, 45, 46, 47, 48,
/* 'x', 'y', 'z', '{', '|', '}', '~', del, */
49, 50, 51, 255, 255, 255, 255, 255
};
unsigned int
base64_encode(const unsigned char *in, unsigned int inlen, char *out)
{
int s;
unsigned int i;
unsigned int j;
unsigned char c;
unsigned char l;
s = 0;
l = 0;
for (i = j = 0; i < inlen; i++) {
c = in[i];
switch (s) {
case 0:
s = 1;
out[j++] = base64en[(c >> 2) & 0x3F];
break;
case 1:
s = 2;
out[j++] = base64en[((l & 0x3) << 4) | ((c >> 4) & 0xF)];
break;
case 2:
s = 0;
out[j++] = base64en[((l & 0xF) << 2) | ((c >> 6) & 0x3)];
out[j++] = base64en[c & 0x3F];
break;
}
l = c;
}
switch (s) {
case 1:
out[j++] = base64en[(l & 0x3) << 4];
out[j++] = BASE64_PAD;
out[j++] = BASE64_PAD;
break;
case 2:
out[j++] = base64en[(l & 0xF) << 2];
out[j++] = BASE64_PAD;
break;
}
out[j] = 0;
return j;
}
unsigned int
base64_decode(const char *in, unsigned int inlen, unsigned char *out)
{
unsigned int i;
unsigned int j;
unsigned char c;
if (inlen & 0x3) {
return 0;
}
for (i = j = 0; i < inlen; i++) {
if (in[i] == BASE64_PAD) {
break;
}
if (in[i] < BASE64DE_FIRST || in[i] > BASE64DE_LAST) {
return 0;
}
c = base64de[(unsigned char)in[i]];
if (c == 255) {
return 0;
}
switch (i & 0x3) {
case 0:
out[j] = (c << 2) & 0xFF;
break;
case 1:
out[j++] |= (c >> 4) & 0x3;
out[j] = (c & 0xF) << 4;
break;
case 2:
out[j++] |= (c >> 2) & 0xF;
out[j] = (c & 0x3) << 6;
break;
case 3:
out[j++] |= c;
break;
}
}
return j;
}

View File

@@ -0,0 +1,28 @@
#ifndef BASE64_H
#define BASE64_H
#define BASE64_ENCODE_OUT_SIZE(s) ((unsigned int)((((s) + 2) / 3) * 4 + 1))
#define BASE64_DECODE_OUT_SIZE(s) ((unsigned int)(((s) / 4) * 3))
#ifdef __cplusplus
extern "C"
{
#endif
/*
* out is null-terminated encode string.
* return values is out length, exclusive terminating `\0'
*/
unsigned int
base64_encode(const unsigned char *in, unsigned int inlen, char *out);
/*
* return values is out length
*/
unsigned int
base64_decode(const char *in, unsigned int inlen, unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif /* BASE64_H */

View File

@@ -0,0 +1,64 @@
#include <gtest/gtest.h>
#include <unistd.h>
#include <stdio.h>
#include "http.h"
#include "http_decoder_private.h"
void httpd_url_decode(const char *string, size_t length, char *ostring, size_t *olen);
TEST(http_url_decoder, none)
{
char decode_url_buf[2048];
size_t decode_url_len = sizeof(decode_url_buf);
const char *encode_url = "https://docs.geedge.net/#all-updates";
httpd_url_decode(encode_url, strlen(encode_url), decode_url_buf, &decode_url_len);
EXPECT_STREQ("https://docs.geedge.net/#all-updates", decode_url_buf);
EXPECT_EQ(decode_url_len, strlen("https://docs.geedge.net/#all-updates"));
}
TEST(http_url_decoder, simple)
{
char decode_url_buf[2048];
size_t decode_url_len = sizeof(decode_url_buf);
const char *encode_url = "http://a.b.cn/%A1%B2%C3%D4";
httpd_url_decode(encode_url, strlen(encode_url), decode_url_buf, &decode_url_len);
const unsigned char expect_result[] =
{0x68, 0x74, 0x74, 0x70,
0x3A, 0x2F, 0x2F, 0x61,
0x2E, 0x62, 0x2E, 0x63,
0x6E, 0x2F, 0xA1, 0xB2,
0xC3, 0xD4, 0x00
};
EXPECT_STREQ((char *)expect_result, decode_url_buf);
EXPECT_EQ(decode_url_len, sizeof(expect_result)-1);
}
TEST(http_url_decoder, chinese1)
{
char decode_url_buf[2048];
size_t decode_url_len = sizeof(decode_url_buf);
const char *encode_url = "http://www.baidu.com/%E6%B5%8B%E8%AF%95%E4%B8%AD%E6%96%87%E8%A7%A3%E7%A0%81";
httpd_url_decode(encode_url, strlen(encode_url), decode_url_buf, &decode_url_len);
EXPECT_STREQ("http://www.baidu.com/\xE6\xB5\x8B\xE8\xAF\x95\xE4\xB8\xAD\xE6\x96\x87\xE8\xA7\xA3\xE7\xA0\x81", decode_url_buf);
EXPECT_EQ(decode_url_len, strlen("http://www.baidu.com/\xE6\xB5\x8B\xE8\xAF\x95\xE4\xB8\xAD\xE6\x96\x87\xE8\xA7\xA3\xE7\xA0\x81"));
}
TEST(http_url_decoder, chinese2)
{
char decode_url_buf[2048];
size_t decode_url_len = sizeof(decode_url_buf);
const char *encode_url = "http%3A%2F%2Fwww.baidu.com%2F%E7%BC%96%E8%A7%A3%E7%A0%81%E6%B5%8B%E8%AF%95%E5%93%88%E5%93%88";
httpd_url_decode(encode_url, strlen(encode_url), decode_url_buf, &decode_url_len);
EXPECT_STREQ("http://www.baidu.com/\xE7\xBC\x96\xE8\xA7\xA3\xE7\xA0\x81\xE6\xB5\x8B\xE8\xAF\x95\xE5\x93\x88\xE5\x93\x88", decode_url_buf);
EXPECT_EQ(decode_url_len, strlen("http://www.baidu.com/\xE7\xBC\x96\xE8\xA7\xA3\xE7\xA0\x81\xE6\xB5\x8B\xE8\xAF\x95\xE5\x93\x88\xE5\x93\x88"));
}
int main(int argc, char const *argv[])
{
::testing::InitGoogleTest(&argc, (char **)argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,68 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <stellar/session.h>
#include <stellar/stellar_mq.h>
#include <stellar/stellar_exdata.h>
#include <stellar/stellar.h>
#ifdef __cplusplus
}
#endif
#include "http.h"
#include "md5.h"
#include <stdint.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <pcap/pcap.h>
#include "cJSON.h"
#define TRUE 1
#define FLASE 0
#define JSON_KEY_VALUE_STRING_MAX_LEN (4096)
#ifndef MAX
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b) ((a) >= (b) ? (b) : (a))
#endif
#define MMALLOC(type, size) ((type *)calloc(1, size))
#define MFREE(p) \
do \
{ \
free(p); \
p = NULL; \
} while (0)
#if 0
#define DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINT(fmt, ...)
#endif
#define EX_DATA_MAX_SIZE 10
#define PIPELINE_MAX_NUM 8
#define GTEST_FIX_PAYLOAD_CSTR "<Hello http decoder World!!!>"
#define GTEST_FIX_PAYLOAD_MD5 "e91e072f772737c7a45013cc3b1a916c"
#define GTEST_HTTP_URL_NAME "__X_HTTP_URL"
#define GTEST_HTTP_TRANS_NAME "__X_HTTP_TRANSACTION"
#define GTEST_HTTP_TRANS_SEQ_NAME "__X_HTTP_TRANSACTION_SEQ"
#define GTEST_HTTP_TUPLE4_NAME "__X_HTTP_TUPLE4"
#define GTEST_HTTP_PAYLOAD_NAME "__X_HTTP_PAYLOAD"
#define GTEST_HTTP_RAW_PAYLOAD_MD5_NAME "__X_HTTP_RAW_PAYLOAD_MD5"
#define GTEST_HTTP_DECOMPRESS_PAYLOAD_MD5_NAME "__X_HTTP_DECOMPRESS_PAYLOAD_MD5"
struct stellar *stellar_init(void);
void stellar_destroy(struct stellar *st);
int stellar_load_plugin(struct stellar *st, void *(plugin_init_cb)(struct stellar *st));
struct session *stellar_session_new(struct stellar *st, int topic_id, const char *payload, size_t payload_len, u_int8_t dir);
void stellar_session_active(struct stellar *st, struct session *sess, int topic_id, const char *payload, size_t payload_len, u_int8_t dir);
void stellar_session_close(struct stellar *st, struct session *sess, int topic_id);

View File

@@ -0,0 +1,226 @@
#ifdef __cplusplus
extern "C"
{
#endif
#include <stellar/session.h>
#include <stellar/stellar_mq.h>
#include <stellar/stellar_exdata.h>
#include <stellar/stellar.h>
#ifdef __cplusplus
}
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <fieldstat/fieldstat_easy.h>
#include "http_decoder_gtest.h"
#define TIME_MEASURE 1
#if TIME_MEASURE
#define TIME_START() struct timespec _start_time, _end_time; long long time_diff_ns; clock_gettime(CLOCK_REALTIME, &_start_time)
#define TIME_UPDATE() clock_gettime(CLOCK_REALTIME, &_start_time)
#define TIME_DIFF() \
do { \
clock_gettime(CLOCK_REALTIME, &_end_time); \
if (_end_time.tv_sec == _start_time.tv_sec)\
{\
time_diff_ns = (_end_time.tv_nsec - _start_time.tv_nsec);\
}else{\
time_diff_ns = (_end_time.tv_sec * 1000 * 1000 * 1000 + _end_time.tv_nsec) - (_start_time.tv_sec * 1000 * 1000 * 1000 + _start_time.tv_nsec);\
}\
}while (0)
#else
#define TIME_START()
#define TIME_DIFF()
#endif
struct test_packet{
const char *payload;
size_t payload_len;
u_int8_t dir;
};
extern "C" void *http_decoder_perf_plug_init(struct stellar *st);
extern "C" void *http_decoder_init(struct stellar *st);
extern "C" void http_decoder_exit(void *plugin_env);
extern "C" void *httpd_session_ctx_new_cb(struct session *sess, void *plugin_env);
extern "C" void _httpd_ex_data_free_cb(struct session *s, int idx,void *ex_data, void *arg);
extern "C" void http_decoder_tcp_stream_msg_cb(struct session *sess, int topic_id, const void *msg, void *no_use_ctx, void *plugin_env);
extern "C" void http_decoder_perf_entry(struct session *sess, int topic_id, const void *raw_msg, void *per_session_ctx, void *plugin_env);
static struct fieldstat_easy *fs4_instance;
static int fs4_simple_id;
static int fs4_long_long_url_id;
static int fs4_frag_id;
static void perf_test_loop(struct stellar *st, int tcp_stream_topic_id, struct test_packet *test_payload, int test_payload_index_max, int fs4_metric_id)
{
int idx = 0;
struct session *sess;
TIME_START();
sess = stellar_session_new(st, tcp_stream_topic_id, test_payload[idx].payload, test_payload[idx].payload_len, test_payload[idx].dir);
idx++;
TIME_DIFF();
fieldstat_easy_histogram_record(fs4_instance, 0, fs4_metric_id, NULL, 0, time_diff_ns);
for(; idx < test_payload_index_max; idx++){
TIME_UPDATE();
stellar_session_active(st, sess, tcp_stream_topic_id, test_payload[idx].payload, test_payload[idx].payload_len, test_payload[idx].dir);
TIME_DIFF();
fieldstat_easy_histogram_record(fs4_instance, 0, fs4_metric_id, NULL, 0, time_diff_ns);
}
TIME_UPDATE();
stellar_session_close(st, sess, tcp_stream_topic_id);
TIME_DIFF();
fieldstat_easy_histogram_record(fs4_instance, 0, fs4_metric_id, NULL, 0, time_diff_ns);
}
#define SET_DATA_LENGTH_DIR(pkt_payload, cstr_in_heap, cur_dir, tmp_index) \
pkt_payload.payload = cstr_in_heap; \
pkt_payload.payload_len = strlen(pkt_payload.payload); \
pkt_payload.dir = cur_dir;\
tmp_index++;
static void init_test_data_simple(struct test_packet *test_payload, int *index)
{
int tmp_index = 0;
const char *c2s_payload = strdup("GET / HTTP/1.1\r\nHost: www.simple.com\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n");
SET_DATA_LENGTH_DIR(test_payload[tmp_index], c2s_payload, FLOW_DIRECTION_C2S , tmp_index);
const char *content = "Hello, http decoder perf test simple!!!";
int content_length = strlen(content);
char *s2c_payload = (char *)malloc(1024);
snprintf(s2c_payload, 1024, "HTTP/1.1 200 OK\r\nServer: Apache-Coyote/1.1\r\nConnection: keep-alive\r\nDate: Sat, 01 May 2024 01:36:57 GMT\r\nContent-Type: text/html;charset=UTF-8\r\nContent-Length: %d\r\n\r\n%s", content_length, content);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], s2c_payload, FLOW_DIRECTION_S2C, tmp_index);
*index = tmp_index;
}
static void init_test_data_frag(struct test_packet *test_payload, int *index)
{
int tmp_index = 0;
/* c2s */
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("GET / HTTP/1.1\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Host: www.fragment.com\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Cache-Control: max-age=0\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Connection: keep-alive\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Referer: http://fragment.com/register.jsp?redirect:http://aa.bb.cc.dd.com/?\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Cookie: JSESSIONID=385C79E211D561C0CA13D90F150F603D34875GH87FSHG8S7RTHG74875GHS8R7THG87SRTH\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Accept: */*\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Accept-Encoding: gzip, deflate\r\n"), FLOW_DIRECTION_C2S , tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("\r\n"), FLOW_DIRECTION_C2S , tmp_index); //header EOF
/* s2c */
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("HTTP/1.1 200 OK\r\n"), FLOW_DIRECTION_S2C, tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Server: Apache-Coyote/1.1\r\n"), FLOW_DIRECTION_S2C, tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Connection: keep-alive\r\n"), FLOW_DIRECTION_S2C, tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Content-Type: text/html;charset=UTF-8\r\n"), FLOW_DIRECTION_S2C, tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("Date: Sat, 01 May 2024 01:36:57 GMT\r\n"), FLOW_DIRECTION_S2C, tmp_index);
char *cont_len_buf = (char *)malloc(1024);
const char *s2c_payload = strdup("Hello, http decoder perf test fragment!!!");
int content_length = strlen(s2c_payload);
snprintf(cont_len_buf, 1024, "Content-Length: %d\r\n", content_length);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], cont_len_buf, FLOW_DIRECTION_S2C, tmp_index);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], strdup("\r\n"), FLOW_DIRECTION_S2C, tmp_index); //header EOF
SET_DATA_LENGTH_DIR(test_payload[tmp_index], s2c_payload, FLOW_DIRECTION_S2C, tmp_index);
*index = tmp_index;
}
static void init_test_data_long_long_url(struct test_packet *test_payload, int *index)
{
int tmp_index = 0;
const char *request_line_frag1 = strdup("GET /long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/");
SET_DATA_LENGTH_DIR(test_payload[tmp_index], request_line_frag1, FLOW_DIRECTION_C2S , tmp_index);
const char *request_line_frag2 = strdup("long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/\
/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long.index.html HTTP/1.1\r\n");
SET_DATA_LENGTH_DIR(test_payload[tmp_index], request_line_frag2, FLOW_DIRECTION_C2S , tmp_index);
const char *request_line_frag3 = strdup("Host: www.long-long-url.com\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n");
SET_DATA_LENGTH_DIR(test_payload[tmp_index], request_line_frag3, FLOW_DIRECTION_C2S , tmp_index);
const char *content = "Hello, http decoder perf test long long url!!!";
int content_length = strlen(content);
char *s2c_payload = (char *)malloc(1024);
snprintf(s2c_payload, 1024, "HTTP/1.1 200 OK\r\nServer: Apache-Coyote/1.1\r\nConnection: keep-alive\r\nDate: Sat, 01 May 2024 01:36:57 GMT\r\nContent-Type: text/html;charset=UTF-8\r\nContent-Length: %d\r\n\r\n%s", content_length, content);
SET_DATA_LENGTH_DIR(test_payload[tmp_index], s2c_payload, FLOW_DIRECTION_S2C, tmp_index);
*index = tmp_index;
}
static void test_payload_free(struct test_packet *test_payload, int test_payload_index_max)
{
for(int i = 0; i < test_payload_index_max; i++){
if(test_payload[i].payload){
free((void *)test_payload[i].payload);
}
}
}
static void perf_stat_init(void)
{
fs4_instance = fieldstat_easy_new(1, "http_decoder_test", NULL, 0);
fieldstat_easy_enable_auto_output(fs4_instance, "./httpd_hisgram.json", 1);
fs4_simple_id = fieldstat_easy_register_histogram(fs4_instance, "simple", 1, 99999999, 5);
fs4_frag_id = fieldstat_easy_register_histogram(fs4_instance, "frag", 1, 99999999, 5);
fs4_long_long_url_id = fieldstat_easy_register_histogram(fs4_instance, "long-url", 1, 99999999, 5);
}
int main(int argc, char const *argv[])
{
struct test_packet test_payload_simple [4] = {};
int payload_index_simple = 0;
struct test_packet test_payload_long_long_url [8] = {};
int payload_index_long_long_url = 0;
struct test_packet test_payload_frag [32] = {};
int payload_index_frag = 0;
struct stellar *st = stellar_init();
int tcp_stream_topic_id = stellar_mq_get_topic_id(st, TOPIC_TCP_STREAM);
if(stellar_load_plugin(st, http_decoder_init) < 0){
fprintf(stderr, "load plugin 'http_decoder_init' failed\n");
return -1;
}
if(stellar_load_plugin(st, http_decoder_perf_plug_init) < 0){
fprintf(stderr, "load plugin 'http_decoder_perf_plug_init' failed\n");
return -1;
}
perf_stat_init();
init_test_data_simple(test_payload_simple, &payload_index_simple);
init_test_data_long_long_url(test_payload_long_long_url, &payload_index_long_long_url);
init_test_data_frag(test_payload_frag, &payload_index_frag);
// while(1){
for(int i = 0; i < 1000; i++){
perf_test_loop(st, tcp_stream_topic_id,test_payload_simple, payload_index_simple, fs4_simple_id);
perf_test_loop(st, tcp_stream_topic_id,test_payload_long_long_url, payload_index_long_long_url, fs4_long_long_url_id);
perf_test_loop(st, tcp_stream_topic_id,test_payload_frag, payload_index_frag, fs4_frag_id);
}
test_payload_free(test_payload_simple, sizeof(test_payload_simple)/sizeof(struct test_packet)) ;
test_payload_free(test_payload_long_long_url, sizeof(test_payload_long_long_url)/sizeof(struct test_packet)) ;
test_payload_free(test_payload_frag, sizeof(test_payload_frag)/sizeof(struct test_packet)) ;
stellar_destroy(st);
sleep(1);
fieldstat_easy_free(fs4_instance);
return 0;
}

View File

@@ -0,0 +1,143 @@
#include "http.h"
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#ifdef __cplusplus
extern "C"
{
#include "http_decoder_private.h"
#include "cJSON.h"
}
#endif
#define MAX_KEY_STR_LEN 2048
static int g_result_count = 0;
static int g_header_count = 1;
static int g_exdata_idx = -1;
static int g_topic_id = -1;
static int g_plugin_id = -1;
#define DEBUG_PRINT(fmt, ...) //printf(fmt, ##__VA_ARGS__)
extern "C" void http_decoder_perf_entry(struct session *sess, int topic_id, const void *raw_msg, void *per_session_ctx, void *plugin_env)
{
struct http_request_line req_line = {0};
struct http_response_line res_line = {0};
struct http_header header = {0};
hstring url = {};
hstring body = {};
struct http_message *msg = (struct http_message *)raw_msg;
enum http_message_type msg_type = http_message_type_get(msg);
void *ret1, *ret2;
switch (msg_type)
{
case HTTP_MESSAGE_REQ_LINE:
DEBUG_PRINT("---------------------------------------------------------------\n");
http_message_request_line_get0(msg, &req_line);
if (req_line.uri.iov_base)
{
DEBUG_PRINT("req_line.method.iov_base: %.*s\n", req_line.method.iov_len, req_line.method.iov_base);
ret1 = memmem(req_line.method.iov_base, req_line.method.iov_len, "PUT", 3);
DEBUG_PRINT("req_line.version.iov_base: %.*s\n", req_line.version.iov_len, req_line.version.iov_base);
}
break;
case HTTP_MESSAGE_REQ_HEADER:
while (http_message_header_next(msg, &header) >= 0)
{
ret1 = memmem(header.key.iov_base, header.key.iov_len, "key", 3);
ret2 = memmem(header.val.iov_base, header.val.iov_len, "val", 3);
DEBUG_PRINT("REQ header: %.*s : %.*s\n", (int)header.key.iov_len, header.key.iov_base, (int)header.val.iov_len, header.val.iov_base);
}
http_message_raw_url_get0(msg, &url);
if(url.iov_base && url.iov_len){
DEBUG_PRINT("URL: %.*s\n", url.iov_len, url.iov_base);
}
break;
case HTTP_MESSAGE_REQ_BODY:
// http_message_get_request_raw_body(msg, &body);
// output_http_body(&body, 0);
http_message_decompress_body_get0(msg, &body);
// output_http_body(&body, 1);
ret1 = memmem(body.iov_base, body.iov_len, "</html>", 7);
break;
case HTTP_MESSAGE_RES_LINE:
http_message_response_line_get0(msg, &res_line);
ret1 = memmem(res_line.status.iov_base, res_line.status.iov_len, "OK", 2);
DEBUG_PRINT("res_line.status.iov_base: %.*s\n", (int)res_line.status.iov_len, res_line.status.iov_base);
break;
case HTTP_MESSAGE_RES_HEADER:
while (http_message_header_next(msg, &header) >= 0)
{
ret1 = memmem(header.key.iov_base, header.key.iov_len, "key", 3);
ret2 = memmem(header.val.iov_base, header.val.iov_len, "val", 3);
DEBUG_PRINT("RES header: %.*s : %.*s\n", (int)header.key.iov_len, header.key.iov_base, (int)header.val.iov_len, header.val.iov_base);
}
break;
case HTTP_MESSAGE_RES_BODY_START:
case HTTP_MESSAGE_RES_BODY:
case HTTP_MESSAGE_RES_BODY_END:
http_message_raw_body_get0(msg, &body);
if(body.iov_base!=NULL && body.iov_len > 0){
DEBUG_PRINT("res raw body: %.*s\n", body.iov_len, body.iov_base);
}
// output_http_body(&body, 0);
http_message_decompress_body_get0(msg, &body);
if(body.iov_base!=NULL && body.iov_len > 0){
// output_http_body(&body, 1);
ret1 = memmem(body.iov_base, body.iov_len, "</html>", 7);
DEBUG_PRINT("res unzip body: %.*s\n", body.iov_len, body.iov_base);
DEBUG_PRINT("---------------------------------------------------------------\n");
}
break;
// to do: check payload
default:
break;
}
return;
}
static on_session_msg_cb_func*g_entry_fun = &http_decoder_perf_entry;
static void http_decoder_test_exdata_free(int idx, void *ex_ptr, void *arg)
{
return;
}
extern "C" void *http_decoder_perf_plug_init(struct stellar *st)
{
g_plugin_id = stellar_session_plugin_register(st, NULL, NULL, NULL);
g_exdata_idx = stellar_exdata_new_index(st, "HTTP_DECODER_REQ_TEST",
http_decoder_test_exdata_free,
NULL);
if (g_exdata_idx < 0)
{
printf("[%s:%d]: can't get http_decoder exdata index !!!\n", __FUNCTION__, __LINE__);
exit(-1);
}
g_topic_id = stellar_mq_get_topic_id(st, "HTTP_DECODER_MESSAGE");
if (g_topic_id < 0)
{
printf("[%s:%d]: can't get http_decoder topic id !!!\n", __FUNCTION__, __LINE__);
exit(-1);
}
stellar_session_mq_subscribe(st, g_topic_id, g_entry_fun, g_plugin_id);
// printf("http_decoder_test_init OK!\n");
return NULL;
}
extern "C" void http_decoder_perf_plug_exit(void *test_ctx)
{
if (test_ctx != NULL)
{
FREE(test_ctx);
}
printf("http_decoder_perf plug exit OK!\n");
}

View File

@@ -0,0 +1,675 @@
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include "http.h"
#include "http_decoder_private.h"
#ifdef __cplusplus
extern "C"
{
#include "cJSON.h"
#include "http_decoder_gtest.h"
#include "md5.h"
#include "toml/toml.h"
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
#define MAX_KEY_STR_LEN 2048
#define GTEST_PLUG_ENTRY_CFG "./etc/http/gtest_entry.toml"
struct plug_entry_t
{
const char *name;
on_session_msg_cb_func *entry;
};
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}};
enum http_transaction_type
{
HTTP_TRANSACTION_REQ = 0,
HTTP_TRANSACTION_RES,
HTTP_TRANSACTION_SESSION, // global session info
HTTP_TRANSACTION_MAX
};
enum payload_compress_mode
{
PAYLOAD_RAW = 0,
PAYLOAD_DECOMPRESS = 1,
PAYLOAD_MAX = 2,
};
struct gtest_plug_exdata_t
{
cJSON *result_jnode[HTTP_TRANSACTION_MAX];
MD5_CTX *payload_md5ctx[PAYLOAD_MAX][HTTP_TRANSACTION_MAX];
};
static int g_result_count = 0;
static int g_header_count = 1;
static int g_http_gtest_plugin_id = -1;
static int g_exdata_idx = -1;
static int g_topic_id = -1;
#if 0
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.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.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.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.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.iov_base, res_line->status.iov_len);
printf("res_status:%s\n", tmp_str);
}
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.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(hstring *body, int decompress_flag)
{
int counter = 0;
if (1 == decompress_flag)
{
printf("\n\n----------------decompress body len:%zu---------------\n",
body->iov_len);
}
else
{
printf("\n\n----------------raw body len:%zu---------------\n",
body->iov_len);
}
for (size_t i = 0; i < body->iov_len; i++)
{
if (counter % 16 == 0)
{
printf("\n");
}
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, enum payload_compress_mode mode,
const hstring *body, enum http_transaction_type type)
{
(void)sess;
if (NULL == body->iov_base || 0 == body->iov_len)
{
return;
}
if (NULL == gtest_plug_exdata->payload_md5ctx[mode][type])
{
gtest_plug_exdata->payload_md5ctx[mode][type] = MMALLOC(MD5_CTX, sizeof(MD5_CTX));
MD5Init(gtest_plug_exdata->payload_md5ctx[mode][type]);
}
MD5Update(gtest_plug_exdata->payload_md5ctx[mode][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)
{
if (NULL == object || NULL == key || NULL == val || 0 == val_len)
{
return -1;
}
char *tmp = CALLOC(char, val_len + 1);
memcpy(tmp, val, val_len);
cJSON_AddStringToObject(object, key, tmp);
FREE(tmp);
return 0;
}
void transaction_index_to_json(cJSON *ctx, int transaction_index)
{
cJSON_AddNumberToObject(ctx, GTEST_HTTP_TRANS_SEQ_NAME, transaction_index);
}
void req_line_to_json(cJSON *ctx, struct http_request_line *req_line)
{
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);
}
void res_line_to_json(cJSON *ctx, struct http_response_line *res_line)
{
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);
cJSON_AddNumberToObject(ctx, "status_code", res_line->status_code);
}
void http_header_to_json(cJSON *ctx, struct http_header *header)
{
char key[MAX_KEY_STR_LEN] = {0};
if ((header->key.iov_base == NULL) || (header->val.iov_base == NULL))
{
return;
}
memcpy(key, header->key.iov_base, header->key.iov_len);
if (cJSON_HasObjectItem(ctx, key) == FALSE)
{
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[header->val.iov_len + 64] = {0};
snprintf(new_key,sizeof(new_key), "%s%d", key, g_header_count++);
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)
{
hstring raw_url_result = {};
if (cJSON_GetObjectItem(ctx, GTEST_HTTP_URL_NAME))
{
return;
}
http_message_raw_url_get0(msg, &raw_url_result);
if (raw_url_result.iov_base == NULL)
{
return;
}
struct http_header raw_url_header_result = {};
raw_url_header_result.key.iov_base = (char *)GTEST_HTTP_URL_NAME;
raw_url_header_result.key.iov_len = strlen(GTEST_HTTP_URL_NAME);
raw_url_header_result.val = raw_url_result;
http_header_to_json(ctx, &raw_url_header_result);
hstring decode_url_result = {};
struct http_header decode_url_header_result = {};
http_message_decoded_url_get0(msg, &decode_url_result);
if (decode_url_result.iov_len != raw_url_result.iov_len)
{
decode_url_header_result.key.iov_base = (char *)"__X_HTTP_DECODED_URL";
decode_url_header_result.key.iov_len = strlen("__X_HTTP_DECODED_URL");
decode_url_header_result.val = decode_url_result;
http_header_to_json(ctx, &decode_url_header_result);
}
}
static void commit_payload_md5sum(cJSON *last_jnode, struct gtest_plug_exdata_t *gtest_plug_exdata, enum http_transaction_type type)
{
// finish md5 streming hash
for (int mode = 0; mode < PAYLOAD_MAX; mode++)
{
if (gtest_plug_exdata->payload_md5ctx[mode][type])
{
unsigned char md5_result_bin[16] = {0};
unsigned char md5_result_cstr[33] = {0};
MD5Final(md5_result_bin, gtest_plug_exdata->payload_md5ctx[mode][type]);
for (int i = 0; i < 16; i++)
sprintf((char *)md5_result_cstr + 2 * i, "%02x", md5_result_bin[i]);
md5_result_cstr[32] = '\0';
if (mode == PAYLOAD_RAW)
{
cJSON_AddStringToObject(last_jnode, GTEST_HTTP_RAW_PAYLOAD_MD5_NAME, (char *)md5_result_cstr);
}
else
{
cJSON_AddStringToObject(last_jnode, GTEST_HTTP_DECOMPRESS_PAYLOAD_MD5_NAME, (char *)md5_result_cstr);
}
FREE(gtest_plug_exdata->payload_md5ctx[mode][type]);
gtest_plug_exdata->payload_md5ctx[mode][type] = NULL;
}
}
}
// Full duplex
static void commit_last_half_flow_data(struct gtest_plug_exdata_t *gtest_plug_exdata,
struct http_message *msg, enum http_transaction_type type, int final)
{
char result_name[MAX_KEY_STR_LEN] = {0};
cJSON *last_jnode = gtest_plug_exdata->result_jnode[type];
if (last_jnode)
{
commit_payload_md5sum(last_jnode, gtest_plug_exdata, type);
sprintf(result_name, "%d", g_result_count);
commit_test_result_json(last_jnode, result_name);
gtest_plug_exdata->result_jnode[type] = NULL;
g_result_count++;
}
if (0 == final)
{
gtest_plug_exdata->result_jnode[type] = cJSON_CreateObject();
if (HTTP_TRANSACTION_REQ == type)
{
cJSON_AddStringToObject(gtest_plug_exdata->result_jnode[type], GTEST_HTTP_TRANS_NAME, "request");
}
else if (HTTP_TRANSACTION_RES == type)
{
cJSON_AddStringToObject(gtest_plug_exdata->result_jnode[type], GTEST_HTTP_TRANS_NAME, "response");
}
if (msg)
{
transaction_index_to_json(gtest_plug_exdata->result_jnode[type], http_message_get_transaction_seq(msg));
}
}
}
static void http_decoder_test_update_session_tuple4(struct session *sess, struct gtest_plug_exdata_t *gtest_plug_exdata)
{
if (gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION] == NULL)
{
const char *human_addr_cstr = session_get0_readable_addr(sess);
if (NULL == human_addr_cstr)
{
fprintf(stderr, "can't get readable_addr, to use session_get0_readable_addr() the sapp_log.conf level must <= INFO\n");
return;
}
char result_name[MAX_KEY_STR_LEN] = {0};
gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION] = cJSON_CreateObject();
cJSON_AddStringToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION], GTEST_HTTP_TUPLE4_NAME, human_addr_cstr);
sprintf(result_name, "%d", g_result_count++);
commit_test_result_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION], result_name);
}
}
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)
{
fprintf(stderr, "[%s:%d]Can't open config file:%s",
__FUNCTION__, __LINE__, cfg_path);
return -1;
}
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, "entry");
if (NULL == basic_sec_tbl)
{
fprintf(stderr, "[%s:%d]config file:%s has no key: [entry]",
__FUNCTION__, __LINE__, cfg_path);
toml_free(root);
return -1;
}
toml_datum_t str_val = toml_string_in(basic_sec_tbl, "name");
if (str_val.ok != 0)
{
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;
}
static void set_gtest_plug_entry(const char *entry_name)
{
if (NULL == entry_name)
{
g_entry_fun = http_decoder_test_entry; // set default
return;
}
for (size_t i = 0; g_entry_tbl[i].name != NULL; i++)
{
if (strcmp(entry_name, g_entry_tbl[i].name) == 0)
{
g_entry_fun = g_entry_tbl[i].entry;
return;
}
}
g_entry_fun = http_decoder_test_entry; // set default
}
extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env)
{
(void)topic_id;
(void)no_use_ctx;
(void)plugin_env;
struct http_request_line req_line = {};
struct http_response_line res_line = {};
struct http_header header = {};
hstring body = {};
struct http_message *msg = (struct http_message *)raw_msg;
enum http_message_type msg_type = http_message_type_get(msg);
struct gtest_plug_exdata_t *gtest_plug_exdata = (struct gtest_plug_exdata_t *)session_exdata_get(sess, g_exdata_idx);
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);
}
// if (http_message_type_is_req(sess, msg_type))
// {
// cJSON *json = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ];
// }
// else
// {
// cJSON *json = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES];
// }
http_decoder_test_update_session_tuple4(sess, gtest_plug_exdata);
switch (msg_type)
{
case HTTP_MESSAGE_REQ_LINE:
commit_last_half_flow_data(gtest_plug_exdata, msg, HTTP_TRANSACTION_REQ, 0);
http_message_request_line_get0(msg, &req_line);
req_line_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], &req_line);
break;
case HTTP_MESSAGE_REQ_HEADER:
while (http_message_header_next(msg, &header) >= 0)
{
http_header_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], &header);
}
g_header_count = 1;
break;
case HTTP_MESSAGE_REQ_HEADER_END:
http_url_add_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], msg);
break;
case HTTP_MESSAGE_REQ_BODY_START:
case HTTP_MESSAGE_REQ_BODY:
memset(&body, 0, sizeof(hstring));
http_message_raw_body_get0(msg, &body);
if (body.iov_base && body.iov_len)
{
append_http_payload(sess, gtest_plug_exdata, PAYLOAD_RAW, &body, HTTP_TRANSACTION_REQ);
}
// output_http_body(&body, 0);
http_message_decompress_body_get0(msg, &body);
// output_http_body(&body, 1);
if (body.iov_base && body.iov_len)
{
append_http_payload(sess, gtest_plug_exdata, PAYLOAD_DECOMPRESS, &body, HTTP_TRANSACTION_REQ);
}
break;
case HTTP_MESSAGE_RES_LINE:
commit_last_half_flow_data(gtest_plug_exdata, msg, HTTP_TRANSACTION_RES, 0);
http_message_response_line_get0(msg, &res_line);
res_line_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], &res_line);
break;
case HTTP_MESSAGE_RES_HEADER:
while (http_message_header_next(msg, &header) >= 0)
{
http_header_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], &header);
}
g_header_count = 1;
break;
case HTTP_MESSAGE_RES_BODY_START:
case HTTP_MESSAGE_RES_BODY:
memset(&body, 0, sizeof(hstring));
http_message_raw_body_get0(msg, &body);
if (body.iov_base && body.iov_len)
{
append_http_payload(sess, gtest_plug_exdata, PAYLOAD_RAW, &body, HTTP_TRANSACTION_RES);
}
// output_http_body(&body, 0);
memset(&body, 0, sizeof(hstring));
http_message_decompress_body_get0(msg, &body);
// output_http_body(&body, 1);
if (body.iov_base && body.iov_len)
{
append_http_payload(sess, gtest_plug_exdata, PAYLOAD_DECOMPRESS, &body, HTTP_TRANSACTION_RES);
}
break;
// to do: check payload
default:
break;
}
return;
}
void http_decoder_test_exdata_free(int idx, void *ex_ptr, void *arg)
{
(void)idx;
(void)arg;
if (ex_ptr != NULL)
{
struct gtest_plug_exdata_t *gtest_plug_exdata = (struct gtest_plug_exdata_t *)ex_ptr;
if (gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ])
{
commit_last_half_flow_data(gtest_plug_exdata, NULL, HTTP_TRANSACTION_REQ, 1);
}
if (gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES])
{
commit_last_half_flow_data(gtest_plug_exdata, NULL, HTTP_TRANSACTION_RES, 1);
}
free(ex_ptr);
}
}
// static int update_config_file(const char *filename, const char *key, const char *value)
// {
// char cmd_buf[1024] = {};
// snprintf(cmd_buf, 1024, "sed 's/^[ \t]*%s=.*/%s=%s/g' -i %s", key, key, value, filename);
// int ret = system(cmd_buf);
// return ret;
// }
extern "C" void http_decoder_test_state_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env)
{
(void)topic_id;
(void)no_use_ctx;
(void)plugin_env;
static int msg_index = 0;
char msg_index_name[64] = {};
char msg_index_value[64] = {};
cJSON *json_object = NULL;
enum http_message_type msg_type = http_message_type_get((struct http_message *)raw_msg);
struct gtest_plug_exdata_t *gtest_plug_exdata = (struct gtest_plug_exdata_t *)session_exdata_get(sess, g_exdata_idx);
if (NULL == gtest_plug_exdata)
{
gtest_plug_exdata = (struct gtest_plug_exdata_t *)calloc(1, sizeof(struct gtest_plug_exdata_t));
gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ] = cJSON_CreateObject();
gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES] = cJSON_CreateObject();
session_exdata_set(sess, g_exdata_idx, gtest_plug_exdata);
}
if (http_message_type_is_req(sess, msg_type))
{
json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ];
}
else
{
json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES];
}
if (HTTP_TRANSACTION_END == msg_type)
{
unsigned char flow_flag;
session_is_symmetric(sess, &flow_flag);
if (SESSION_SEEN_C2S_FLOW == flow_flag)
{
json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ];
}
else if (SESSION_SEEN_S2C_FLOW == flow_flag)
{
json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES];
}
else
{ // is symmetric
json_object = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES];
}
}
int cur_transaction_id = http_message_get_transaction_seq((const http_message *)raw_msg);
if (HTTP_TRANSACTION_START == msg_type || HTTP_TRANSACTION_END == msg_type)
{
snprintf(msg_index_name, sizeof(msg_index_name), "msg_%d", msg_index++);
snprintf(msg_index_value, sizeof(msg_index_value), "%s_transaction_%d", http_message_type_to_string(msg_type), cur_transaction_id);
cJSON_AddStringToObject(json_object, msg_index_name, msg_index_value);
}
else
{
snprintf(msg_index_name, sizeof(msg_index_name), "msg_%d", msg_index++);
cJSON_AddStringToObject(json_object, msg_index_name, http_message_type_to_string(msg_type));
}
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)
{
(void)topic_id;
(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");
}
break;
case HTTP_TUNNEL_ACTIVE:
{
enum flow_direction curdir = session_get_current_flow_direction(sess);
hstring tunnel_payload = {};
http_tunnel_message_get_payload((const struct http_tunnel_message *)raw_msg, &tunnel_payload);
if (FLOW_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_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;
}
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_mq_get_topic_id(st, topic_name);
if (g_topic_id < 0)
{
printf("[%s:%d]: can't get http_decoder topic:%s id !!!\n", __FUNCTION__, __LINE__, topic_name);
return NULL;
}
stellar_session_mq_subscribe(st, g_topic_id, g_entry_fun, g_http_gtest_plugin_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");
}
extern "C" void http_decoder_test_exit(void *test_ctx)
{
if (test_ctx != NULL)
{
FREE(test_ctx);
}
printf("http_decoder_test_exit OK!\n");
}

356
test/decoders/http/md5.c Normal file
View File

@@ -0,0 +1,356 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software. */
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include "md5.h"
/* Constants for MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform PROTO_LIST((UINT4[4], unsigned char[64]));
static void Encode PROTO_LIST((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST((UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST((POINTER, POINTER, unsigned int));
static void MD5_memset PROTO_LIST((POINTER, int, unsigned int));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/* F, G, H and I are basic MD5 functions. */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation. */
#define FF(a, b, c, d, x, s, ac) \
{ \
(a) += F((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) \
{ \
(a) += G((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) \
{ \
(a) += H((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) \
{ \
(a) += I((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
void MD5Init(MD5_CTX *context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context. */
void MD5Update(
MD5_CTX *context, /* context */
unsigned char *input, /* input block */
unsigned int inputLen) /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.*/
if (inputLen >= partLen)
{
MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform(context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform(context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen - i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context. */
void MD5Final(
unsigned char digest[16], /* message digest */
MD5_CTX *context) /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode(bits, context->count, 8);
/* Pad out to 56 mod 64.*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update(context, PADDING, padLen);
/* Append length (before padding) */
MD5Update(context, bits, 8);
/* Store state in digest */
Encode(digest, context->state, 16);
/* Zeroize sensitive information.*/
MD5_memset((POINTER)context, 0, sizeof(*context));
}
/* MD5 basic transformation. Transforms state based on block. */
static void MD5Transform(
UINT4 state[4],
unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode(x, block, 64);
/* Round 1 */
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
MD5_memset((POINTER)x, 0, sizeof(x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4. */
static void Encode(
unsigned char *output,
const UINT4 *input,
unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
output[j] = (unsigned char)(input[i] & 0xff);
output[j + 1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j + 2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j + 3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4. */
static void Decode(
UINT4 *output,
unsigned char *input,
unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j + 1]) << 8) |
(((UINT4)input[j + 2]) << 16) | (((UINT4)input[j + 3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible. */
static void MD5_memcpy(
POINTER output,
const POINTER input,
unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible. */
static void MD5_memset(
POINTER output,
int value,
unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
char *MESA_MD5_sum_str(unsigned char *raw_data, unsigned int raw_data_len, char result[33])
{
int i;
MD5_CTX context;
unsigned char digest[16];
MD5Init(&context);
MD5Update(&context, raw_data, raw_data_len);
MD5Final(digest, &context);
for (i = 0; i < 16; i++)
sprintf(result + 2 * i, "%02x", digest[i]);
result[32] = 0;
return result;
}
char *MESA_MD5_sum_bin(unsigned char *raw_data, unsigned int raw_data_len, char result[16])
{
MD5_CTX context;
MD5Init(&context);
MD5Update(&context, raw_data, raw_data_len);
MD5Final((unsigned char *)result, &context);
return result;
}
#ifdef __cplusplus
}
#endif

74
test/decoders/http/md5.h Normal file
View File

@@ -0,0 +1,74 @@
/* MD5.H - header file for MD5C.C */
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software. */
#ifndef __MD5_H
#define __MD5_H
#ifndef PROTOTYPES
#define PROTOTYPES 0
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
// typedef unsigned long int UINT4;
typedef unsigned int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list. */
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif
/* MD5 context. */
typedef struct
{
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
#ifdef __cplusplus
extern "C"
{
void MD5Init(MD5_CTX *context);
void MD5Update(
MD5_CTX *context, /* context */
unsigned char *input, /* input block */
unsigned int inputLen); /* length of input block */
void MD5Final(
unsigned char digest[16], /* message digest */
MD5_CTX *context); /* context */
char *MESA_MD5_sum_str(unsigned char *raw_data, unsigned int raw_data_len, char result[33]);
char *MESA_MD5_sum_bin(unsigned char *raw_data, unsigned int raw_data_len, char result[16]);
}
#endif
#endif

View File

@@ -0,0 +1,150 @@
#include "cJSON.h"
#include <gtest/gtest.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include "http_decoder_gtest.h"
#ifdef __cplusplus
extern "C"
{
#endif
#include "stellar/stellar.h"
#ifdef __cplusplus
}
#endif
// #define IGNORE_PRINTF
#ifdef IGNORE_PRINTF
#define printf(fmt, ...) (0)
#endif
static cJSON *g_test_result_root = NULL;
static cJSON *g_load_result_root = NULL;
static const char *result_json_path = NULL;
extern "C" int commit_test_result_json(cJSON *node, const char *name)
{
(void)name;
if (g_test_result_root)
{
// cJSON_AddItemToObject(g_test_result_root, name, node);
// cJSON_AddStringToObject(node, "name", name);
cJSON_AddItemToArray(g_test_result_root, node);
return 0;
}
return -1;
}
static void hdgt_prune_non_result_item(cJSON *benchmark_json_root)
{
int array_size = cJSON_GetArraySize(benchmark_json_root);
for (int i = 0; i < array_size; i++)
{
cJSON *object_root = cJSON_GetArrayItem(benchmark_json_root, i);
cJSON_DeleteItemFromObject(object_root, GTEST_HTTP_PAYLOAD_NAME);
}
}
static cJSON *load_result_from_jsonfile(const char *json_path)
{
if (json_path == NULL)
return NULL;
long file_len = 0;
char *file_content = NULL;
FILE *fp = NULL;
fp = fopen(json_path, "r+");
if (NULL == fp)
{
return NULL;
}
fseek(fp, 0, SEEK_END);
file_len = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (file_len == 0)
{
fclose(fp);
return NULL;
}
file_content = (char *)malloc(file_len + 1);
fread(file_content, file_len, 1, fp);
file_content[file_len] = '\0';
cJSON *load = cJSON_Parse(file_content);
free(file_content);
fclose(fp);
hdgt_prune_non_result_item(load);
return load;
}
TEST(PROTOCOL, compare_result_json)
{
EXPECT_EQ(cJSON_GetArraySize(g_test_result_root), cJSON_GetArraySize(g_load_result_root));
int ret = cJSON_Compare(g_test_result_root, g_load_result_root, 0);
EXPECT_EQ(1, ret);
if (ret != 1)
{
char *load_json_str = cJSON_Print(g_load_result_root);
printf("LOAD Raw:\n%s\n", load_json_str);
free(load_json_str);
char *result_json_str = cJSON_Print(g_test_result_root);
printf("TEST Raw:\n%s\n", result_json_str);
free(result_json_str);
cJSON *t_load = g_load_result_root->child, *t_test = g_test_result_root->child;
while (t_load != NULL)
{
ret = cJSON_Compare(t_load, t_test, 0);
if (ret != 1)
{
load_json_str = cJSON_Print(t_load);
printf("LOAD Diff:\n%s\n", load_json_str);
free(load_json_str);
result_json_str = cJSON_Print(t_test);
printf("TEST Diff:\n%s\n", result_json_str);
free(result_json_str);
goto fail;
}
t_load = t_load->next;
t_test = t_test->next;
}
}
cJSON_Delete(g_load_result_root);
cJSON_Delete(g_test_result_root);
return;
fail:
cJSON_Delete(g_load_result_root);
cJSON_Delete(g_test_result_root);
return;
}
int main(int argc, char *argv[])
{
int ret = 0;
if (argc < 2)
{
printf("Usage: %s <result_json_path>\n", argv[0]);
result_json_path = NULL;
}
else
{
result_json_path = argv[1];
g_test_result_root = cJSON_CreateArray();
g_load_result_root = load_result_from_jsonfile(result_json_path);
assert(g_load_result_root != NULL && g_test_result_root != NULL);
}
::testing::InitGoogleTest(&argc, argv);
if (stellar_run(argc - 1, argv + 1) < 0)
{
return -1;
}
if (result_json_path != NULL)
{
ret = RUN_ALL_TESTS();
}
return ret;
}

View File

@@ -0,0 +1,128 @@
set(DECODER_NAME http)
set(TEST_RUN_DIR ${CMAKE_BINARY_DIR}/test/decoders/http)
set(SAPP_DEVEL_DIR ${TEST_RUN_DIR}/lib)
set(TEST_MAIN http_test_main)
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/test)
include_directories(/usr/local/include/cjson)
include_directories(/opt/tsg/framework/include/stellar)
include_directories(/opt/MESA/include/MESA)
include_directories(/opt/tsg/stellar/include/)
#various ways to add -rdynamic for centos7, centos8, and different cmake version
add_definitions(-rdynamic)
link_directories(${SAPP_DEVEL_DIR})
# assemble test env
add_test(NAME HTTP_MKDIR_METRIC COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/metrics; mkdir -p ${TEST_RUN_DIR}/plugin; mkdir -p ${TEST_RUN_DIR}/log; mkdir -p ${TEST_RUN_DIR}/pcap")
add_test(NAME HTTP_COPY_SPEC COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/plugin/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/spec.toml ${TEST_RUN_DIR}/plugin/spec.toml")
add_test(NAME HTTP_COPY_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/conf/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/stellar.toml ${TEST_RUN_DIR}/conf/stellar.toml")
add_test(NAME HTTP_COPY_LOG_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/conf/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/log.toml ${TEST_RUN_DIR}/conf/log.toml")
add_test(NAME HTTP_COPY_HTTP_DECODER_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/etc/http && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/http_decoder.toml ${TEST_RUN_DIR}/etc/http/")
add_test(NAME HTTP_COPY_HTTP_GTEST_ENTRY_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/etc/http && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/gtest_entry.toml ${TEST_RUN_DIR}/etc/http/")
# update config files
add_test(NAME HTTP_UPDATE_GTEST_PLUG_ENTRY COMMAND bash -c "sed -i 's/name=.*/name=\\x22http_decoder_test_entry\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml")
add_test(NAME HTTP_UPDATE_GTEST_PLUG_TOPIC COMMAND bash -c "sed -i 's/topic=.*/topic=\\x22HTTP_DECODER_MESSAGE\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml")
# update plugin to be tested
add_test(NAME HTTP_CP_DECODER_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/decoders/http/http_dyn.so ${TEST_RUN_DIR}/plugin/${DECODER_NAME}.so")
add_test(NAME HTTP_CP_DECODER_GTEST_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/decoders/http/${DECODER_NAME}_test.so ${TEST_RUN_DIR}/plugin/${DECODER_NAME}_test.so")
set_tests_properties(HTTP_MKDIR_METRIC HTTP_COPY_SPEC HTTP_COPY_HTTP_DECODER_CONF HTTP_COPY_HTTP_GTEST_ENTRY_CONF
HTTP_COPY_CONF HTTP_COPY_LOG_CONF
HTTP_CP_DECODER_SO HTTP_CP_DECODER_GTEST_SO
HTTP_UPDATE_GTEST_PLUG_ENTRY HTTP_UPDATE_GTEST_PLUG_TOPIC
PROPERTIES FIXTURES_SETUP TestFixture)
set(TEST_JSON_DIR ${PROJECT_SOURCE_DIR}/benchmarks/json/http)
set(TEST_PCAP_DIR ${PROJECT_SOURCE_DIR}/benchmarks/pcap/http)
# run tests
add_test(NAME HTTP_GET_SINGLE_TRANS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_single_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_single_trans.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_GET_MULTI_TRANS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_multi_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_multi_trans.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_GET_LONG_COOKIE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_long_cookie.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_long_cookie.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_GET_ENCODED_URI_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_encoded_uri.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_encoded_uri.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_RES_GZIP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_res_gzip.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_res_gzip.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_CHUNKED_RES_GZIP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_chunked_res_gzip.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_chunked_res_gzip.json"WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_OVER_TCP_KEEPALIVE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_tcp_keepalive.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_tcp_keepalive.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_OVER_PPPOE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_pppoe.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_pppoe.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_OVER_TLS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_tls.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_tls.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME NON_HTTP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/non_http.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/non_http.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_REQ_1BYTE_SLIDING_WINDOW_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_req_1byte_sliding_window.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_req_1byte_sliding_window.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_RES_1BYTE_SLIDING_WINDOW_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_res_1byte_sliding_window.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_res_1byte_sliding_window.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_NO_CONTENT_LENGTH_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_no_content_length.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_no_content_length.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_POST_MULTIPART_FORM_DATA_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_multipart_form_data.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_post_multipart_form_data.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_HEADERS_EXCEED_MAXIMUM_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdrs_exceed_maximum.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdrs_exceed_maximum.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_GET_MALFORMED_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_malformed.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_malformed.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_URL_WITHOUT_HOST_V4_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_url_test_without_host.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_url_test_without_host.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_URL_WITHOUT_HOST_V6_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_url_test_without_host_v6.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_url_test_without_host_v6.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
#no SYN, steallar not support !
# add_test(NAME HTTP_HEADER_VALUE_EMPTY_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdr_value_empty.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_value_empty.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_UPGRADE_WEBSOCKET_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_upgrade_websocket.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_upgrade_websocket.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_MULTI_PARSE_ERROR_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_multi_parse_error.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_multi_parse_error.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_GET_REQ_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_req_pipeline.pcap ${TEST_RUN_DIR}/pcap/test.pcap;./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_req_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_TRANS_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_trans_pipeline.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_trans_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
#no SYN, steallar not support !
# add_test(NAME HTTP_HEADER_TRUNCATED_IN_KV_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdr_truncated_in_kv.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_truncated_in_kv.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
# add_test(NAME HTTP_HEADER_TRUNCATED_AFTER_KV_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_truncated_after_kv.json -r ${TEST_PCAP_DIR}/http_hdr_truncated_after_kv.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_FIN_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_fin.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/non_http.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
# add_test(NAME HTTP_TUNNEL_ONLY_HDR_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_tunnel_s2c_only_hdr.json
# -r ${TEST_PCAP_DIR}/http_tunnel_s2c_only_hdr.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_CHN_ENCODE_URL COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_chn_encode_url.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_chn_encode_url.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_ZLIB_DEADLOCK COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_zlib_deadlock.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_zlib_deadlock.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_OUT_OF_ORDER COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_out_of_order.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_out_of_order.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_GZIP_OUT_OF_ORDER COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_gzip_out_of_order.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_gzip_out_of_order.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
set_tests_properties(HTTP_GET_SINGLE_TRANS_TEST
HTTP_GET_MULTI_TRANS_TEST
HTTP_GET_LONG_COOKIE_TEST
HTTP_GET_ENCODED_URI_TEST
HTTP_RES_GZIP_TEST
HTTP_CHUNKED_RES_GZIP_TEST
HTTP_OVER_TCP_KEEPALIVE_TEST
HTTP_OVER_PPPOE_TEST
HTTP_OVER_TLS_TEST
NON_HTTP_TEST
HTTP_REQ_1BYTE_SLIDING_WINDOW_TEST
HTTP_RES_1BYTE_SLIDING_WINDOW_TEST
HTTP_NO_CONTENT_LENGTH_TEST
HTTP_POST_MULTIPART_FORM_DATA_TEST
HTTP_HEADERS_EXCEED_MAXIMUM_TEST
HTTP_GET_MALFORMED_TEST
HTTP_URL_WITHOUT_HOST_V4_TEST
HTTP_URL_WITHOUT_HOST_V6_TEST
HTTP_MULTI_PARSE_ERROR_TEST
HTTP_UPGRADE_WEBSOCKET_TEST
HTTP_GET_REQ_PIPELINE_TEST
HTTP_TRANS_PIPELINE_TEST
HTTP_FIN_TEST
HTTP_CHN_ENCODE_URL
HTTP_ZLIB_DEADLOCK
HTTP_OUT_OF_ORDER
HTTP_GZIP_OUT_OF_ORDER
PROPERTIES FIXTURES_REQUIRED TestFixture)
add_test(NAME HTTP_UPDATE_STATE_PLUG_ENTRY COMMAND bash -c "sed -i 's/name=.*/name=\\x22http_decoder_test_state_entry\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml")
add_test(NAME HTTP_UPDATE_STATE_PLUG_TOPIC COMMAND bash -c "sed -i 's/topic=.*/topic=\\x22HTTP_DECODER_MESSAGE\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml")
set_tests_properties(HTTP_UPDATE_STATE_PLUG_ENTRY HTTP_UPDATE_STATE_PLUG_TOPIC HTTP_CP_DECODER_SO HTTP_CP_DECODER_GTEST_SO HTTP_MKDIR_METRIC
PROPERTIES FIXTURES_SETUP TestState)
add_test(NAME HTTP_MSG_TYPE_STATE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_MSG_TYPE_STATE_C2S_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_c2s.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_c2s.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_MSG_TYPE_STATE_S2C_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_s2c.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_s2c.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_MSG_TYPE_STATE_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_multi_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_MSG_TYPE_STATE_SES_EXCEPTION_C2S_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_session_exception_c2s.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_exception_c2s.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
add_test(NAME HTTP_MSG_TYPE_STATE_SES_EXCEPTION_S2C_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_session_exception_s2c.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_exception_s2c.json" WORKING_DIRECTORY ${TEST_RUN_DIR})
set_tests_properties(HTTP_MSG_TYPE_STATE_TEST
HTTP_MSG_TYPE_STATE_C2S_TEST
HTTP_MSG_TYPE_STATE_S2C_TEST
HTTP_MSG_TYPE_STATE_PIPELINE_TEST
HTTP_MSG_TYPE_STATE_SES_EXCEPTION_C2S_TEST
HTTP_MSG_TYPE_STATE_SES_EXCEPTION_S2C_TEST
PROPERTIES FIXTURES_REQUIRED TestState)

View File

@@ -0,0 +1,3 @@
[entry]
name="http_decoder_test_state_entry"
topic="HTTP_DECODER_MESSAGE"

View File

@@ -0,0 +1,18 @@
[basic]
# Switch for decompress body, open(1) closed(0), default(0)
decompress=1
# per session mempool size, default(32Ki)
mempool_size=32768
# per session http parsed result queue length
result_queue_len=16
# call fieldstat every stat_interval_pkts
stat_interval_pkts=1000
# fieldstat output interval
stat_output_interval=1
# connect tunnel
proxy_enable=0

View File

@@ -0,0 +1,4 @@
[log]
output = file # stderr, file
file = "log/stellar.log"
level = DEBUG # TRACE, DEBUG, INFO, WARN, ERROR, FATAL

View File

@@ -0,0 +1,9 @@
[[plugin]]
path = "./plugin/http.so"
init = "http_decoder_init"
exit = "http_decoder_exit"
[[plugin]]
path = "./plugin/http_test.so"
init = "http_decoder_test_init"
exit = "http_decoder_test_exit"

View File

@@ -0,0 +1,57 @@
[id_generator]
snowflake_worker_id_base = 1 # [0, 31]
snowflake_worker_id_offset = 2 # [0, 127]
[packet_io]
mode = dumpfile # dumpfile, marsio
app_symbol = stellar
dev_symbol = nf_0_fw
dumpfile_dir = "./pcap"
nr_threads = 1 # [1, 256]
#cpu_mask = [5, 6, 7, 8, 9, 10, 11, 12]
cpu_mask = [5]
[ip_reassembly]
enable = 1
timeout = 10000 # range: [1, 60000] (ms)
bucket_entries = 256 # range: [1, 4294967295] (must be power of 2)
bucket_num = 4096 # range: [1, 4294967295]
[session_manager]
# max session number
max_tcp_session_num = 1000
max_udp_session_num = 1000
# session overload evict
tcp_overload_evict_old_sess = 1 # 1: evict old session, 0: bypass new session
udp_overload_evict_old_sess = 1 # 1: evict old session, 0: bypass new session
# TCP timeout
tcp_init_timeout = 10 # range: [1, 60000] (ms)
tcp_handshake_timeout = 10 # range: [1, 60000] (ms)
tcp_data_timeout = 10 # range: [1, 15999999000] (ms)
tcp_half_closed_timeout = 10 # range: [1, 604800000] (ms)
tcp_time_wait_timeout = 10 # range: [1, 600000] (ms)
tcp_discard_timeout = 10 # range: [1, 15999999000] (ms)
tcp_unverified_rst_timeout = 10 # range: [1, 600000] (ms)
# UDP timeout
udp_data_timeout = 10 # range: [1, 15999999000] (ms)
udp_discard_timeout = 10 # range: [1, 15999999000] (ms)
# duplicate packet filter
duplicated_packet_filter_enable = 0
duplicated_packet_filter_capacity = 1000000 # range: [1, 4294967295]
duplicated_packet_filter_timeout = 10 # range: [1, 60000] (ms)
duplicated_packet_filter_error_rate = 0.00001 # range: [0.0, 1.0]
# evicted session filter
evicted_session_filter_enable = 0
evicted_session_filter_capacity = 1000000 # range: [1, 4294967295]
evicted_session_filter_timeout = 10 # range: [1, 60000] (ms)
evicted_session_filter_error_rate = 0.00001 # range: [0.0, 1.0]
# TCP reassembly (Per direction)
tcp_reassembly_enable = 1
tcp_reassembly_max_timeout = 10 # range: [1, 60000] (ms)
tcp_reassembly_max_segments = 256 # range: [2, 4096]