summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorlijia <[email protected]>2024-04-08 09:48:13 +0800
committerlijia <[email protected]>2024-04-08 09:48:13 +0800
commit215e383be1f47cd18c235855d0cee0485f6cb423 (patch)
tree34668fd59622c37826c3a786ba0e196a7d65147b /test
parentea795e9c6940281bf8557bfd79f13f319f947c58 (diff)
Separate from stellar-on-sapp project.
Diffstat (limited to 'test')
-rw-r--r--test/.gitkeep0
-rw-r--r--test/CMakeLists.txt149
-rw-r--r--test/http_decoder_driver.cpp923
-rw-r--r--test/http_decoder_gtest.cpp370
-rw-r--r--test/http_decoder_gtest.h114
-rw-r--r--test/http_decoder_stub.cpp250
-rw-r--r--test/http_pcap/http_6over4_single_trans.pcapbin0 -> 1424 bytes
-rw-r--r--test/http_pcap/http_chunked_res_gzip.pcapbin0 -> 29517 bytes
-rw-r--r--test/http_pcap/http_connect_flood.pcapbin0 -> 31672 bytes
-rw-r--r--test/http_pcap/http_get_encoded_uri.pcapbin0 -> 35174 bytes
-rw-r--r--test/http_pcap/http_get_long_cookie.pcapbin0 -> 4489 bytes
-rw-r--r--test/http_pcap/http_get_malformed.pcapbin0 -> 2737 bytes
-rw-r--r--test/http_pcap/http_get_multi_trans.pcapbin0 -> 35841 bytes
-rw-r--r--test/http_pcap/http_get_req_pipeline.pcapbin0 -> 2251 bytes
-rw-r--r--test/http_pcap/http_get_single_trans.pcapbin0 -> 1359 bytes
-rw-r--r--test/http_pcap/http_hdr_truncated_after_kv.pcapbin0 -> 155839 bytes
-rw-r--r--test/http_pcap/http_hdr_truncated_in_kv.pcapbin0 -> 5493 bytes
-rw-r--r--test/http_pcap/http_hdr_value_empty.pcapbin0 -> 1718 bytes
-rw-r--r--test/http_pcap/http_hdrs_exceed_maximum.pcapbin0 -> 5029 bytes
-rw-r--r--test/http_pcap/http_multi_parse_error.pcapbin0 -> 1980 bytes
-rw-r--r--test/http_pcap/http_no_content_length.pcapbin0 -> 1944 bytes
-rw-r--r--test/http_pcap/http_over_pppoe.pcapbin0 -> 1991 bytes
-rw-r--r--test/http_pcap/http_over_tcp_keepalive.pcapbin0 -> 20213 bytes
-rw-r--r--test/http_pcap/http_over_tls.pcapbin0 -> 232820 bytes
-rw-r--r--test/http_pcap/http_post_multipart_form_data.pcapbin0 -> 4824 bytes
-rw-r--r--test/http_pcap/http_req_1byte_sliding_window.pcapbin0 -> 31724 bytes
-rw-r--r--test/http_pcap/http_res_1byte_sliding_window.pcapbin0 -> 55449 bytes
-rw-r--r--test/http_pcap/http_res_gzip.pcapbin0 -> 1707 bytes
-rw-r--r--test/http_pcap/http_trans_pipeline.pcapbin0 -> 6832 bytes
-rw-r--r--test/http_pcap/http_tunnel_for_pop3.pcapbin0 -> 3673 bytes
-rw-r--r--test/http_pcap/http_upgrade_http2.pcapbin0 -> 1617 bytes
-rw-r--r--test/http_pcap/http_upgrade_websocket.pcapbin0 -> 7851 bytes
-rw-r--r--test/http_pcap/http_url_test_with_host.pcapbin0 -> 1362 bytes
-rw-r--r--test/http_pcap/http_url_test_without_host.pcapbin0 -> 1624 bytes
-rw-r--r--test/http_pcap/non_http.pcapbin0 -> 27850 bytes
-rw-r--r--test/md5.c356
-rw-r--r--test/md5.h70
-rw-r--r--test/test_env/conflist.inf9
-rw-r--r--test/test_env/sapp4.el8.x86_64.rpmbin0 -> 1052968 bytes
-rw-r--r--test/test_env/spec.toml11
-rw-r--r--test/test_env/start_loader.inf17
-rw-r--r--test/test_env/tsg_l7_protocol.conf57
-rw-r--r--test/test_result_json/http_6over4_single_trans.json33
-rw-r--r--test/test_result_json/http_chunked_res_gzip.json41
-rw-r--r--test/test_result_json/http_connect_flood.json686
-rw-r--r--test/test_result_json/http_get_encoded_uri.json71
-rw-r--r--test/test_result_json/http_get_long_cookie.json24
-rw-r--r--test/test_result_json/http_get_malformed.json28
-rw-r--r--test/test_result_json/http_get_multi_trans.json139
-rw-r--r--test/test_result_json/http_get_req_pipeline.json67
-rw-r--r--test/test_result_json/http_get_single_trans.json29
-rw-r--r--test/test_result_json/http_hdr_truncated_after_kv.json285
-rw-r--r--test/test_result_json/http_hdr_truncated_in_kv.json53
-rw-r--r--test/test_result_json/http_hdr_value_empty.json35
-rw-r--r--test/test_result_json/http_hdrs_exceed_maximum.json46
-rw-r--r--test/test_result_json/http_multi_parse_error.json35
-rw-r--r--test/test_result_json/http_no_content_length.json45
-rw-r--r--test/test_result_json/http_over_pppoe.json35
-rw-r--r--test/test_result_json/http_over_tcp_keepalive.json40
-rw-r--r--test/test_result_json/http_over_tls.json2
-rw-r--r--test/test_result_json/http_post_multipart_form_data.json101
-rw-r--r--test/test_result_json/http_req_1byte_sliding_window.json34
-rw-r--r--test/test_result_json/http_res_1byte_sliding_window.json34
-rw-r--r--test/test_result_json/http_res_gzip.json44
-rw-r--r--test/test_result_json/http_trans_pipeline.json368
-rw-r--r--test/test_result_json/http_tunnel_for_pop3.json33
-rw-r--r--test/test_result_json/http_upgrade_http2.json42
-rw-r--r--test/test_result_json/http_upgrade_websocket.json42
-rw-r--r--test/test_result_json/http_url_test_with_host.json35
-rw-r--r--test/test_result_json/http_url_test_without_host.json29
-rw-r--r--test/test_result_json/non_http.json1
71 files changed, 4783 insertions, 0 deletions
diff --git a/test/.gitkeep b/test/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/.gitkeep
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..6ee5c6f
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,149 @@
+set(DECODER_NAME http_decoder)
+
+add_library(${DECODER_NAME}_test SHARED http_decoder_gtest.cpp)
+add_dependencies(${DECODER_NAME}_test ${DECODER_NAME})
+target_link_libraries(${DECODER_NAME}_test MESA_prof_load)
+set_target_properties(${DECODER_NAME}_test PROPERTIES PREFIX "")
+
+set(TEST_RUN_DIR ${CMAKE_BINARY_DIR}/testing)
+
+include_directories(${CMAKE_SOURCE_DIR}/include)
+include_directories(/usr/local/include/cjson)
+include_directories(/opt/tsg/framework/include/stellar)
+include_directories(/opt/MESA/include/MESA)
+
+add_executable(gtest_http_decoder http_decoder_driver.cpp http_decoder_stub.cpp http_decoder_gtest.cpp)
+link_directories(${CMAKE_BINARY_DIR}/src)
+target_link_libraries(gtest_http_decoder http_decoder gtest pcap MESA_jump_layer cjson-static)
+
+set(TEST_MAIN gtest_http_decoder)
+
+add_test(NAME CREATE_RUN_ENV COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}")
+add_test(NAME COPY_TEST_MAIN COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/${TEST_MAIN} ${TEST_RUN_DIR}/${TEST_MAIN}")
+add_test(NAME COPY_HTTP_DECODER_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/etc/http && cp ${PROJECT_SOURCE_DIR}/conf/http_decoder.toml ${TEST_RUN_DIR}/etc/http/")
+
+
+set_tests_properties(CREATE_RUN_ENV COPY_TEST_MAIN COPY_HTTP_DECODER_CONF
+ PROPERTIES FIXTURES_SETUP TestFixture)
+
+# run tests
+add_test(NAME HTTP_GET_SINGLE_TRANS_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_get_single_trans.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_get_single_trans.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_GET_SINGLE_TRANS_MSS1_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_get_single_trans.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_get_single_trans.pcap -m 1 WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_GET_MULTI_TRANS_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_get_multi_trans.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_get_multi_trans.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_GET_LONG_COOKIE_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_get_long_cookie.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_get_long_cookie.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_GET_ENCODED_URI_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_get_encoded_uri.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_get_encoded_uri.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_RES_GZIP_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_res_gzip.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_res_gzip.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_CHUNKED_RES_GZIP_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_chunked_res_gzip.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_chunked_res_gzip.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_OVER_TCP_KEEPALIVE_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_over_tcp_keepalive.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_over_tcp_keepalive.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_TUNNEL_FOR_POP3_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_tunnel_for_pop3.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_tunnel_for_pop3.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_OVER_PPPOE_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_over_pppoe.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_over_pppoe.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_OVER_TLS_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_over_tls.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_over_tls.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME NON_HTTP_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/non_http.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/non_http.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_REQ_1BYTE_SLIDING_WINDOW_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_req_1byte_sliding_window.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_req_1byte_sliding_window.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_RES_1BYTE_SLIDING_WINDOW_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_res_1byte_sliding_window.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_res_1byte_sliding_window.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_NO_CONTENT_LENGTH_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_no_content_length.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_no_content_length.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_POST_MULTIPART_FORM_DATA_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_post_multipart_form_data.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_post_multipart_form_data.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_HEADERS_EXCEED_MAXIMUM_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_hdrs_exceed_maximum.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_hdrs_exceed_maximum.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+#add_test(NAME HTTP_CONNECT_FLOOD_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_connect_flood.json
+# -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_connect_flood.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_GET_MALFORMED_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_get_malformed.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_get_malformed.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_HEADER_VALUE_EMPTY_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_hdr_value_empty.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_hdr_value_empty.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_UPGRADE_WEBSOCKET_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_upgrade_websocket.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_upgrade_websocket.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_UPGRADE_HTTP2_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_upgrade_http2.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_upgrade_http2.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_MULTI_PARSE_ERROR_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_multi_parse_error.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_multi_parse_error.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_GET_REQ_PIPELINE_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_get_req_pipeline.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_get_req_pipeline.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_TRANS_PIPELINE_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_trans_pipeline.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_trans_pipeline.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_HEADER_TRUNCATED_IN_KV_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_hdr_truncated_in_kv.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_hdr_truncated_in_kv.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_HEADER_TRUNCATED_AFTER_KV_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_hdr_truncated_after_kv.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_hdr_truncated_after_kv.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_URL_WITH_HOST_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_url_test_with_host.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_url_test_with_host.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_URL_WITHOUT_HOST_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_url_test_without_host.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_url_test_without_host.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_6OVER4_SINGLE_TRANS_TEST COMMAND ${TEST_MAIN} -b ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_6over4_single_trans.json
+ -p ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/http_6over4_single_trans.pcap WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+set_tests_properties(HTTP_GET_SINGLE_TRANS_TEST
+ HTTP_GET_SINGLE_TRANS_MSS1_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_TUNNEL_FOR_POP3_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_HEADER_VALUE_EMPTY_TEST
+ HTTP_MULTI_PARSE_ERROR_TEST
+ HTTP_UPGRADE_WEBSOCKET_TEST
+ HTTP_UPGRADE_HTTP2_TEST
+ HTTP_GET_REQ_PIPELINE_TEST
+ HTTP_TRANS_PIPELINE_TEST
+ HTTP_HEADER_TRUNCATED_IN_KV_TEST
+ HTTP_HEADER_TRUNCATED_AFTER_KV_TEST
+ HTTP_URL_WITH_HOST_TEST
+ HTTP_URL_WITHOUT_HOST_TEST
+ HTTP_6OVER4_SINGLE_TRANS_TEST
+ PROPERTIES FIXTURES_REQUIRED TestFixture)
diff --git a/test/http_decoder_driver.cpp b/test/http_decoder_driver.cpp
new file mode 100644
index 0000000..b1e24dc
--- /dev/null
+++ b/test/http_decoder_driver.cpp
@@ -0,0 +1,923 @@
+/*
+ Http Decoder Google Test driver module
+*/
+#include <stdio.h>
+#include <string.h>
+#ifndef __USE_MISC
+#define __USE_MISC 1
+#endif
+#ifndef __FAVOR_BSD
+#define __FAVOR_BSD 1
+#endif
+#ifndef __USE_BSD
+#define __USE_BSD 1
+#endif
+#include <netinet/tcp.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <unistd.h>
+#include <assert.h>
+#include <getopt.h>
+#include <gtest/gtest.h>
+#include <pcap/pcap.h>
+#include "http_decoder_gtest.h"
+#include "MESA_jump_layer.h"
+
+extern "C" int http_decoder_entry(struct session *sess, int events,
+ const struct packet *pkt, void *cb_arg);
+extern "C" void http_decoder_test_exit(void *test_ctx);
+extern "C" void *http_decoder_test_init(struct stellar *st);
+extern "C" void *http_decoder_init(struct stellar *st);
+struct fake_stellar *g_fake_stellar; // used for plugin commit_test_result_json()
+
+static const char *hdgt_cla_short_options = "hb:p:s:m:";
+static const struct option hdgt_cla_long_options[] =
+ {
+ {"help", no_argument, NULL, 'h'},
+ {"benchmark-file", required_argument, NULL, 'b'},
+ {"data-pcap-file", required_argument, NULL, 'p'},
+ {"data-json-file", required_argument, NULL, 's'},
+ {"mss", required_argument, NULL, 'm'},
+ {NULL, 0, NULL, 0}};
+
+static const char *g_data_src_json_non_headers[] = {
+ "__X_HTTP_TUPLE4",
+ "__X_HTTP_TRANSACTION",
+ "__X_HTTP_RESULT_INDEX",
+ "__X_HTTP_URL",
+ "method",
+ "uri",
+ "req_version",
+ "major_version",
+ "minor_version",
+ "res_version",
+ "res_status",
+ "status_code",
+ NULL};
+
+static void hdgt_cmd_usage(int argc, char **argv)
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "\t -b set benchmark json file\n");
+ fprintf(stderr, "\t -p set data source as pcap file\n");
+ fprintf(stderr, "\t -s set data source as json file\n");
+ fprintf(stderr, "\t -m set tcp Max Segment Size\n");
+ exit(1);
+}
+
+static int hdgt_parse_cmd_args(fake_stellar *fst, int argc, char **argv)
+{
+ int c, ret;
+
+ fst->tcp_mss = 1460; // set default value
+
+ while (1)
+ {
+ c = getopt_long(argc, argv, hdgt_cla_short_options, hdgt_cla_long_options, NULL);
+ if (c == -1)
+ {
+ ret = 0;
+ break;
+ }
+
+ switch (c)
+ {
+ case 'h':
+ hdgt_cmd_usage(argc, argv);
+ break;
+ case 'b':
+ fst->benchmark_json_file_name = optarg;
+ break;
+ case 'p':
+ fst->data_source_type = DATA_SOURCE_PCAP;
+ fst->data_source_file_name = optarg;
+ break;
+ case 's':
+ fst->data_source_type = DATA_SOURCE_JSON;
+ fst->data_source_file_name = optarg;
+ break;
+ case 'm':
+ fst->tcp_mss = atoi(optarg);
+ if (fst->tcp_mss <= 0 || fst->tcp_mss > 65535)
+ {
+ DEBUG_PRINT("Invalid tcp mss value! must be [1, 65535]\n");
+ hdgt_cmd_usage(argc, argv);
+ }
+ break;
+ default:
+ return -1;
+ break;
+ }
+ }
+
+ // check args
+ if (!fst->benchmark_json_file_name)
+ {
+ DEBUG_PRINT("benchmark json file is not set!\n");
+ hdgt_cmd_usage(argc, argv);
+ return -1;
+ }
+
+ if (__DATA_SOURCE_NULL == fst->data_source_type)
+ {
+ DEBUG_PRINT("data source is not set!\n");
+ hdgt_cmd_usage(argc, argv);
+ return -1;
+ }
+
+ return ret;
+}
+
+static int hdgt_compare_result(struct fake_stellar *fst)
+{
+ int final_result = 0;
+ cJSON_bool case_sensitive = FLASE;
+
+ if (!fst->http_plug_test_result_root)
+ {
+ DEBUG_PRINT("Not found test json result!\n");
+ return -1;
+ }
+
+ if (!fst->load_benchmark_json_root)
+ {
+ DEBUG_PRINT("Not found benchmark json instance!\n");
+ return -1;
+ }
+
+ if (cJSON_GetArraySize(fst->load_benchmark_json_root) != cJSON_GetArraySize(fst->http_plug_test_result_root))
+ {
+ DEBUG_PRINT("Compare json result: array size is diff!\n");
+ final_result++;
+ }
+
+ int ret = cJSON_Compare(fst->load_benchmark_json_root, fst->http_plug_test_result_root, case_sensitive);
+ if (ret != TRUE)
+ {
+ char *load_json_str = cJSON_Print(fst->load_benchmark_json_root);
+ printf("LOAD Raw:\n%s\n", load_json_str);
+
+ char *result_json_str = cJSON_Print(fst->http_plug_test_result_root);
+ printf("TEST Raw:\n%s\n", result_json_str);
+
+ int min_len = MIN(strlen(load_json_str), strlen(result_json_str));
+ for (size_t i = 0; i < min_len; i++)
+ {
+ if (load_json_str[i] != result_json_str[i])
+ {
+ printf("######### JSON Diff at len:%d: \n\tLOAD: %.*s\n\tTEST: %.*s\n", (int)i, 16, load_json_str + i, 16, result_json_str + i);
+ break;
+ }
+ }
+
+ free(load_json_str);
+ free(result_json_str);
+
+ cJSON *t_load = fst->load_benchmark_json_root->child;
+ cJSON *t_test = fst->http_plug_test_result_root->child;
+ while (t_load != NULL && t_test != NULL)
+ {
+ ret = cJSON_Compare(t_load, t_test, case_sensitive);
+ if (ret != TRUE)
+ {
+ 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);
+ final_result++;
+ }
+ t_load = t_load->next;
+ t_test = t_test->next;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT("Compare json result success!\n");
+ }
+
+ return final_result;
+}
+
+static char *hdgt_get_file_content(const char *filename)
+{
+ FILE *fp = fopen(filename, "r");
+ if (NULL == fp)
+ {
+ DEBUG_PRINT("fopen() fail!\n");
+ return NULL;
+ }
+ fseek(fp, 0, SEEK_END);
+ long file_size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ char *file_content = MMALLOC(char, file_size + 1);
+ if (fread(file_content, 1, file_size, fp) != file_size)
+ {
+ DEBUG_PRINT("fread() %s fail!\n", filename);
+ fclose(fp);
+ MFREE(file_content);
+ return NULL;
+ }
+ fclose(fp);
+ return file_content;
+}
+
+static struct fake_session *hdgt_session_new(struct fake_stellar *fst)
+{
+ struct fake_session *fses = MMALLOC(struct fake_session, sizeof(struct fake_session));
+
+ fses->fst = fst;
+ fses->tcp_mss = fst->tcp_mss;
+ // todo : get protocol type from packet, not fixed
+ fses->type = SESSION_TYPE_TCP;
+ return fses;
+}
+
+static int hdgt_get_packet_from_pcap(struct fake_stellar *fst, struct fake_packet *fpkt)
+{
+ struct pcap_pkthdr *pkt_hdr;
+ const u_char *pkt_data;
+ int ret = pcap_next_ex(fst->pcap_ins, &pkt_hdr, &pkt_data);
+ if (1 == ret)
+ {
+ fpkt->raw_pkt_data = (char *)pkt_data;
+ fpkt->raw_pkt_data_len = pkt_hdr->caplen;
+ DEBUG_PRINT("Warning! this is a rough packet decoder, not support tcp out of order, seq overlap...\n");
+ return 1;
+ }
+ else if (-2 == ret)
+ {
+ DEBUG_PRINT("pcap file over!\n");
+ return 0;
+ }
+ DEBUG_PRINT("pcap_next_ex() fail: %s!\n", pcap_geterr(fst->pcap_ins));
+ return -1;
+}
+
+static int hdgt_get_packet_from_json(struct fake_stellar *fst, struct fake_packet *fpkt)
+{
+ cJSON *json_root = fst->data_src_json_para.json_root;
+ cJSON *json_item = cJSON_GetArrayItem(json_root, fst->data_src_json_para.current_json_array_idx);
+ if (NULL == json_item)
+ {
+ DEBUG_PRINT("Not found json object at index %d!\n", fst->data_src_json_para.current_json_array_idx);
+ return -1;
+ }
+ fst->data_src_json_para.current_object = json_item;
+ fst->data_src_json_para.current_json_array_idx++;
+ return 1;
+}
+
+static int hdgt_is_reserverd_json_header(const cJSON *json_object)
+{
+ for (size_t i = 0; g_data_src_json_non_headers[i] != NULL; i++)
+ {
+ if (strlen(json_object->string) == strlen(g_data_src_json_non_headers[i]) && (0 == strncmp(json_object->string, g_data_src_json_non_headers[i], strlen(g_data_src_json_non_headers[i]))))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int hdgt_get_packet_dir_from_json(cJSON *json)
+{
+ cJSON *json_dir = cJSON_GetObjectItem(json, GTEST_HTTP_TRANS_NAME);
+ if (NULL == json_dir)
+ {
+ return -1;
+ }
+ if (strncasecmp("request", json_dir->valuestring, strlen("request")) == 0)
+ {
+ return PACKET_DIRECTION_C2S;
+ }
+ else if (strncasecmp("response", json_dir->valuestring, strlen("response")) == 0)
+ {
+ return PACKET_DIRECTION_S2C;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static void hdgt_get_req_line_from_json(struct data_src_json_para_t *data_src_json_para)
+{
+ cJSON *json_item = data_src_json_para->current_object;
+ cJSON *method, *uri, *major_version, *minor_version;
+
+ method = cJSON_GetObjectItem(json_item, "method");
+ uri = cJSON_GetObjectItem(json_item, "uri");
+ major_version = cJSON_GetObjectItem(json_item, "major_version");
+ minor_version = cJSON_GetObjectItem(json_item, "minor_version");
+
+ if (method && uri && major_version && minor_version)
+ {
+ sprintf(data_src_json_para->key_value_buf, "%s %s HTTP/%d.%d\r\n",
+ method->valuestring, uri->valuestring, major_version->valueint, minor_version->valueint);
+ }
+ else
+ {
+ DEBUG_PRINT("get request line from json fail!\n");
+ }
+}
+
+static void hdgt_get_res_line_from_json(struct data_src_json_para_t *data_src_json_para)
+{
+ cJSON *json_item = data_src_json_para->current_object;
+ cJSON *res_status, *status_code, *major_version, *minor_version;
+
+ res_status = cJSON_GetObjectItem(json_item, "res_status");
+ status_code = cJSON_GetObjectItem(json_item, "status_code");
+ major_version = cJSON_GetObjectItem(json_item, "major_version");
+ minor_version = cJSON_GetObjectItem(json_item, "minor_version");
+
+ if (res_status && status_code && major_version && minor_version)
+ {
+ sprintf(data_src_json_para->key_value_buf, "HTTP/%d.%d %d %s\r\n",
+ major_version->valueint, minor_version->valueint, status_code->valueint, res_status->valuestring);
+ }
+ else
+ {
+ DEBUG_PRINT("get response line from json fail!\n");
+ }
+}
+
+static void hdgt_get_headers_from_json(struct data_src_json_para_t *data_src_json_para)
+{
+ cJSON *json_item = data_src_json_para->current_object->child;
+ char *data_ptr = data_src_json_para->key_value_buf + strlen(data_src_json_para->key_value_buf);
+ int len;
+
+ while (json_item)
+ {
+ if (0 == hdgt_is_reserverd_json_header(json_item))
+ {
+ if (cJSON_IsString(json_item))
+ {
+ len = sprintf(data_ptr, "%s: %s\r\n", json_item->string, json_item->valuestring);
+ }
+ else if (cJSON_IsNumber(json_item))
+ {
+ len = sprintf(data_ptr, "%s: %d\r\n", json_item->string, json_item->valueint);
+ }
+ else if (cJSON_IsBool(json_item))
+ {
+ len = sprintf(data_ptr, "%s: %s\r\n", json_item->string, json_item->valueint ? "true" : "false");
+ }
+ else
+ {
+ len = sprintf(data_ptr, "%s: %s\r\n", json_item->string, cJSON_Print(json_item));
+ }
+ data_ptr += len;
+ }
+ json_item = json_item->next;
+ }
+ sprintf(data_ptr, "\r\n"); // headers EOF
+}
+
+static int hdgt_update_packet_detail_by_json(struct fake_stellar *fst, struct fake_packet *fpkt)
+{
+ fpkt->dir = hdgt_get_packet_dir_from_json(fst->data_src_json_para.current_object);
+ if (PACKET_DIRECTION_C2S != fpkt->dir && PACKET_DIRECTION_S2C != fpkt->dir)
+ {
+ DEBUG_PRINT("get packet direction from json fail!\n");
+ return -1;
+ }
+
+ if (PACKET_DIRECTION_C2S == fpkt->dir)
+ {
+ hdgt_get_req_line_from_json(&fst->data_src_json_para);
+ }
+ else
+ {
+ hdgt_get_res_line_from_json(&fst->data_src_json_para);
+ }
+ hdgt_get_headers_from_json(&fst->data_src_json_para);
+
+ fpkt->payload_data = fst->data_src_json_para.key_value_buf;
+ fpkt->payload_data_len = strlen(fst->data_src_json_para.key_value_buf);
+ fpkt->payload_submit_offset = 0;
+
+ return 0;
+}
+
+static int hdgt_get_packet(struct fake_stellar *fst, struct fake_packet *fpkt)
+{
+ int ret = -1;
+ memset(fpkt, 0, sizeof(struct fake_packet));
+ if (DATA_SOURCE_PCAP == fst->data_source_type)
+ {
+ ret = hdgt_get_packet_from_pcap(fst, fpkt);
+ }
+ else if (DATA_SOURCE_JSON == fst->data_source_type)
+ {
+ ret = hdgt_get_packet_from_json(fst, fpkt);
+ }
+ else
+ {
+ DEBUG_PRINT("Invalid data source type!\n");
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int hdgt_has_data_left(struct fake_packet *fpkt)
+{
+ return fpkt->payload_submit_offset < fpkt->payload_data_len;
+}
+
+static int hdgt_get_packet_dir_of_tcp(const struct tcphdr *th)
+{
+ int dir;
+
+ if (TH_SYN == th->th_flags)
+ {
+ dir = PACKET_DIRECTION_C2S;
+ }
+ else if ((TH_SYN | TH_ACK) == th->th_flags)
+ {
+ dir = PACKET_DIRECTION_S2C;
+ }
+ else
+ {
+ if (ntohs(th->th_sport) > ntohs(th->th_dport)) // Unwritten rule, not sure
+ {
+ dir = PACKET_DIRECTION_C2S;
+ }
+ else
+ {
+ dir = PACKET_DIRECTION_S2C;
+ }
+ }
+
+ return dir;
+}
+
+static void hdgt_determine_packet_dir(struct fake_session *fses, struct fake_packet *fpkt, const struct tcphdr *th)
+{
+ if (SESSION_ADDR_TYPE_IPV4_TCP == fses->addr_type)
+ {
+ if (th->th_sport == fses->addr->ipv4.sport)
+ {
+ fpkt->dir = PACKET_DIRECTION_C2S;
+ }
+ else
+ {
+ fpkt->dir = PACKET_DIRECTION_S2C;
+ }
+ }
+ else
+ {
+ if (th->th_sport == fses->addr->ipv6.sport)
+ {
+ fpkt->dir = PACKET_DIRECTION_C2S;
+ }
+ else
+ {
+ fpkt->dir = PACKET_DIRECTION_S2C;
+ }
+ }
+}
+
+static void hdgt_update_packet_payload(struct fake_packet *fpkt, const struct tcphdr *th)
+{
+ // todo, support UDP?
+ fpkt->payload_data = (char *)th + th->th_off * 4;
+ fpkt->payload_data_len = fpkt->raw_pkt_data_len - ((char *)th - fpkt->raw_pkt_data) - (th->th_off * 4);
+ fpkt->payload_submit_offset = 0;
+}
+
+static int hdgt_update_packet_detail_by_pcap(struct fake_session *fses, struct fake_packet *fpkt)
+{
+ struct tcphdr *th = (struct tcphdr *)MESA_jump_layer_greedy(fpkt->raw_pkt_data, ADDR_TYPE_MAC, ADDR_TYPE_TCP);
+ if (NULL == th)
+ {
+ DEBUG_PRINT("Not found tcp header!\n");
+ return -1;
+ }
+
+ hdgt_determine_packet_dir(fses, fpkt, th);
+ hdgt_update_packet_payload(fpkt, th);
+ return 0;
+}
+
+static int hdgt_update_packet_detail(struct fake_session *fses, struct fake_packet *fpkt)
+{
+ int ret;
+ if (DATA_SOURCE_PCAP == fses->fst->data_source_type)
+ {
+ ret = hdgt_update_packet_detail_by_pcap(fses, fpkt);
+ }
+ else
+ {
+ ret = hdgt_update_packet_detail_by_json(fses->fst, fpkt);
+ }
+ return ret;
+}
+
+static struct session_addr *hgdt_get_session_addr_by_pcap(struct fake_session *fses, struct fake_packet *fpkt)
+{
+ if (fses->addr != NULL)
+ {
+ return fses->addr;
+ }
+
+ struct session_addr tmp_addr = {};
+ int innermost_l3_layer_type;
+
+ struct tcphdr *th = (struct tcphdr *)MESA_jump_layer_greedy(fpkt->raw_pkt_data, ADDR_TYPE_MAC, ADDR_TYPE_TCP);
+ if (NULL == th)
+ {
+ DEBUG_PRINT("Not found tcp header!\n");
+ // todo, support UDP ?
+ return NULL;
+ }
+ fpkt->l4_header = (char *)th;
+ struct ip *i4h = (struct ip *)MESA_jump_layer_greedy(fpkt->raw_pkt_data, ADDR_TYPE_MAC, ADDR_TYPE_IPV4);
+ struct ip6_hdr *i6h = (struct ip6_hdr *)MESA_jump_layer_greedy(fpkt->raw_pkt_data, ADDR_TYPE_MAC, ADDR_TYPE_IPV6);
+ if ((NULL == i6h) && (NULL == i4h))
+ {
+ DEBUG_PRINT("Not found ipv4 or ipv6 header!\n");
+ return NULL;
+ }
+
+ if (i4h && (NULL == i6h))
+ {
+ innermost_l3_layer_type = ADDR_TYPE_IPV4;
+ }
+ else if (i6h && (NULL == i4h))
+ {
+ innermost_l3_layer_type = ADDR_TYPE_IPV6;
+ }
+ else // both ipv4 and ipv6 exist, maybe 4over6, 6over4, gtp etc.
+ {
+ if ((char *)i4h - (char *)i6h > 0)
+ {
+ innermost_l3_layer_type = ADDR_TYPE_IPV4;
+ }
+ else
+ {
+ innermost_l3_layer_type = ADDR_TYPE_IPV6;
+ }
+ }
+
+ int cur_pkt_dir = hdgt_get_packet_dir_of_tcp(th);
+
+ if (ADDR_TYPE_IPV4 == innermost_l3_layer_type)
+ {
+ fses->addr_type = SESSION_ADDR_TYPE_IPV4_TCP;
+ if (PACKET_DIRECTION_C2S == cur_pkt_dir)
+ {
+
+ tmp_addr.ipv4.saddr = i4h->ip_src.s_addr;
+ tmp_addr.ipv4.daddr = i4h->ip_dst.s_addr;
+ tmp_addr.ipv4.sport = th->th_sport;
+ tmp_addr.ipv4.dport = th->th_dport;
+ }
+ else
+ {
+ tmp_addr.ipv4.saddr = i4h->ip_dst.s_addr;
+ tmp_addr.ipv4.daddr = i4h->ip_src.s_addr;
+ tmp_addr.ipv4.sport = th->th_dport;
+ tmp_addr.ipv4.dport = th->th_sport;
+ }
+ }
+ else
+ {
+ fses->addr_type = SESSION_ADDR_TYPE_IPV6_TCP;
+ if (PACKET_DIRECTION_C2S == cur_pkt_dir)
+ {
+ memcpy(tmp_addr.ipv6.saddr, i6h->ip6_src.s6_addr, IPV6_ADDR_LEN);
+ memcpy(tmp_addr.ipv6.daddr, i6h->ip6_dst.s6_addr, IPV6_ADDR_LEN);
+ tmp_addr.ipv6.sport = th->th_sport;
+ tmp_addr.ipv6.dport = th->th_dport;
+ }
+ else
+ {
+ memcpy(tmp_addr.ipv6.saddr, i6h->ip6_dst.s6_addr, IPV6_ADDR_LEN);
+ memcpy(tmp_addr.ipv6.daddr, i6h->ip6_src.s6_addr, IPV6_ADDR_LEN);
+ tmp_addr.ipv6.sport = th->th_dport;
+ tmp_addr.ipv6.dport = th->th_sport;
+ }
+ }
+
+ fses->addr = MMALLOC(struct session_addr, sizeof(struct session_addr));
+ memcpy(fses->addr, &tmp_addr, sizeof(struct session_addr));
+
+ return fses->addr;
+}
+
+/* example: "1.1.1.1.12345>2.2.2.2.80" */
+static void hdgt_json_session_adddr_pton_v4(struct session_addr *addr, const char *tuple4_cstr)
+{
+ const char *delim = ".>";
+ char *dup_str = strdup(tuple4_cstr);
+ char *sip1 = strtok(dup_str, delim);
+ char *sip2 = strtok(NULL, delim);
+ char *sip3 = strtok(NULL, delim);
+ char *sip4 = strtok(NULL, delim);
+ char *sport = strtok(NULL, delim);
+
+ char *dip1 = strtok(NULL, delim);
+ char *dip2 = strtok(NULL, delim);
+ char *dip3 = strtok(NULL, delim);
+ char *dip4 = strtok(NULL, delim);
+ char *dport = strtok(NULL, delim);
+
+ char sip_str[INET_ADDRSTRLEN] = {};
+ char dip_str[INET_ADDRSTRLEN] = {};
+ sprintf(sip_str, "%s.%s.%s.%s", sip1, sip2, sip3, sip4);
+ inet_pton(AF_INET, sip_str, &addr->ipv4.saddr);
+ sprintf(dip_str, "%s.%s.%s.%s", dip1, dip2, dip3, dip4);
+ inet_pton(AF_INET, dip_str, &addr->ipv4.daddr);
+ addr->ipv4.sport = htons(atoi(sport));
+ addr->ipv4.dport = htons(atoi(dport));
+}
+
+/* fe80::8c19:7aff:fef2:11e5.12345>fe80::8c19:7aff:fef2:11e5.80 */
+static void hdgt_json_session_adddr_pton_v6(struct session_addr *addr, const char *tuple4_cstr)
+{
+ char *dup_str = strdup(tuple4_cstr);
+ char *sip = dup_str;
+ char *ptr = strchr(dup_str, '.');
+ *ptr = '\0';
+ ptr++;
+ char *sport = ptr;
+ ptr = strchr(sport, '>');
+ *ptr = '\0';
+ ptr++;
+ char *dip = ptr;
+ ptr = strchr(dip, '.');
+ *ptr = '\0';
+ ptr++;
+ char *dport = ptr;
+
+ char sip_str[INET6_ADDRSTRLEN] = {};
+ char dip_str[INET6_ADDRSTRLEN] = {};
+ inet_pton(AF_INET6, sip, addr->ipv6.saddr);
+ inet_pton(AF_INET6, dip, addr->ipv6.daddr);
+ addr->ipv6.sport = htons(atoi(sport));
+ addr->ipv6.dport = htons(atoi(dport));
+}
+
+static void hdgt_json_session_adddr_pton(struct fake_session *fses, const char *tuple4_cstr)
+{
+ struct session_addr *addr = fses->addr;
+ if (strchr(tuple4_cstr, ':') != NULL)
+ {
+ hdgt_json_session_adddr_pton_v6(addr, tuple4_cstr);
+ fses->addr_type = SESSION_ADDR_TYPE_IPV6_TCP;
+ return;
+ }
+ else
+ {
+ hdgt_json_session_adddr_pton_v4(addr, tuple4_cstr);
+ fses->addr_type = SESSION_ADDR_TYPE_IPV4_TCP;
+ }
+}
+
+static struct session_addr *hgdt_get_session_addr_by_json(struct fake_session *fses, struct fake_packet *fpkt)
+{
+ if (fses->addr != NULL)
+ {
+ return fses->addr;
+ }
+
+ cJSON *tuple4_obj = cJSON_GetObjectItem(fses->fst->data_src_json_para.current_object, GTEST_HTTP_TUPLE4_NAME);
+ if (NULL == tuple4_obj)
+ {
+ return NULL;
+ }
+ fses->addr = MMALLOC(struct session_addr, sizeof(struct session_addr));
+ hdgt_json_session_adddr_pton(fses, tuple4_obj->valuestring);
+ return fses->addr;
+}
+
+static struct session_addr *hgdt_get_session_addr(struct fake_session *fses, struct fake_packet *fpkt)
+{
+ if (fses->fst->data_source_type == DATA_SOURCE_PCAP)
+ {
+ return hgdt_get_session_addr_by_pcap(fses, fpkt);
+ }
+ return hgdt_get_session_addr_by_json(fses, fpkt);
+}
+
+static void hdgt_session_update(struct fake_stellar *fst, struct fake_session *fses, int event)
+{
+ fst->http_decoder_entry((struct session *)fses, event, (struct packet *)fses->fpkt, fst->http_decoder_ctx);
+}
+
+static int hdgt_data_source_init(struct fake_stellar *fst)
+{
+ if (DATA_SOURCE_PCAP == fst->data_source_type)
+ {
+ char errbuf[PCAP_ERRBUF_SIZE];
+ fst->pcap_ins = pcap_open_offline(fst->data_source_file_name, errbuf);
+ if (NULL == fst->pcap_ins)
+ {
+ fprintf(stderr, "pcap_open_offline() fail: %s\n", errbuf);
+ return -1;
+ }
+ }
+ else if (DATA_SOURCE_JSON == fst->data_source_type)
+ {
+ char *file_cont = hdgt_get_file_content(fst->data_source_file_name);
+ if (NULL == file_cont)
+ {
+ fprintf(stderr, "Open json file fail: %s\n", fst->data_source_file_name);
+ return -1;
+ }
+ fst->data_src_json_para.json_root = cJSON_Parse(file_cont);
+ if (NULL == fst->data_src_json_para.json_root)
+ {
+ fprintf(stderr, "cJSON_Parse() %s fail!\n", fst->data_source_file_name);
+ MFREE(file_cont);
+ return -1;
+ }
+ fst->data_src_json_para.json_array_size = cJSON_GetArraySize(fst->data_src_json_para.json_root);
+ fst->data_src_json_para.current_json_array_idx = 0;
+ MFREE(file_cont);
+ }
+ else
+ {
+ DEBUG_PRINT("Invalid data source type!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int hdgt_benchmakr_json_parse(struct fake_stellar *fst)
+{
+ char *file_cont = hdgt_get_file_content(fst->benchmark_json_file_name);
+ if (NULL == file_cont)
+ {
+ fprintf(stderr, "Open json file fail: %s\n", fst->benchmark_json_file_name);
+ return -1;
+ }
+ fst->load_benchmark_json_root = cJSON_Parse(file_cont);
+ if (NULL == fst->load_benchmark_json_root)
+ {
+ fprintf(stderr, "cJSON_Parse() %s fail!\n", fst->benchmark_json_file_name);
+ MFREE(file_cont);
+ return -1;
+ }
+ fst->http_plug_test_result_root = cJSON_CreateArray();
+ MFREE(file_cont);
+ return 0;
+}
+
+static int hdgt_under_test_module_init(struct fake_stellar *fst)
+{
+ fst->http_decoder_ctx = http_decoder_init((struct stellar *)fst);
+ fst->http_decoder_entry = http_decoder_entry;
+
+ return 0;
+}
+
+static int hdgt_test_plug_init(struct fake_stellar *fst)
+{
+ fst->http_http_plug_ctx = http_decoder_test_init((struct stellar *)fst);
+ return 0;
+}
+
+static struct fake_stellar *hdgt_init(int argc, char **argv)
+{
+ struct fake_stellar *fst = MMALLOC(struct fake_stellar, sizeof(struct fake_stellar));
+
+ if (hdgt_parse_cmd_args(fst, argc, argv) < 0)
+ {
+ fprintf(stderr, "hdgt_parse_cmd_args() fail!\n");
+ goto fail_exit;
+ }
+ if (hdgt_data_source_init(fst) < 0)
+ {
+ fprintf(stderr, "hdgt_data_source_init() fail!\n");
+ goto fail_exit;
+ }
+ if (hdgt_benchmakr_json_parse(fst) < 0)
+ {
+ fprintf(stderr, "hdgt_benchmakr_json_parse() fail!\n");
+ goto fail_exit;
+ }
+ if (hdgt_under_test_module_init(fst) < 0)
+ {
+ fprintf(stderr, "hdgt_under_test_module_init() fail!\n");
+ goto fail_exit;
+ }
+ if (hdgt_test_plug_init(fst) < 0)
+ {
+ fprintf(stderr, "hdgt_test_plug_init() fail!\n");
+ goto fail_exit;
+ }
+
+ g_fake_stellar = fst;
+ return fst;
+
+fail_exit:
+ MFREE(fst);
+ return NULL;
+}
+
+static void hdgt_exit(struct fake_stellar *fst)
+{
+ cJSON_free(fst->load_benchmark_json_root);
+ cJSON_free(fst->http_plug_test_result_root);
+ if (fst->data_src_json_para.json_root)
+ {
+ cJSON_free(fst->data_src_json_para.json_root);
+ }
+ if (fst->pcap_ins)
+ {
+ pcap_close(fst->pcap_ins);
+ }
+
+ MFREE(fst);
+ return;
+}
+
+static void hdgt_session_free(struct fake_session *fses)
+{
+ const struct fake_exdata_manage *ex_mgr = fses->fst->fake_exdata_mgr;
+
+ for (int i = 0; i < EX_DATA_MAX_SIZE; i++)
+ {
+ if (fses->plug_exdata_array[i] != NULL)
+ {
+ ex_mgr[i].free_func((struct session *)fses, i, fses->plug_exdata_array[i], ex_mgr[i].arg);
+ }
+ }
+
+ if (fses->readable_addr_cstr)
+ {
+ MFREE(fses->readable_addr_cstr);
+ }
+
+ if (fses->addr)
+ {
+ MFREE(fses->addr);
+ }
+
+ MFREE(fses);
+}
+
+static void hdgt_main_loop(struct fake_stellar *fst)
+{
+ struct fake_packet __null_pkt = {};
+ struct fake_packet fpkt = {};
+ struct fake_session *fses = hdgt_session_new(fst);
+
+ fses->fpkt = &__null_pkt;
+ hdgt_session_update(fst, fses, SESS_EV_OPENING);
+
+ fses->fpkt = &fpkt;
+ while (hdgt_get_packet(fst, &fpkt) == 1)
+ {
+ if (NULL == hgdt_get_session_addr(fses, &fpkt))
+ {
+ continue; // not tcp, not ip
+ }
+ if (hdgt_update_packet_detail(fses, &fpkt) < 0)
+ {
+ continue;
+ }
+ while (hdgt_has_data_left(&fpkt))
+ {
+ hdgt_session_update(fst, fses, SESS_EV_PACKET);
+ }
+ }
+
+ fses->fpkt = &__null_pkt;
+ hdgt_session_update(fst, fses, SESS_EV_CLOSING);
+
+ hdgt_session_free(fses);
+}
+
+TEST(HTTP_DECODER, GTEST)
+{
+ ASSERT_EQ(0, hdgt_compare_result(g_fake_stellar));
+}
+
+int main(int argc, char **argv)
+{
+ struct fake_stellar *fake_st = hdgt_init(argc, argv);
+ if (NULL == fake_st)
+ {
+ fprintf(stderr, "hdgt_init() fail!\n");
+ exit(1);
+ }
+
+ hdgt_main_loop(fake_st);
+
+ ::testing::InitGoogleTest(&argc, argv);
+ int ret = RUN_ALL_TESTS();
+
+ hdgt_exit(fake_st);
+
+ return ret;
+}
diff --git a/test/http_decoder_gtest.cpp b/test/http_decoder_gtest.cpp
new file mode 100644
index 0000000..aa81df2
--- /dev/null
+++ b/test/http_decoder_gtest.cpp
@@ -0,0 +1,370 @@
+/*
+**********************************************************************************************
+* File: http_decoder_gtest.cpp
+* Description:
+* Authors: Liu WenTan <[email protected]>
+* Date: 2023-12-15
+* Copyright: (c) Since 2023 Geedge Networks, Ltd. All rights reserved.
+***********************************************************************************************
+*/
+
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+
+#include "../include/http_decoder.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+
+#include "cJSON.h"
+#include "http_decoder_gtest.h"
+#include "stellar/utils.h"
+#include "stellar/stellar.h"
+#include "stellar/session_exdata.h"
+#include "stellar/session_mq.h"
+
+ int commit_test_result_json(cJSON *node, const char *name);
+}
+#endif
+
+#define MAX_KEY_STR_LEN 2048
+
+enum http_transaction_type
+{
+ HTTP_TRANSACTION_REQ = 0,
+ HTTP_TRANSACTION_RES,
+ HTTP_TRANSACTION_SESSION,
+ HTTP_TRANSACTION_MAX
+};
+
+struct gtest_plug_exdata_t
+{
+ cJSON *result_jnode[HTTP_TRANSACTION_MAX];
+};
+
+static int g_result_count = 0;
+static int g_header_count = 1;
+static int g_exdata_idx = 0;
+static int g_topic_id = 0;
+
+#if 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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.str, header->key.str_len);
+ memcpy(tmp_val, header->val.str, header->val.str_len);
+ printf("<%s:%s>\n", tmp_key, tmp_val);
+}
+#endif
+
+void output_http_body(struct hstring *body, int decompress_flag)
+{
+ int counter = 0;
+
+ if (1 == decompress_flag)
+ {
+ printf("\n\n----------------decompress body len:%zu---------------\n",
+ body->str_len);
+ }
+ else
+ {
+ printf("\n\n----------------raw body len:%zu---------------\n",
+ body->str_len);
+ }
+
+ for (size_t i = 0; i < body->str_len; i++)
+ {
+ if (counter % 16 == 0)
+ {
+ printf("\n");
+ }
+ printf("%02x ", (unsigned char)body->str[i]);
+ counter++;
+ }
+ printf("\n");
+}
+
+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 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);
+
+ 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", 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);
+
+ 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};
+
+ memcpy(key, header->key.str, header->key.str_len);
+
+ if (cJSON_HasObjectItem(ctx, key) == FALSE)
+ {
+ http_field_to_json(ctx, key, header->val.str, header->val.str_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);
+ }
+}
+
+void http_url_add_to_json(cJSON *ctx, struct http_message *msg)
+{
+ struct hstring url_result = {};
+
+ if (cJSON_GetObjectItem(ctx, GTEST_HTTP_URL_NAME))
+ {
+ return;
+ }
+
+ if (http_message_get_url(msg, &url_result) < 0)
+ {
+ // printf("url:%s\n", url_result.str);
+ 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.val = url_result;
+
+ http_header_to_json(ctx, &url_header_result);
+}
+
+// Full duplex
+static void commit_last_half_flow_data(struct session *sess, struct gtest_plug_exdata_t *gtest_plug_exdata, enum http_transaction_type type)
+{
+ char result_name[MAX_KEY_STR_LEN] = {0};
+
+ cJSON *last_jnode = gtest_plug_exdata->result_jnode[type];
+ if (last_jnode)
+ {
+ 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++;
+ }
+
+ 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");
+ }
+}
+
+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)
+ {
+ 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, session_get0_readable_addr(sess));
+ sprintf(result_name, "%d", g_result_count++);
+ commit_test_result_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION], result_name);
+ }
+}
+
+extern "C" int
+http_decoder_test_entry(struct session *sess, int topic_id, const void *data,
+ void *cb_arg)
+{
+ struct http_request_line req_line = {0};
+ struct http_response_line res_line = {0};
+ struct http_header header = {0};
+ struct hstring body = {0};
+ struct http_message *msg = (struct http_message *)data;
+ enum http_message_type msg_type = http_message_type(msg);
+
+ struct gtest_plug_exdata_t *gtest_plug_exdata = (struct gtest_plug_exdata_t *)session_get_ex_data(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_set_ex_data(sess, g_exdata_idx, gtest_plug_exdata);
+ }
+
+ if (msg_type == HTTP_MESSAGE_REQ_LINE || msg_type == HTTP_MESSAGE_REQ_HEADER || msg_type == HTTP_MESSAGE_REQ_BODY)
+ {
+ 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(sess, gtest_plug_exdata, HTTP_TRANSACTION_REQ);
+ http_message_get_request_line(msg, &req_line);
+ req_line_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], &req_line);
+ break;
+ case HTTP_MESSAGE_REQ_HEADER:
+ while (http_message_request_header_next(msg, &header) > 0)
+ {
+ http_header_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], &header);
+ }
+ g_header_count = 1;
+ http_url_add_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ], msg);
+ break;
+ case HTTP_MESSAGE_REQ_BODY:
+ http_message_get_request_raw_body(msg, &body);
+ // output_http_body(&body, 0);
+
+ http_message_get_request_decompress_body(msg, &body);
+ // output_http_body(&body, 1);
+ break;
+ case HTTP_MESSAGE_RES_LINE:
+ commit_last_half_flow_data(sess, gtest_plug_exdata, HTTP_TRANSACTION_RES);
+ http_message_get_response_line(msg, &res_line);
+ res_line_to_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES], &res_line);
+ break;
+ case HTTP_MESSAGE_RES_HEADER:
+ while (http_message_response_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:
+ http_message_get_response_raw_body(msg, &body);
+ // output_http_body(&body, 0);
+
+ http_message_get_response_decompress_body(msg, &body);
+ // output_http_body(&body, 1);
+ break;
+
+ // to do: check payload
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void http_decoder_test_exdata_free(struct session *sess, int idx, void *ex_ptr,
+ 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(sess, gtest_plug_exdata, HTTP_TRANSACTION_REQ);
+ }
+ if (gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES])
+ {
+ commit_last_half_flow_data(sess, gtest_plug_exdata, HTTP_TRANSACTION_RES);
+ }
+ free(ex_ptr);
+ }
+}
+
+extern "C" void *http_decoder_test_init(struct stellar *st)
+{
+ g_exdata_idx =
+ stellar_session_get_ex_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 = session_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);
+ }
+
+ session_mq_subscribe_topic(st, g_topic_id, http_decoder_test_entry, NULL);
+ printf("http_decoder_test_init OK!\n");
+
+ return NULL;
+}
+
+extern "C" void http_decoder_test_exit(void *test_ctx)
+{
+ if (test_ctx != NULL)
+ {
+ FREE(test_ctx);
+ }
+
+ printf("http_decoder_test_exit OK!\n");
+} \ No newline at end of file
diff --git a/test/http_decoder_gtest.h b/test/http_decoder_gtest.h
new file mode 100644
index 0000000..46b0c43
--- /dev/null
+++ b/test/http_decoder_gtest.h
@@ -0,0 +1,114 @@
+#pragma once
+
+#include "http_decoder.h"
+#include "session.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)
+
+#define MAX(a, b) ((a) >= (b) ? (a) : (b))
+#define MIN(a, b) ((a) >= (b) ? (b) : (a))
+
+#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 KEY_NAME_REQ_LINE "__REQ_LINE__"
+#define KEY_NAME_RES_LINE "__RES_LINE__"
+#define KEY_NAME_REQ_URL "__REQ_URL__"
+#define KEY_NAME_PAYLOAD_MD5 "__PAYLOAD_MD5__"
+
+#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_TUPLE4_NAME "__X_HTTP_TUPLE4"
+
+struct fake_exdata_manage
+{
+ char *name;
+ int name_len;
+ void *arg;
+ void (*free_func)(struct session *sess, int idx, void *ex_ptr, void *arg);
+};
+
+struct fake_packet
+{
+ int dir;
+ size_t raw_pkt_data_len;
+ const char *raw_pkt_data; // referred to packet Ethernet MAC header
+ const char *l4_header; // referred to TCP, UDP header
+ size_t payload_data_len;
+ const char *payload_data; // referred to L7 data, such as HTTP, DNS, etc.
+ size_t payload_submit_offset;
+};
+
+enum data_source_type_t
+{
+ __DATA_SOURCE_NULL = 0,
+ DATA_SOURCE_PCAP,
+ DATA_SOURCE_JSON,
+ __DATA_SOURCE_MAX
+};
+
+struct data_src_json_para_t
+{
+ cJSON *json_root;
+ cJSON *current_object;
+ int json_array_size;
+ int current_json_array_idx;
+ char key_value_buf[JSON_KEY_VALUE_STRING_MAX_LEN];
+};
+
+struct fake_stellar
+{
+ struct fake_exdata_manage fake_exdata_mgr[EX_DATA_MAX_SIZE];
+ int tcp_mss;
+ void *http_decoder_ctx;
+ void *http_http_plug_ctx;
+ int (*http_decoder_entry)(struct session *sess, int events,
+ const struct packet *pkt, void *cb_arg);
+ cJSON *http_plug_test_result_root;
+ enum data_source_type_t data_source_type;
+ const char *benchmark_json_file_name;
+ const char *data_source_file_name;
+ cJSON *load_benchmark_json_root;
+ pcap_t *pcap_ins;
+
+ struct data_src_json_para_t data_src_json_para;
+};
+
+struct fake_session
+{
+ enum session_type type;
+ struct fake_stellar *fst;
+ struct fake_packet *fpkt;
+ int events;
+ int tcp_mss;
+ enum session_addr_type addr_type;
+ struct session_addr *addr;
+ char *readable_addr_cstr;
+ void *plug_exdata_array[EX_DATA_MAX_SIZE];
+};
diff --git a/test/http_decoder_stub.cpp b/test/http_decoder_stub.cpp
new file mode 100644
index 0000000..c879630
--- /dev/null
+++ b/test/http_decoder_stub.cpp
@@ -0,0 +1,250 @@
+/*
+ Http Decoder Google Test stub module
+*/
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include "http_decoder.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "session.h"
+#include "session_exdata.h"
+#include "session_mq.h"
+#include "stellar.h"
+#include "http_decoder_gtest.h"
+#include "MESA_jump_layer.h"
+
+ static int g_topic_id = -1;
+ static msg_free_cb_func *g_msg_free_cb = NULL;
+ static void *g_msg_free_cb_arg = NULL;
+
+ extern struct fake_stellar *g_fake_stellar;
+
+ int commit_test_result_json(cJSON *node, const char *name)
+ {
+ assert(node != NULL || name != NULL);
+ if (g_fake_stellar->http_plug_test_result_root)
+ {
+ cJSON_AddStringToObject(node, "__X_HTTP_RESULT_INDEX", name);
+ cJSON_AddItemToArray(g_fake_stellar->http_plug_test_result_root, node);
+ return 0;
+ }
+ return -1;
+ }
+
+ int packet_get_direction(const struct packet *pkt)
+ {
+ struct fake_packet *fpkt = (struct fake_packet *)pkt;
+ return fpkt->dir;
+ }
+
+ int session_event_assign(struct session_event *ev, struct stellar *st, struct session *sess, int events, session_event_cb_func *cb, void *cb_arg)
+ {
+ DEBUG_PRINT("todo: fake session_event_assign()\n");
+ return 0;
+ }
+
+ const char *session_get0_readable_addr(struct session *sess)
+ {
+ struct fake_session *fses = (struct fake_session *)sess;
+
+ if (fses->readable_addr_cstr)
+ {
+ return fses->readable_addr_cstr;
+ }
+
+ char ip_src_buf[INET6_ADDRSTRLEN] = {};
+ char ip_dst_buf[INET6_ADDRSTRLEN] = {};
+ char port_src_buf[16] = {};
+ char port_dst_buf[16] = {};
+ char tuple4_buf[256] = {};
+
+ if (SESSION_ADDR_TYPE_IPV4_TCP == fses->addr_type)
+ {
+ inet_ntop(AF_INET, &fses->addr->ipv4.saddr, ip_src_buf, INET_ADDRSTRLEN);
+ inet_ntop(AF_INET, &fses->addr->ipv4.daddr, ip_dst_buf, INET_ADDRSTRLEN);
+ sprintf(port_src_buf, "%u", ntohs(fses->addr->ipv4.sport));
+ sprintf(port_dst_buf, "%u", ntohs(fses->addr->ipv4.dport));
+ }
+ else
+ {
+ inet_ntop(AF_INET6, fses->addr->ipv6.saddr, ip_src_buf, INET6_ADDRSTRLEN);
+ inet_ntop(AF_INET6, fses->addr->ipv6.daddr, ip_dst_buf, INET6_ADDRSTRLEN);
+ sprintf(port_src_buf, "%u", ntohs(fses->addr->ipv6.sport));
+ sprintf(port_dst_buf, "%u", ntohs(fses->addr->ipv6.dport));
+ }
+
+ snprintf(tuple4_buf, sizeof(tuple4_buf), "%s.%s>%s.%s", ip_src_buf, port_src_buf, ip_dst_buf, port_dst_buf);
+ fses->readable_addr_cstr = MMALLOC(char, strlen(tuple4_buf) + 1);
+ memcpy(fses->readable_addr_cstr, tuple4_buf, strlen(tuple4_buf));
+
+ return fses->readable_addr_cstr;
+ }
+
+ struct session_addr *session_get0_addr(struct session *sess, enum session_addr_type *addr_type)
+ {
+ struct fake_session *fses = (struct fake_session *)sess;
+ *addr_type = fses->addr_type;
+ return fses->addr;
+ }
+
+ static int __find_ex_data(struct fake_stellar *fst, const char *name)
+ {
+ int find_name_len = strlen(name);
+
+ for (int i = 0; i < EX_DATA_MAX_SIZE; i++)
+ {
+ if ((fst->fake_exdata_mgr[i].name != NULL) && (strncasecmp(name, fst->fake_exdata_mgr[i].name, find_name_len) == 0) && (find_name_len == fst->fake_exdata_mgr[i].name_len))
+ {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ static int __save_ex_data(struct fake_stellar *fst, const char *name, session_ex_free *free_func, void *arg)
+ {
+ for (int i = 0; i < EX_DATA_MAX_SIZE; i++)
+ {
+ if (fst->fake_exdata_mgr[i].name == NULL && fst->fake_exdata_mgr[i].name_len == 0)
+ {
+ fst->fake_exdata_mgr[i].name = MMALLOC(char, strlen(name) + 1);
+ fst->fake_exdata_mgr[i].name_len = strlen(name) + 1;
+ memcpy(fst->fake_exdata_mgr[i].name, name, strlen(name));
+ fst->fake_exdata_mgr[i].free_func = free_func;
+ fst->fake_exdata_mgr[i].arg = arg;
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ int stellar_session_get_ex_new_index(struct stellar *st, const char *name, session_ex_free *free_func, void *arg)
+ {
+ int ex_id = __find_ex_data((struct fake_stellar *)st, name);
+ if (-1 == ex_id)
+ {
+ ex_id = __save_ex_data((struct fake_stellar *)st, name, free_func, arg);
+ }
+
+ return ex_id;
+ }
+
+ int session_mq_get_topic_id(struct stellar *st, const char *topic_name)
+ {
+ return g_topic_id;
+ }
+
+ int session_get_current_thread_id(struct session *sess)
+ {
+ return 0;
+ }
+
+ int session_mq_destroy_topic(struct stellar *st, int topic_id)
+ {
+ return 0;
+ }
+
+ int session_set_ex_data(struct session *sess, int idx, void *ex_ptr)
+ {
+ struct fake_session *fses = (struct fake_session *)sess;
+ fses->plug_exdata_array[idx] = ex_ptr;
+
+ return 0;
+ }
+
+ void *session_get_ex_data(struct session *sess, int idx)
+ {
+ struct fake_session *fses = (struct fake_session *)sess;
+ return fses->plug_exdata_array[idx];
+ }
+
+ void hdd_session_free_exdata(struct fake_session *fake_ses)
+ {
+ for (int i = 0; i < EX_DATA_MAX_SIZE; i++)
+ {
+ if (fake_ses->plug_exdata_array[i] != NULL)
+ {
+ fake_ses->fst->fake_exdata_mgr[i].free_func((struct session *)fake_ses, i, fake_ses->plug_exdata_array[i], NULL);
+ }
+ }
+ }
+
+ int stellar_plugin_register(struct stellar *st, int events, session_event_cb_func *cb, void *cb_arg)
+ {
+ return 0; // fix plugin id
+ }
+
+ extern int http_decoder_test_entry(struct session *sess, int topic_id, const void *data, void *cb_arg);
+ int session_mq_publish_message(struct session *sess, int topic_id, void *data)
+ {
+ http_decoder_test_entry(sess, topic_id, data, NULL);
+
+ g_msg_free_cb(data, g_msg_free_cb_arg);
+ return 0;
+ }
+
+ int stellar_get_worker_thread_num(struct stellar *st)
+ {
+ return 1;
+ }
+
+ int session_mq_create_topic(struct stellar *st, const char *topic_name, msg_free_cb_func *free_cb, void *cb_arg)
+ {
+ g_msg_free_cb = free_cb;
+ g_msg_free_cb_arg = cb_arg;
+
+ g_topic_id = 0; // KISS, use fix value
+ return g_topic_id;
+ }
+
+ const char *session_get0_current_payload(struct session *sess, size_t *payload_len)
+ {
+ struct fake_session *fses = (struct fake_session *)sess;
+ struct fake_packet *fpkt = fses->fpkt;
+ const char *payload_ptr = NULL;
+
+ if (!fpkt || !fpkt->payload_data || fpkt->payload_data_len == 0)
+ {
+ return NULL;
+ }
+
+ int submit_len = MIN(fses->tcp_mss, fpkt->payload_data_len - fpkt->payload_submit_offset);
+ if(submit_len <= 0)
+ {
+ *payload_len = 0;
+ return NULL;
+ }
+ payload_ptr = fpkt->payload_data + fpkt->payload_submit_offset;
+ *payload_len = submit_len;
+ fpkt->payload_submit_offset += submit_len;
+
+ return payload_ptr;
+ }
+
+ struct session_event *session_get_intrinsic_event(struct session *sess, int plugin_id)
+ {
+ return NULL;
+ }
+
+ int session_is_inner_most(struct session *sess, uint64_t *flag)
+ {
+ return 1; // no tunnel
+ }
+
+ int session_mq_subscribe_topic(struct stellar *st, int topic_id, on_msg_cb_func *sub_cb, void *cb_arg)
+ {
+ // to do
+ return 0;
+ }
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/test/http_pcap/http_6over4_single_trans.pcap b/test/http_pcap/http_6over4_single_trans.pcap
new file mode 100644
index 0000000..6b074e5
--- /dev/null
+++ b/test/http_pcap/http_6over4_single_trans.pcap
Binary files differ
diff --git a/test/http_pcap/http_chunked_res_gzip.pcap b/test/http_pcap/http_chunked_res_gzip.pcap
new file mode 100644
index 0000000..fa237fb
--- /dev/null
+++ b/test/http_pcap/http_chunked_res_gzip.pcap
Binary files differ
diff --git a/test/http_pcap/http_connect_flood.pcap b/test/http_pcap/http_connect_flood.pcap
new file mode 100644
index 0000000..11b7e14
--- /dev/null
+++ b/test/http_pcap/http_connect_flood.pcap
Binary files differ
diff --git a/test/http_pcap/http_get_encoded_uri.pcap b/test/http_pcap/http_get_encoded_uri.pcap
new file mode 100644
index 0000000..633b50b
--- /dev/null
+++ b/test/http_pcap/http_get_encoded_uri.pcap
Binary files differ
diff --git a/test/http_pcap/http_get_long_cookie.pcap b/test/http_pcap/http_get_long_cookie.pcap
new file mode 100644
index 0000000..8857615
--- /dev/null
+++ b/test/http_pcap/http_get_long_cookie.pcap
Binary files differ
diff --git a/test/http_pcap/http_get_malformed.pcap b/test/http_pcap/http_get_malformed.pcap
new file mode 100644
index 0000000..08deaeb
--- /dev/null
+++ b/test/http_pcap/http_get_malformed.pcap
Binary files differ
diff --git a/test/http_pcap/http_get_multi_trans.pcap b/test/http_pcap/http_get_multi_trans.pcap
new file mode 100644
index 0000000..9c0d2e7
--- /dev/null
+++ b/test/http_pcap/http_get_multi_trans.pcap
Binary files differ
diff --git a/test/http_pcap/http_get_req_pipeline.pcap b/test/http_pcap/http_get_req_pipeline.pcap
new file mode 100644
index 0000000..f805493
--- /dev/null
+++ b/test/http_pcap/http_get_req_pipeline.pcap
Binary files differ
diff --git a/test/http_pcap/http_get_single_trans.pcap b/test/http_pcap/http_get_single_trans.pcap
new file mode 100644
index 0000000..a4b6bea
--- /dev/null
+++ b/test/http_pcap/http_get_single_trans.pcap
Binary files differ
diff --git a/test/http_pcap/http_hdr_truncated_after_kv.pcap b/test/http_pcap/http_hdr_truncated_after_kv.pcap
new file mode 100644
index 0000000..de9f018
--- /dev/null
+++ b/test/http_pcap/http_hdr_truncated_after_kv.pcap
Binary files differ
diff --git a/test/http_pcap/http_hdr_truncated_in_kv.pcap b/test/http_pcap/http_hdr_truncated_in_kv.pcap
new file mode 100644
index 0000000..b4015c9
--- /dev/null
+++ b/test/http_pcap/http_hdr_truncated_in_kv.pcap
Binary files differ
diff --git a/test/http_pcap/http_hdr_value_empty.pcap b/test/http_pcap/http_hdr_value_empty.pcap
new file mode 100644
index 0000000..bb22243
--- /dev/null
+++ b/test/http_pcap/http_hdr_value_empty.pcap
Binary files differ
diff --git a/test/http_pcap/http_hdrs_exceed_maximum.pcap b/test/http_pcap/http_hdrs_exceed_maximum.pcap
new file mode 100644
index 0000000..537bffa
--- /dev/null
+++ b/test/http_pcap/http_hdrs_exceed_maximum.pcap
Binary files differ
diff --git a/test/http_pcap/http_multi_parse_error.pcap b/test/http_pcap/http_multi_parse_error.pcap
new file mode 100644
index 0000000..b57e275
--- /dev/null
+++ b/test/http_pcap/http_multi_parse_error.pcap
Binary files differ
diff --git a/test/http_pcap/http_no_content_length.pcap b/test/http_pcap/http_no_content_length.pcap
new file mode 100644
index 0000000..28e6881
--- /dev/null
+++ b/test/http_pcap/http_no_content_length.pcap
Binary files differ
diff --git a/test/http_pcap/http_over_pppoe.pcap b/test/http_pcap/http_over_pppoe.pcap
new file mode 100644
index 0000000..a6587cb
--- /dev/null
+++ b/test/http_pcap/http_over_pppoe.pcap
Binary files differ
diff --git a/test/http_pcap/http_over_tcp_keepalive.pcap b/test/http_pcap/http_over_tcp_keepalive.pcap
new file mode 100644
index 0000000..5b2db18
--- /dev/null
+++ b/test/http_pcap/http_over_tcp_keepalive.pcap
Binary files differ
diff --git a/test/http_pcap/http_over_tls.pcap b/test/http_pcap/http_over_tls.pcap
new file mode 100644
index 0000000..71c557e
--- /dev/null
+++ b/test/http_pcap/http_over_tls.pcap
Binary files differ
diff --git a/test/http_pcap/http_post_multipart_form_data.pcap b/test/http_pcap/http_post_multipart_form_data.pcap
new file mode 100644
index 0000000..052d326
--- /dev/null
+++ b/test/http_pcap/http_post_multipart_form_data.pcap
Binary files differ
diff --git a/test/http_pcap/http_req_1byte_sliding_window.pcap b/test/http_pcap/http_req_1byte_sliding_window.pcap
new file mode 100644
index 0000000..632c676
--- /dev/null
+++ b/test/http_pcap/http_req_1byte_sliding_window.pcap
Binary files differ
diff --git a/test/http_pcap/http_res_1byte_sliding_window.pcap b/test/http_pcap/http_res_1byte_sliding_window.pcap
new file mode 100644
index 0000000..6d1d6a4
--- /dev/null
+++ b/test/http_pcap/http_res_1byte_sliding_window.pcap
Binary files differ
diff --git a/test/http_pcap/http_res_gzip.pcap b/test/http_pcap/http_res_gzip.pcap
new file mode 100644
index 0000000..04b9998
--- /dev/null
+++ b/test/http_pcap/http_res_gzip.pcap
Binary files differ
diff --git a/test/http_pcap/http_trans_pipeline.pcap b/test/http_pcap/http_trans_pipeline.pcap
new file mode 100644
index 0000000..43438e1
--- /dev/null
+++ b/test/http_pcap/http_trans_pipeline.pcap
Binary files differ
diff --git a/test/http_pcap/http_tunnel_for_pop3.pcap b/test/http_pcap/http_tunnel_for_pop3.pcap
new file mode 100644
index 0000000..6df9669
--- /dev/null
+++ b/test/http_pcap/http_tunnel_for_pop3.pcap
Binary files differ
diff --git a/test/http_pcap/http_upgrade_http2.pcap b/test/http_pcap/http_upgrade_http2.pcap
new file mode 100644
index 0000000..a77847a
--- /dev/null
+++ b/test/http_pcap/http_upgrade_http2.pcap
Binary files differ
diff --git a/test/http_pcap/http_upgrade_websocket.pcap b/test/http_pcap/http_upgrade_websocket.pcap
new file mode 100644
index 0000000..b823d7e
--- /dev/null
+++ b/test/http_pcap/http_upgrade_websocket.pcap
Binary files differ
diff --git a/test/http_pcap/http_url_test_with_host.pcap b/test/http_pcap/http_url_test_with_host.pcap
new file mode 100644
index 0000000..8a57c4a
--- /dev/null
+++ b/test/http_pcap/http_url_test_with_host.pcap
Binary files differ
diff --git a/test/http_pcap/http_url_test_without_host.pcap b/test/http_pcap/http_url_test_without_host.pcap
new file mode 100644
index 0000000..0036379
--- /dev/null
+++ b/test/http_pcap/http_url_test_without_host.pcap
Binary files differ
diff --git a/test/http_pcap/non_http.pcap b/test/http_pcap/non_http.pcap
new file mode 100644
index 0000000..931b43b
--- /dev/null
+++ b/test/http_pcap/non_http.pcap
Binary files differ
diff --git a/test/md5.c b/test/md5.c
new file mode 100644
index 0000000..13a5d16
--- /dev/null
+++ b/test/md5.c
@@ -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(result, &context);
+
+ return result;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test/md5.h b/test/md5.h
new file mode 100644
index 0000000..9f5b5d2
--- /dev/null
+++ b/test/md5.h
@@ -0,0 +1,70 @@
+/* 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;
+
+void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+
+#ifdef __cplusplus
+extern "C"
+{
+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
diff --git a/test/test_env/conflist.inf b/test/test_env/conflist.inf
new file mode 100644
index 0000000..2e8144d
--- /dev/null
+++ b/test/test_env/conflist.inf
@@ -0,0 +1,9 @@
+[platform]
+./plug/stellar_on_sapp/start_loader.inf
+
+
+[protocol]
+
+
+[business]
+#./plug/stellar_on_sapp/defer_loader.inf
diff --git a/test/test_env/sapp4.el8.x86_64.rpm b/test/test_env/sapp4.el8.x86_64.rpm
new file mode 100644
index 0000000..e43fe2f
--- /dev/null
+++ b/test/test_env/sapp4.el8.x86_64.rpm
Binary files differ
diff --git a/test/test_env/spec.toml b/test/test_env/spec.toml
new file mode 100644
index 0000000..b8c7eb9
--- /dev/null
+++ b/test/test_env/spec.toml
@@ -0,0 +1,11 @@
+# stellar_plugin.toml
+#
+[[plugin]]
+path = "./stellar_plugin/http_decoder.so"
+init = "http_decoder_init"
+exit = "http_decoder_exit"
+
+[[plugin]]
+path = "./stellar_plugin/http_decoder_test.so"
+init = "http_decoder_test_init"
+exit = "http_decoder_test_exit" \ No newline at end of file
diff --git a/test/test_env/start_loader.inf b/test/test_env/start_loader.inf
new file mode 100644
index 0000000..89b2f94
--- /dev/null
+++ b/test/test_env/start_loader.inf
@@ -0,0 +1,17 @@
+[PLUGINFO]
+PLUGNAME=stellar_start_loader
+SO_PATH=./plug/stellar_on_sapp/stellar_on_sapp.so
+INIT_FUNC=STELLAR_START_LOADER_INIT
+DESTROY_FUNC=STELLAR_START_LOADER_EXIT
+
+#[TCP_ALL]
+#FUNC_FLAG=ALL
+#FUNC_NAME=stellar_on_sapp_tcpall_entry
+
+[TCP]
+FUNC_FLAG=ALL
+FUNC_NAME=stellar_on_sapp_tcp_entry
+
+[UDP]
+FUNC_FLAG=ALL
+FUNC_NAME=stellar_on_sapp_udp_entry \ No newline at end of file
diff --git a/test/test_env/tsg_l7_protocol.conf b/test/test_env/tsg_l7_protocol.conf
new file mode 100644
index 0000000..1075a8f
--- /dev/null
+++ b/test/test_env/tsg_l7_protocol.conf
@@ -0,0 +1,57 @@
+#TYPE:1:UCHAR,2:USHORT,3:USTRING,4:ULOG,5:USTRING,6:FILE,7:UBASE64,8:PACKET
+#TYPE FIELD VALUE
+STRING UNCATEGORIZED 8000
+#STRING UNCATEGORIZED 8001
+#STRING UNKNOWN_OTHER 8002
+STRING DNS 32
+STRING FTP 45
+STRING FTPS 751
+STRING HTTP 67
+STRING HTTPS 68
+STRING ICMP 70
+STRING IKE 8003
+STRING MAIL 8004
+STRING IMAP 75
+STRING IMAPS 76
+STRING IPSEC 85
+STRING XMPP 94
+STRING L2TP 98
+STRING NTP 137
+STRING POP3 147
+STRING POP3S 148
+STRING PPTP 153
+STRING QUIC 2521
+STRING SIP 182
+STRING SMB 185
+STRING SMTP 186
+STRING SMTPS 187
+STRING SPDY 1469
+STRING SSH 198
+STRING SSL 199
+STRING SOCKS 8005
+STRING TELNET 209
+STRING DHCP 29
+STRING RADIUS 158
+STRING OPENVPN 336
+STRING STUN 201
+STRING TEREDO 555
+STRING DTLS 1291
+STRING DoH 8006
+STRING ISAKMP 92
+STRING MDNS 3835
+STRING NETBIOS 129
+STRING NETFLOW 130
+STRING RDP 150
+STRING RTCP 174
+STRING RTP 175
+STRING SLP 8007
+STRING SNMP 190
+STRING SSDP 197
+STRING TFTP 211
+STRING BJNP 2481
+STRING LDAP 100
+STRING RTMP 337
+STRING RTSP 176
+STRING ESNI 8008
+STRING QQ 156
+STRING WeChat 1296
diff --git a/test/test_result_json/http_6over4_single_trans.json b/test/test_result_json/http_6over4_single_trans.json
new file mode 100644
index 0000000..4f6244a
--- /dev/null
+++ b/test/test_result_json/http_6over4_single_trans.json
@@ -0,0 +1,33 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "2001:da8:200:900e:200:5efe:d24d:58a3.52556>2600:140e:6::1702:1058.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/ncsi.txt",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Connection": "Close",
+ "User-Agent": "Microsoft NCSI",
+ "Host": "www.msftncsi.com",
+ "__X_HTTP_URL": "www.msftncsi.com/ncsi.txt",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Content-Length": "14",
+ "Date": "Tue, 01 Dec 2015 03:41:27 GMT",
+ "Connection": "close",
+ "Content-Type": "text/plain",
+ "Cache-Control": "max-age=30, must-revalidate",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_chunked_res_gzip.json b/test/test_result_json/http_chunked_res_gzip.json
new file mode 100644
index 0000000..4da91fd
--- /dev/null
+++ b/test/test_result_json/http_chunked_res_gzip.json
@@ -0,0 +1,41 @@
+[{
+ "__X_HTTP_TUPLE4": "127.0.0.1.33412>127.0.0.1.8080",
+ "__X_HTTP_RESULT_INDEX": "0"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "www.wireshark.org:8080",
+ "User-Agent": "curl/7.46.0",
+ "Accept": "*/*",
+ "Connection": "close",
+ "Accept-Encoding": "chunked, gzip",
+ "__X_HTTP_URL": "www.wireshark.org:8080/",
+ "__X_HTTP_RESULT_INDEX": "1"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "cloudflare-nginx",
+ "Date": "Wed, 06 Jan 2016 20:42:10 GMT",
+ "Content-Type": "text/html",
+ "Transfer-Encoding": "chunked",
+ "Connection": "close",
+ "Set-Cookie": "__cfduid=d8d37b52eaa3137bdfd7fd67a4ffc8a7a1452112929; expires=Thu, 05-Jan-17 20:42:09 GMT; path=/; domain=.wireshark.org; HttpOnly",
+ "X-Frame-Options": "SAMEORIGIN",
+ "Strict-Transport-Security": "max-age=31536000;",
+ "X-Slogan": "It's a great product with a great story to tell. I'm pumped!",
+ "X-Mod-Pagespeed": "1.9.32.11-7550",
+ "Vary": "Accept-Encoding",
+ "Cache-control": "max-age=0, no-cache, no-store",
+ "X-Slogan1": "Go deep.",
+ "CF-RAY": "260a3f709d7b0761-AMS",
+ "Content-Encoding": "gzip",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }]
diff --git a/test/test_result_json/http_connect_flood.json b/test/test_result_json/http_connect_flood.json
new file mode 100644
index 0000000..199c038
--- /dev/null
+++ b/test/test_result_json/http_connect_flood.json
@@ -0,0 +1,686 @@
+[
+ {
+ "Tuple4": "10.128.0.2.18762>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.16) Gecko/20110929 Iceweasel/3.5.16",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_1"
+ },
+ {
+ "Tuple4": "10.128.0.2.18746>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_2"
+ },
+ {
+ "Tuple4": "10.128.0.2.18744>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_3"
+ },
+ {
+ "Tuple4": "10.128.0.2.18748>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_4"
+ },
+ {
+ "Tuple4": "10.128.0.2.18750>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_5"
+ },
+ {
+ "Tuple4": "10.128.0.2.18752>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_6"
+ },
+ {
+ "Tuple4": "10.128.0.2.18754>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_7"
+ },
+ {
+ "Tuple4": "10.128.0.2.18756>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_8"
+ },
+ {
+ "Tuple4": "10.128.0.2.18758>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_9"
+ },
+ {
+ "Tuple4": "10.128.0.2.18760>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_10"
+ },
+ {
+ "Tuple4": "10.128.0.2.18762>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:38 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_11"
+ },
+ {
+ "Tuple4": "10.128.0.2.18768>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Safari/5.00 (Macintosh; U; en)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_12"
+ },
+ {
+ "Tuple4": "10.128.0.2.18766>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_13"
+ },
+ {
+ "Tuple4": "10.128.0.2.18770>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Opera/9.00 (Windows NT 5.1; U; en)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_14"
+ },
+ {
+ "Tuple4": "10.128.0.2.18772>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Opera/9.00 (Windows NT 5.1; U; en)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_15"
+ },
+ {
+ "Tuple4": "10.128.0.2.18776>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "GooglePocket/2.1 ( http://www.googlePocket.com/Pocket.html)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_16"
+ },
+ {
+ "Tuple4": "10.128.0.2.18774>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.4.0",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_17"
+ },
+ {
+ "Tuple4": "10.128.0.2.18780>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4b) Gecko/20030505 Mozilla Firebird/0.6",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_18"
+ },
+ {
+ "Tuple4": "10.128.0.2.18778>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "DoCoMo/2.0 SH902i (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_19"
+ },
+ {
+ "Tuple4": "10.128.0.2.18782>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "IE/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 1.1.4322;)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_20"
+ },
+ {
+ "Tuple4": "10.128.0.2.18784>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.16) Gecko/20110929 Iceweasel/3.5.16",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_21"
+ },
+ {
+ "Tuple4": "10.128.0.2.18768>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_22"
+ },
+ {
+ "Tuple4": "10.128.0.2.18766>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_23"
+ },
+ {
+ "Tuple4": "10.128.0.2.18770>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_24"
+ },
+ {
+ "Tuple4": "10.128.0.2.18772>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_25"
+ },
+ {
+ "Tuple4": "10.128.0.2.18776>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_26"
+ },
+ {
+ "Tuple4": "10.128.0.2.18780>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_27"
+ },
+ {
+ "Tuple4": "10.128.0.2.18774>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_28"
+ },
+ {
+ "Tuple4": "10.128.0.2.18778>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_29"
+ },
+ {
+ "Tuple4": "10.128.0.2.18782>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_30"
+ },
+ {
+ "Tuple4": "10.128.0.2.18784>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:39 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_31"
+ },
+ {
+ "Tuple4": "10.128.0.2.18790>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Safari/5.00 (Macintosh; U; en)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_32"
+ },
+ {
+ "Tuple4": "10.128.0.2.18792>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_33"
+ },
+ {
+ "Tuple4": "10.128.0.2.18796>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Opera/9.00 (Windows NT 5.1; U; en)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_34"
+ },
+ {
+ "Tuple4": "10.128.0.2.18794>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Opera/9.00 (Windows NT 5.1; U; en)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_35"
+ },
+ {
+ "Tuple4": "10.128.0.2.18798>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "GooglePocket/2.1 ( http://www.googlePocket.com/Pocket.html)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_36"
+ },
+ {
+ "Tuple4": "10.128.0.2.18800>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4b) Gecko/20030505 Mozilla Firebird/0.6",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_37"
+ },
+ {
+ "Tuple4": "10.128.0.2.18804>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "DoCoMo/2.0 SH902i (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_38"
+ },
+ {
+ "Tuple4": "10.128.0.2.18802>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.4.0",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_39"
+ },
+ {
+ "Tuple4": "10.128.0.2.18806>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "IE/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 1.1.4322;)",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_40"
+ },
+ {
+ "Tuple4": "10.128.0.2.18808>10.0.0.2.80",
+ "method": "CONNECT",
+ "uri": "test.mazebolt.com:80",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.mazebolt.com",
+ "User-Agent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.16) Gecko/20110929 Iceweasel/3.5.16",
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Content-Length": "0",
+ "name": "HTTP_DECODER_RESULT_41"
+ },
+ {
+ "Tuple4": "10.128.0.2.18790>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_42"
+ },
+ {
+ "Tuple4": "10.128.0.2.18792>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_43"
+ },
+ {
+ "Tuple4": "10.128.0.2.18796>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_44"
+ },
+ {
+ "Tuple4": "10.128.0.2.18798>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_45"
+ },
+ {
+ "Tuple4": "10.128.0.2.18794>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_46"
+ },
+ {
+ "Tuple4": "10.128.0.2.18800>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_47"
+ },
+ {
+ "Tuple4": "10.128.0.2.18804>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_48"
+ },
+ {
+ "Tuple4": "10.128.0.2.18802>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_49"
+ },
+ {
+ "Tuple4": "10.128.0.2.18806>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_50"
+ },
+ {
+ "Tuple4": "10.128.0.2.18808>10.0.0.2.80",
+ "res_version": "1.1",
+ "res_status": "Forbidden",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 403,
+ "Date": "Thu, 03 Sep 2020 10:26:41 GMT",
+ "Server": "Apache",
+ "Content-Length": "199",
+ "Content-Type": "text/html; charset=iso-8859-1",
+ "name": "HTTP_DECODER_RESULT_51"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_get_encoded_uri.json b/test/test_result_json/http_get_encoded_uri.json
new file mode 100644
index 0000000..189bf88
--- /dev/null
+++ b/test/test_result_json/http_get_encoded_uri.json
@@ -0,0 +1,71 @@
+[{
+ "__X_HTTP_TUPLE4": "192.168.117.60.39655>58.16.70.122.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "POST",
+ "uri": "/disAll/tcCertType.html",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
+ "Accept": "*/*",
+ "Accept-Language": "en-US,en;q=0.8,en-us,en;q=0.5",
+ "Origin": "http://58.16.70.122",
+ "X-Requested-With": "XMLHttpRequest",
+ "Referer": "http://58.16.70.122/register.jsp?redirect:http://58.16.70.122.r87.com/?",
+ "Cache-Control": "no-cache",
+ "X-Scanner": "Netsparker",
+ "Cookie": "JSESSIONID=385C79E211D561C0CA13D90F150F603D",
+ "Host": "58.16.70.122",
+ "Content-Length": "0",
+ "Accept-Encoding": "gzip, deflate",
+ "__X_HTTP_URL": "58.16.70.122/disAll/tcCertType.html",
+ "__X_HTTP_RESULT_INDEX": "1"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "Apache-Coyote/1.1",
+ "Pragma": "No-cache",
+ "Expires": "Thu, 01 Jan 1970 00:00:00 GMT",
+ "Content-Type": "text/html;charset=UTF-8",
+ "Transfer-Encoding": "chunked",
+ "Date": "Sat, 18 May 2019 01:36:57 GMT",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/upload/%E6%B3%95%E5%BE%8B%E6%B3%95%E8%A7%84/%E5%B8%82%E4%BA%BA%E6%B0%91%E6%94%BF%E5%BA%9C%E5%8A%9E%E5%85%AC%E5%8E%85%E5%8D%B0%E5%8F%91%E8%B4%B5%E9%98%B3%E5%B8%82%E5%85%B3%E4%BA%8E%E6%8E%A8%E8%BF%9B%E5%B7%A5%E5%95%86%E8%90%A5%E4%B8%9A%E6%89%A7%E7%85%A7%E3%80%81%E7%BB%84%E7%BB%87%E6%9C%BA%E6%9E%84%E4%BB%A3%E7%A0%81%E8%AF%81%E5%92%8C%E7%A8%8E%E5%8A%A1%E7%99%BB%E8%AE%B0%E8%AF%81%E2%80%9C%E4%B8%89%E8%AF%81%E5%90%88%E4%B8%80%E2%80%9D%E7%99%BB%E8%AE%B0%E5%88%B6%E5%BA%A6%E6%94%B9%E9%9D%A9%E5%AE%9E%E6%96%BD%E6%96%B9%E6%A1%88%E7%9A%84%E9%80%9A%E7%9F%A5%EF%BC%88%E7%AD%91%E5%BA%9C%E5%8A%9E%E5%87%BD%E3%80%902015%E3%80%91162%E5%8F%B7%EF%BC%89.docx?nsextt=N3TSP4RKE2",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
+ "User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
+ "Cache-Control": "no-cache",
+ "Accept-Language": "en-us,en;q=0.5",
+ "X-Scanner": "Netsparker",
+ "Cookie": "JSESSIONID=385C79E211D561C0CA13D90F150F603D",
+ "Host": "58.16.70.122",
+ "Accept-Encoding": "gzip, deflate",
+ "__X_HTTP_URL": "58.16.70.122/upload/%E6%B3%95%E5%BE%8B%E6%B3%95%E8%A7%84/%E5%B8%82%E4%BA%BA%E6%B0%91%E6%94%BF%E5%BA%9C%E5%8A%9E%E5%85%AC%E5%8E%85%E5%8D%B0%E5%8F%91%E8%B4%B5%E9%98%B3%E5%B8%82%E5%85%B3%E4%BA%8E%E6%8E%A8%E8%BF%9B%E5%B7%A5%E5%95%86%E8%90%A5%E4%B8%9A%E6%89%A7%E7%85%A7%E3%80%81%E7%BB%84%E7%BB%87%E6%9C%BA%E6%9E%84%E4%BB%A3%E7%A0%81%E8%AF%81%E5%92%8C%E7%A8%8E%E5%8A%A1%E7%99%BB%E8%AE%B0%E8%AF%81%E2%80%9C%E4%B8%89%E8%AF%81%E5%90%88%E4%B8%80%E2%80%9D%E7%99%BB%E8%AE%B0%E5%88%B6%E5%BA%A6%E6%94%B9%E9%9D%A9%E5%AE%9E%E6%96%BD%E6%96%B9%E6%A1%88%E7%9A%84%E9%80%9A%E7%9F%A5%EF%BC%88%E7%AD%91%E5%BA%9C%E5%8A%9E%E5%87%BD%E3%80%902015%E3%80%91162%E5%8F%B7%EF%BC%89.docx?nsextt=N3TSP4RKE2",
+ "__X_HTTP_RESULT_INDEX": "3"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "Apache-Coyote/1.1",
+ "Accept-Ranges": "bytes",
+ "ETag": "W/\"1703517-1546572172000\"",
+ "Last-Modified": "Fri, 04 Jan 2019 03:22:52 GMT",
+ "Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8",
+ "Content-Length": "1703517",
+ "Date": "Sat, 18 May 2019 01:37:00 GMT",
+ "__X_HTTP_RESULT_INDEX": "4"
+ }]
diff --git a/test/test_result_json/http_get_long_cookie.json b/test/test_result_json/http_get_long_cookie.json
new file mode 100644
index 0000000..8c73779
--- /dev/null
+++ b/test/test_result_json/http_get_long_cookie.json
@@ -0,0 +1,24 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "202.127.156.91.27282>14.17.32.203.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/livemsg?imagemd5=02f5efd8a349c50280f8540b2735bd54&tailroll=1&plugin=1.3.8&pf=out&si=3766845706&url=http%3A%2F%2Fsports.qq.com%2Fa%2F20160106%2F008987.htm&soid=CA7F9C5B0120568CDC2F68726300&chid=0&ping_data=dXNlcl9pbmZvPXVCWDluVDg5SFJhOUFQK0JQVGdKRUxVYi9Kdz0&t=0&iptype=0&vptag=&pid=7F993E38C0E676ACC07DE764D1F3DEF56AA8F90A&adtype=LD&oadid=6012&ev=3236&l=4020&ufc_filter=0&imagelog=1&pid2=7F993E38C0E676ACC07DE764D1F3DEF56AA8F90A&mt=15000&coverid=&reqtime=1452071981&requestl=4020&isthirdip=0&cid=0&isfloatindex=0&o=100654557&lcount=2&refluence=4020&from=0&vid=m01794rm5ej&cip=202.127.156.91&aver=0&ip_filter=0&adlength=30000&tagid=&v=TencentPlayerOutV3.2.19.346&live=0&dura=105",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "livep.l.qq.com",
+ "Connection": "keep-alive",
+ "User-Agent": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36",
+ "Accept": "*/*",
+ "Referer": "http://imgcache.qq.com/tencentvideo_v1/player/TPout.swf?max_age=86400&v=20140714",
+ "Accept-Encoding": "gzip,deflate,sdch",
+ "Accept-Language": "zh-CN,zh;q=0.8",
+ "__X_HTTP_URL": "livep.l.qq.com/livemsg?imagemd5=02f5efd8a349c50280f8540b2735bd54&tailroll=1&plugin=1.3.8&pf=out&si=3766845706&url=http%3A%2F%2Fsports.qq.com%2Fa%2F20160106%2F008987.htm&soid=CA7F9C5B0120568CDC2F68726300&chid=0&ping_data=dXNlcl9pbmZvPXVCWDluVDg5SFJhOUFQK0JQVGdKRUxVYi9Kdz0&t=0&iptype=0&vptag=&pid=7F993E38C0E676ACC07DE764D1F3DEF56AA8F90A&adtype=LD&oadid=6012&ev=3236&l=4020&ufc_filter=0&imagelog=1&pid2=7F993E38C0E676ACC07DE764D1F3DEF56AA8F90A&mt=15000&coverid=&reqtime=1452071981&requestl=4020&isthirdip=0&cid=0&isfloatindex=0&o=100654557&lcount=2&refluence=4020&from=0&vid=m01794rm5ej&cip=202.127.156.91&aver=0&ip_filter=0&adlength=30000&tagid=&v=TencentPlayerOutV3.2.19.346&live=0&dura=105",
+ "Cookie": "flashuser=95621BA8CB862E09; piao_city=179; lv_irt_id=3628e1bbe25a6c941da9fac02ec2df8b; cm_cookie=V1,10017&-EP5mRruXhQarsCl5LD-2YzgjVTvyr2K&AQEBh7uoLMUB9lnaB5Tz9XdYnGIWflXmsDrU&150723&150723,10035&7t-tEmfJ076VAsM9&AQEBh7uoLMUB9lnc4tpW7vbazqdrRdBYOUCi&150724&150807,110054&ucO0Z0gctNn3&AQEBh7uoLMUB9llxMNl45F3RAIsKK0iMOJAG&150716&151008,10040&ACZ1r0A70NaEFcGT&AQEBh7uoLMUB9lmVgSoTwuuXZi896zSVsXIF&150818&151014,110015&1&AQEBh7uoLMUB9lkt2LUHO6ARwODHLI_Y51rj&150928&151103,10037&1433388364186289251984&AQEBh7uoLMUB9llIBencOqTAEh2aQ2SURSSQ&150909&151110,10011&jL40Z03uUFI0&AQEBh7uoLMUB9lkfw2sJVNx9g12Fzs12rPSN&150717&151125,10016&F64E6LFZs0W&AQEBh7uoLMUB9llE4yoPFNUykSj7WKaRK5lH&150805&151127,10019&WQAO-C1K9qI5OP8W_t2pSw&AQEBh7uoLMUB9llhpZE87GmOk3XGo_MJgV6K&150826&151130,10015&820490997316506147&AQEBh7uoLMUB9llXiynsGYRhMO3XuPnkuHUt&150715&151201,10012&x3X1yY6b&AQEBh7uoLMUB9ll9mraU_LJCDBYsE0Sbk_V9&151202&151202,110065&ucO0Z0gctNn3&AQEBh7uoLMUB9lkJcK3KDBQTKF0YfZ5wB7r5&150716&151203,110066&jL40Z03uUFI0&AQEBh7uoLMUB9lnyvKSYhcJD1X_rSs_DLVWx&150916&151221,10013&ePyYB2MSKa0TCbebpxKjmU&AQEBh7uoLMUB9ln6_6nGNidqml4nFKXhtE58&151221&151221,110061&d9cfa518d82abee&AQEBh7uoLMUB9llj2NYzmCjxaLWXALTcAGIH&150818&151224,10038&CAESEPZbUhToZJ39CS9MlgXGUSQ&AQEBh7uoLMUB9lmhnrDM5lIGtl6vc1NxMD6F&151110&151224,10077&820490997316506147&AQEBh7uoLMUB9lmkUdUe2xSHGkvM0IRu9Jt9&151214&151228,10008&0yPSvk92ie1nhB8wTUlTq&AQEBh7uoLMUB9lnL5ZCYvXJNvlv53G0CKEkj&150817&151228,10045&0&AQEBh7uoLMUB9llW3v1Vh7W72lv14RlAjUXn&151023&151228,110064&jL40Z03uUFI0&AQEBh7uoLMUB9lkBYuCUDLDrOcGURJcilogv&151016&160104,110069&26d49ecc&AQEBh7uoLMUB9lmlBLTxQY9BkCmimkMFqTo5&151204&160105,10079&B8hGto5y1e3uDXwCMsIun3rjk--dVCof&AQEBh7uoLMUB9llxnFrhDtdNMjZ1hs1il5J4&151214&160105; LHTturn=24; ptisp=ctc; RK=hRWyd82Gd8; pgv_pvi=7567882240; image_md5=bd21d5fb2f401b37cf3a02724dc06545; LTPturn=27; pt2gguin=o0583115900; uin=o0583115900; skey=@Mp9aCinaO; ptcz=10d4b1b7bde835d64663338a8008fd4f81e2c6b5f0ba81a90da3627ee617c7ee; pgv_info=ssid=s4768939310; pgv_pvid=6872592818; o_cookie=583115900; lv_play_index_textAd=47; lv_play_indexl.=32; dc_vplaying=1; LKBturn=29; Lturn=29; adid=583115900; appuser=95621BA8CB862E09; o_minduid=phhdxyNLkxBWMa74VTm5zU4y5EbUv5vR; appuser_95621BA8CB862E09_0=2b7gwp=1453219199_6&2btemv=1455551999_1&2c8311=1453305599_3&2cfx4j=1453651199_3&2cfx9l=1453651199_1&2d49y9=1453823999_2&2d67kl=1454255999_2&2d69mf=1454255999_3&2dxv8l=1455465599_6&2dzhfl=1452614399_1&f_pogvwp=1452095999_1&f_pogvwv=1452095999_2&f_pogw0m=1452095999_1&fd_15bm2t7=1452095999_1&fd_1h2pbsd=1452095999_2&fd_1k6so62=1452095999_1&fd_rhmjmq=1452095999_2&m_roiw0t=1452095999_3&m_xty8wl=1452095999_1&pogree=1452095999_2; TX.boid=100655474=1452072582_1&701041365=1452072585_1; appuser_95621BA8CB862E09_effect_0=fd_1ez2rcc=1452095999_1&fd_qdh7zw=1452095999_1&fd_ul215j=1452095999_1; psessionid=ca7f9c5b_1452071982_583115900_30754; psessiontime=1452071990",
+ "__X_HTTP_RESULT_INDEX": "1"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_get_malformed.json b/test/test_result_json/http_get_malformed.json
new file mode 100644
index 0000000..fdaa350
--- /dev/null
+++ b/test/test_result_json/http_get_malformed.json
@@ -0,0 +1,28 @@
+ [
+ {
+ "__X_HTTP_TUPLE4": "192.168.4.2.36598>108.61.176.217.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.0",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 0,
+ "status_code": 200,
+ "Server": "FakeNet/1.3",
+ "Date": "Wed, 12 Sep 2018 19:45:55 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "1547",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+ ] \ No newline at end of file
diff --git a/test/test_result_json/http_get_multi_trans.json b/test/test_result_json/http_get_multi_trans.json
new file mode 100644
index 0000000..6bb4ca4
--- /dev/null
+++ b/test/test_result_json/http_get_multi_trans.json
@@ -0,0 +1,139 @@
+
+[{
+ "__X_HTTP_TUPLE4": "192.168.50.18.60400>192.168.42.1.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/account/login.htm",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.pro.testin.cn",
+ "Connection": "keep-alive",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "zh-CN,zh;q=0.9",
+ "Cookie": "Hm_lvt_1b8c1194303ef64e02f003f0cb8a1906=1653898514; _gcl_au=1.1.1010551181.1653898515; _ga=GA1.2.1419569885.1653898515; _gid=GA1.2.2007113907.1653898515; authtoken_pro=tea83b3beef07488bb8571811385db42; userId_pro=1160; pid_pro=1; eid_pro=1; pname_pro=name; Hm_lpvt_1b8c1194303ef64e02f003f0cb8a1906=1653961741; JSESSIONID=531AACA879469EDAB825E28113490E10",
+ "__X_HTTP_URL": "test.pro.testin.cn/account/login.htm",
+ "__X_HTTP_RESULT_INDEX": "1"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 302,
+ "Server": "nginx/1.16.1",
+ "Date": "Tue, 31 May 2022 06:41:23 GMT",
+ "Content-Length": "0",
+ "Connection": "keep-alive",
+ "Set-Cookie": "JSESSIONID=CFAB9C0C3F4D9D6C2837E3BA9425AFCA; Path=/; HttpOnly",
+ "Set-Cookie1": "authtoken_pro=tea83b3beef07488bb8571811385db42; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Set-Cookie2": "userId_pro=1160; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Location": "http://test.pro.testin.cn/enterprise/index.htm",
+ "Content-Language": "zh-CN",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/enterprise/index.htm",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.pro.testin.cn",
+ "Connection": "keep-alive",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "zh-CN,zh;q=0.9",
+ "Cookie": "Hm_lvt_1b8c1194303ef64e02f003f0cb8a1906=1653898514; _gcl_au=1.1.1010551181.1653898515; _ga=GA1.2.1419569885.1653898515; _gid=GA1.2.2007113907.1653898515; authtoken_pro=tea83b3beef07488bb8571811385db42; userId_pro=1160; pid_pro=1; eid_pro=1; pname_pro=name; Hm_lpvt_1b8c1194303ef64e02f003f0cb8a1906=1653961741; JSESSIONID=CFAB9C0C3F4D9D6C2837E3BA9425AFCA",
+ "__X_HTTP_URL": "test.pro.testin.cn/enterprise/index.htm",
+ "__X_HTTP_RESULT_INDEX": "3"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 302,
+ "Server": "nginx/1.16.1",
+ "Date": "Tue, 31 May 2022 06:41:23 GMT",
+ "Content-Length": "0",
+ "Connection": "keep-alive",
+ "Set-Cookie": "authtoken_pro=tea83b3beef07488bb8571811385db42; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Set-Cookie1": "userId_pro=1160; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Location": "http://test.pro.testin.cn/enterprise/into.htm?eid=1",
+ "Content-Language": "zh-CN",
+ "__X_HTTP_RESULT_INDEX": "4"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/enterprise/into.htm?eid=1",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.pro.testin.cn",
+ "Connection": "keep-alive",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "zh-CN,zh;q=0.9",
+ "Cookie": "Hm_lvt_1b8c1194303ef64e02f003f0cb8a1906=1653898514; _gcl_au=1.1.1010551181.1653898515; _ga=GA1.2.1419569885.1653898515; _gid=GA1.2.2007113907.1653898515; authtoken_pro=tea83b3beef07488bb8571811385db42; userId_pro=1160; pid_pro=1; eid_pro=1; pname_pro=name; Hm_lpvt_1b8c1194303ef64e02f003f0cb8a1906=1653961741; JSESSIONID=CFAB9C0C3F4D9D6C2837E3BA9425AFCA",
+ "__X_HTTP_URL": "test.pro.testin.cn/enterprise/into.htm?eid=1",
+ "__X_HTTP_RESULT_INDEX": "5"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 302,
+ "Server": "nginx/1.16.1",
+ "Date": "Tue, 31 May 2022 06:41:23 GMT",
+ "Content-Length": "0",
+ "Connection": "keep-alive",
+ "Set-Cookie": "authtoken_pro=tea83b3beef07488bb8571811385db42; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Set-Cookie1": "userId_pro=1160; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Location": "http://test.pro.testin.cn/realmachine/index.htm",
+ "Content-Language": "zh-CN",
+ "__X_HTTP_RESULT_INDEX": "6"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/realmachine/index.htm",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "test.pro.testin.cn",
+ "Connection": "keep-alive",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "zh-CN,zh;q=0.9",
+ "Cookie": "Hm_lvt_1b8c1194303ef64e02f003f0cb8a1906=1653898514; _gcl_au=1.1.1010551181.1653898515; _ga=GA1.2.1419569885.1653898515; _gid=GA1.2.2007113907.1653898515; authtoken_pro=tea83b3beef07488bb8571811385db42; userId_pro=1160; pid_pro=1; eid_pro=1; pname_pro=name; Hm_lpvt_1b8c1194303ef64e02f003f0cb8a1906=1653961741; JSESSIONID=CFAB9C0C3F4D9D6C2837E3BA9425AFCA",
+ "__X_HTTP_URL": "test.pro.testin.cn/realmachine/index.htm",
+ "__X_HTTP_RESULT_INDEX": "7"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx/1.16.1",
+ "Date": "Tue, 31 May 2022 06:41:23 GMT",
+ "Content-Type": "text/html;charset=UTF-8",
+ "Transfer-Encoding": "chunked",
+ "Connection": "keep-alive",
+ "Vary": "Accept-Encoding",
+ "Set-Cookie": "authtoken_pro=tea83b3beef07488bb8571811385db42; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Set-Cookie1": "userId_pro=1160; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Set-Cookie2": "pid_pro=1; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Set-Cookie3": "eid_pro=1; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Set-Cookie4": "pname_pro=name; Max-Age=28800; Expires=Tue, 31-May-2022 14:41:23 GMT; Domain=testin.cn; Path=/; HttpOnly",
+ "Content-Language": "zh-CN",
+ "Content-Encoding": "gzip",
+ "__X_HTTP_RESULT_INDEX": "8"
+ }] \ No newline at end of file
diff --git a/test/test_result_json/http_get_req_pipeline.json b/test/test_result_json/http_get_req_pipeline.json
new file mode 100644
index 0000000..a442274
--- /dev/null
+++ b/test/test_result_json/http_get_req_pipeline.json
@@ -0,0 +1,67 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.40.81.52802>192.168.40.137.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/aa.mp4?asf=sdaf",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "113.31.27.226",
+ "Connection": "keep-alive",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+ "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1636.2 Safari/537.36",
+ "Accept-Encoding": "gzip,deflate,sdch",
+ "Accept-Language": "zh-CN,zh;q=0.8",
+ "__X_HTTP_URL": "113.31.27.226/aa.mp4?asf=sdaf",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/fetch_ldns.png",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "ns.pb.cachecn.net",
+ "Connection": "keep-alive",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+ "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1636.2 Safari/537.36",
+ "Accept-Encoding": "gzip,deflate,sdch",
+ "Accept-Language": "zh-CN,zh;q=0.8",
+ "__X_HTTP_URL": "ns.pb.cachecn.net/fetch_ldns.png",
+ "__X_HTTP_RESULT_INDEX": "2"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/40x.jpg",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "ns.pb.cachecn.net",
+ "Connection": "keep-alive",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+ "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1636.2 Safari/537.36",
+ "Accept-Encoding": "gzip,deflate,sdch",
+ "Accept-Language": "zh-CN,zh;q=0.8",
+ "__X_HTTP_URL": "ns.pb.cachecn.net/40x.jpg",
+ "__X_HTTP_RESULT_INDEX": "3"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.0",
+ "res_status": "File not found",
+ "major_version": 1,
+ "minor_version": 0,
+ "status_code": 404,
+ "Server": "SimpleHTTP/0.6 Python/2.7.5",
+ "Date": "Wed, 25 Oct 2023 06:43:35 GMT",
+ "Content-Type": "text/html",
+ "Connection": "close",
+ "__X_HTTP_RESULT_INDEX": "4"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_get_single_trans.json b/test/test_result_json/http_get_single_trans.json
new file mode 100644
index 0000000..b227989
--- /dev/null
+++ b/test/test_result_json/http_get_single_trans.json
@@ -0,0 +1,29 @@
+[{
+ "__X_HTTP_TUPLE4": "192.168.38.73.50806>192.168.40.137.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/index.html",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "192.168.40.137",
+ "User-Agent": "curl/7.79.1",
+ "Accept": "*/*",
+ "__X_HTTP_URL": "192.168.40.137/index.html",
+ "__X_HTTP_RESULT_INDEX": "1"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.0",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 0,
+ "status_code": 200,
+ "Server": "SimpleHTTP/0.6 Python/2.7.5",
+ "Date": "Thu, 30 Nov 2023 08:42:24 GMT",
+ "Content-type": "text/html",
+ "Content-Length": "144",
+ "Last-Modified": "Thu, 30 Nov 2023 08:38:54 GMT",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }]
diff --git a/test/test_result_json/http_hdr_truncated_after_kv.json b/test/test_result_json/http_hdr_truncated_after_kv.json
new file mode 100644
index 0000000..68b5f45
--- /dev/null
+++ b/test/test_result_json/http_hdr_truncated_after_kv.json
@@ -0,0 +1,285 @@
+[{
+ "__X_HTTP_TUPLE4": "196.188.112.76.51494>23.246.50.149.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABQSwLpJi-yDFZ7k9eqarY3x3-b99vNxxOt5xDeIOapZB6Y5QXPSa54b7cbWYTXYdFimDKCeJ4s7ngqpqByvtt0aLh85nSucLTcR3-OKleuNwVltHUscQhSgVfHc.jpg?r=392",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABQSwLpJi-yDFZ7k9eqarY3x3-b99vNxxOt5xDeIOapZB6Y5QXPSa54b7cbWYTXYdFimDKCeJ4s7ngqpqByvtt0aLh85nSucLTcR3-OKleuNwVltHUscQhSgVfHc.jpg?r=392",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABQSwLpJi-yDFZ7k9eqarY3x3-b99vNxxOt5xDeIOapZB6Y5QXPSa54b7cbWYTXYdFimDKCeJ4s7ngqpqByvtt0aLh85nSucLTcR3-OKleuNwVltHUscQhSgVfHc.jpg?r=392",
+ "__X_HTTP_RESULT_INDEX": "1"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABUWN8S1k3yM2coX2bwxbP699Jdr0BUqBRzIfiAJXKC5Ywt7DXqJOCjrBSYs36Tny8277IXm2BF_cgTmY18NJlocglKjhaoJhFeGoIg1cwntFduyxyRPP2EJQL5Y.jpg?r=e0e",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABUWN8S1k3yM2coX2bwxbP699Jdr0BUqBRzIfiAJXKC5Ywt7DXqJOCjrBSYs36Tny8277IXm2BF_cgTmY18NJlocglKjhaoJhFeGoIg1cwntFduyxyRPP2EJQL5Y.jpg?r=e0e",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABUWN8S1k3yM2coX2bwxbP699Jdr0BUqBRzIfiAJXKC5Ywt7DXqJOCjrBSYs36Tny8277IXm2BF_cgTmY18NJlocglKjhaoJhFeGoIg1cwntFduyxyRPP2EJQL5Y.jpg?r=e0e",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABR1YQS01SaHGzoxgWBJF1Gas0Gv9_DPebb4irdCTRjcQ_FUaVbXFTTrJ68_bvJds1sb28VMq22Qn3oSSKKJ7DdLN8ybgkJooYlCD3gAntrqgIFugqv5Z3kV8rRE.jpg?r=ec7",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABR1YQS01SaHGzoxgWBJF1Gas0Gv9_DPebb4irdCTRjcQ_FUaVbXFTTrJ68_bvJds1sb28VMq22Qn3oSSKKJ7DdLN8ybgkJooYlCD3gAntrqgIFugqv5Z3kV8rRE.jpg?r=ec7",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABR1YQS01SaHGzoxgWBJF1Gas0Gv9_DPebb4irdCTRjcQ_FUaVbXFTTrJ68_bvJds1sb28VMq22Qn3oSSKKJ7DdLN8ybgkJooYlCD3gAntrqgIFugqv5Z3kV8rRE.jpg?r=ec7",
+ "__X_HTTP_RESULT_INDEX": "3"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 14:15:58 GMT",
+ "Content-Type": "image/jpeg",
+ "Content-Length": "18377",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=2592000",
+ "Last-Modified": "Wed, 10 Nov 2021 08:00:14 GMT",
+ "ETag": "\"c289a42885b30107ad119e2a6e405e4d\"",
+ "__X_HTTP_RESULT_INDEX": "4"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABYo5IGwDn1LaWbeaa7amS0JhH3bU5MEVlcBsC4OK0mGbea97_xoi8EbqJt8_Zp0bMuuKPE80qUUjb4wq5po_lBtulA.jpg?r=c83",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABYo5IGwDn1LaWbeaa7amS0JhH3bU5MEVlcBsC4OK0mGbea97_xoi8EbqJt8_Zp0bMuuKPE80qUUjb4wq5po_lBtulA.jpg?r=c83",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABYo5IGwDn1LaWbeaa7amS0JhH3bU5MEVlcBsC4OK0mGbea97_xoi8EbqJt8_Zp0bMuuKPE80qUUjb4wq5po_lBtulA.jpg?r=c83",
+ "__X_HTTP_RESULT_INDEX": "5"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABaYF3Rmi954cg6Afu9jOtirnvF3iIMHPZCCnP34eDeYQXfRGG9Vg0qgn7hHpMVV4jOr8OZmcD2Nb7MhQv6gl-fNmVQ.jpg?r=257",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABaYF3Rmi954cg6Afu9jOtirnvF3iIMHPZCCnP34eDeYQXfRGG9Vg0qgn7hHpMVV4jOr8OZmcD2Nb7MhQv6gl-fNmVQ.jpg?r=257",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABaYF3Rmi954cg6Afu9jOtirnvF3iIMHPZCCnP34eDeYQXfRGG9Vg0qgn7hHpMVV4jOr8OZmcD2Nb7MhQv6gl-fNmVQ.jpg?r=257",
+ "__X_HTTP_RESULT_INDEX": "6"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABfC-ByjFJSfWZf7MFtjVl3ONnaQ69824xWP1l-cpAFGgAfaNFk4XR9uoHNWwnbG8N2UVDctVKz0a4Uyv0mEnC2kI9Q.jpg?r=532",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABfC-ByjFJSfWZf7MFtjVl3ONnaQ69824xWP1l-cpAFGgAfaNFk4XR9uoHNWwnbG8N2UVDctVKz0a4Uyv0mEnC2kI9Q.jpg?r=532",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABfC-ByjFJSfWZf7MFtjVl3ONnaQ69824xWP1l-cpAFGgAfaNFk4XR9uoHNWwnbG8N2UVDctVKz0a4Uyv0mEnC2kI9Q.jpg?r=532",
+ "__X_HTTP_RESULT_INDEX": "7"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABSyGFXaB0IqQ6VR92uKMi38mNtoz7eeWxDziAf9VYKfauhh5Qo7FnnCRb31ff6Ez9yTXsqRszsGuz0GA9FVDf_NLn-9F60IcUHm59J73eYX6BD0h4wLLK0Da6YM.jpg?r=aaa",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABSyGFXaB0IqQ6VR92uKMi38mNtoz7eeWxDziAf9VYKfauhh5Qo7FnnCRb31ff6Ez9yTXsqRszsGuz0GA9FVDf_NLn-9F60IcUHm59J73eYX6BD0h4wLLK0Da6YM.jpg?r=aaa",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABSyGFXaB0IqQ6VR92uKMi38mNtoz7eeWxDziAf9VYKfauhh5Qo7FnnCRb31ff6Ez9yTXsqRszsGuz0GA9FVDf_NLn-9F60IcUHm59J73eYX6BD0h4wLLK0Da6YM.jpg?r=aaa",
+ "__X_HTTP_RESULT_INDEX": "8"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABZbHXQr7bRUpSQ2vQe8F8p3xODTJjUbSjEcLgQrFVyGsPgQT1GVhqGWFetJhebcGrVeZGOTmQ3qvHTe9eBRJdjFsVg.jpg?r=723",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABZbHXQr7bRUpSQ2vQe8F8p3xODTJjUbSjEcLgQrFVyGsPgQT1GVhqGWFetJhebcGrVeZGOTmQ3qvHTe9eBRJdjFsVg.jpg?r=723",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABZbHXQr7bRUpSQ2vQe8F8p3xODTJjUbSjEcLgQrFVyGsPgQT1GVhqGWFetJhebcGrVeZGOTmQ3qvHTe9eBRJdjFsVg.jpg?r=723",
+ "__X_HTTP_RESULT_INDEX": "9"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 14:15:58 GMT",
+ "Content-Type": "image/jpeg",
+ "Content-Length": "13488",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=2592000",
+ "Last-Modified": "Mon, 08 Nov 2021 19:50:54 GMT",
+ "ETag": "\"35d56b6a0ef3b5857013f44620bd8888\"",
+ "__X_HTTP_RESULT_INDEX": "10"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 14:15:58 GMT",
+ "Content-Type": "image/jpeg",
+ "Content-Length": "14129",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=2592000",
+ "Last-Modified": "Tue, 26 Oct 2021 15:12:58 GMT",
+ "ETag": "\"bb83961ad5fe366dcbb5240ead69f650\"",
+ "__X_HTTP_RESULT_INDEX": "11"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 14:15:58 GMT",
+ "Content-Type": "image/jpeg",
+ "Content-Length": "11493",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=2592000",
+ "Last-Modified": "Thu, 04 Nov 2021 20:44:22 GMT",
+ "ETag": "\"c5be6a7137482da270bb2adc8d44a28d\"",
+ "__X_HTTP_RESULT_INDEX": "12"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 14:15:58 GMT",
+ "Content-Type": "image/jpeg",
+ "Content-Length": "14219",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=2592000",
+ "Last-Modified": "Sat, 25 Sep 2021 05:02:49 GMT",
+ "ETag": "\"61bec96775876749bb57139f86f6b0ca\"",
+ "__X_HTTP_RESULT_INDEX": "13"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 14:15:58 GMT",
+ "Content-Type": "image/jpeg",
+ "Content-Length": "21967",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=2592000",
+ "Last-Modified": "Fri, 02 Jul 2021 10:15:04 GMT",
+ "ETag": "\"841065529f1e89eabd0ef235a3d3291c\"",
+ "__X_HTTP_RESULT_INDEX": "14"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 14:15:58 GMT",
+ "Content-Type": "image/jpeg",
+ "Content-Length": "21670",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=2592000",
+ "Last-Modified": "Tue, 19 Oct 2021 14:00:02 GMT",
+ "ETag": "\"21d4b2c21a3a2f26ba665670e8513940\"",
+ "__X_HTTP_RESULT_INDEX": "15"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABSFXjTUaVrddq_nehO4yuLziSjuekxJuv3oEsyUpmt3oK3InJcXjtZUHrBBuu0EP05WRC8wFVe78VtxtW_ZuZQ65MIcApb0oZF4JoFlHHnv363RbgJn898Q4tQc.jpg?r=590",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Accept": "image/*",
+ "Accept-Encoding": "deflate, gzip",
+ "Connection": "Keep-Alive",
+ "Host": "occ-0-778-360.1.nflxso.net",
+ "Language": "en-ET,en",
+ "Referer": "https://secure.netflix.com/us/tvui/ql/patch/20211109_18752/2/release/darwinBootstrap.js?getMainUrlFromCodex=true&taskDefaultTimeoutV2=120000&bootloader_trace=apiusernotnull__false&nq=true&nq_control_tag=tvui-main&startup_key=e38d3c70814421931b0189d91d872546326f05d8f470150d07340df9e9d72275&device_type=TCL-TVS88L&e=TCL-TVS88L0000000000000000342914&env=prod&fromNM=true&nm_prefetch=true&nrdapp_version=2015.1.1&plain=true&dh=720&dw=1280&dar=16_9&reg=undefined&authType=login&authclid=845becf0-992c-46f7-a938-1bc22b097c58&q=source_type%3D1%26additionalDataUrl%3Dhttp%253A%252F%252Flocalhost%253A56789%252Fapps%252FNetflix%252Fdial_data%26source_type_payload%3D",
+ "User-Agent": "Gibbon/2015.1.1/2015.1.1: Netflix/2015.1.1 (DEVTYPE=TCL-TVS88L; CERTVER=1)",
+ "__X_HTTP_URL": "occ-0-778-360.1.nflxso.net/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABSFXjTUaVrddq_nehO4yuLziSjuekxJuv3oEsyUpmt3oK3InJcXjtZUHrBBuu0EP05WRC8wFVe78VtxtW_ZuZQ65MIcApb0oZF4JoFlHHnv363RbgJn898Q4tQc.jpg?r=590",
+ "X-Gibbon-Cache-Control": "max-age=2592000, priority=4, key=/dnm/api/v6/Da_vleYcahiCE7JMYt8LJRyoenc/AAAABSFXjTUaVrddq_nehO4yuLziSjuekxJuv3oEsyUpmt3oK3InJcXjtZUHrBBuu0EP05WRC8wFVe78VtxtW_ZuZQ65MIcApb0oZF4JoFlHHnv363RbgJn898Q4tQc.jpg?r=590",
+ "__X_HTTP_RESULT_INDEX": "16"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 14:15:58 GMT",
+ "Content-Type": "image/jpeg",
+ "Content-Length": "14215",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=2592000",
+ "Last-Modified": "Thu, 11 Nov 2021 17:32:01 GMT",
+ "ETag": "\"837a2051f7d0f2899baf54ff20b3d9ad\"",
+ "__X_HTTP_RESULT_INDEX": "17"
+ }]
diff --git a/test/test_result_json/http_hdr_truncated_in_kv.json b/test/test_result_json/http_hdr_truncated_in_kv.json
new file mode 100644
index 0000000..f123f6d
--- /dev/null
+++ b/test/test_result_json/http_hdr_truncated_in_kv.json
@@ -0,0 +1,53 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "196.190.248.93.32727>94.130.141.49.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/iframes2/e38f4959d33f4fa390045b0d7123997d.html?subid=65843620",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "tsyndicate.com",
+ "Connection": "keep-alive",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Mozilla/5.0 (Linux; Android 11; SM-A217F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "Referer": "http://the-sexy-tube.com/",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8",
+ "__X_HTTP_URL": "tsyndicate.com/iframes2/e38f4959d33f4fa390045b0d7123997d.html?subid=65843620",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "nginx",
+ "Date": "Sat, 13 Nov 2021 13:58:01 GMT",
+ "Content-Type": "text/html; charset=utf-8",
+ "Transfer-Encoding": "chunked",
+ "Connection": "keep-alive",
+ "Vary": "Accept-Encoding",
+ "Cache-Control": "no-cache, no-store, no-transform, must-revalidate",
+ "Pragma": "no-cache",
+ "Expires": "0",
+ "Vary1": "*",
+ "X-Api-Version": "2",
+ "Link": "<http://lcdn.tsyndicate.com/sdk/v1/b.b.js>; rel=preload; as=script",
+ "X-Request-Id": "2ceed9968bf8c648",
+ "Set-Cookie": "ts_uid=6ec96511-9fa6-4e10-86b8-31fdb4531864; expires=Fri, 13 May 2022 13:58:01 GMT; domain=.tsyndicate.com; path=/; HttpOnly; secure; SameSite=None",
+ "Set-Cookie2": "bfq=e0SIEaFjiwwZNWjkkDGjCwsRYwpuifFQRJmJMWzMsIEjBw4ZOCr2URAQ; expires=Sun, 14 Nov 2021 13:58:01 GMT; domain=.tsyndicate.com; path=/; secure; SameSite=None",
+ "X-Robots-Tag": "none",
+ "Cache-Control3": "no-transform",
+ "X-Robots-Tag4": "noindex, nofollow",
+ "Report-To": "{ \"url\": \"https://pxl.tsyndicate.com/api/v1/heavy-ad/report\", \"max_age\": 86401 }",
+ "Content-Encoding": "gzip",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_hdr_value_empty.json b/test/test_result_json/http_hdr_value_empty.json
new file mode 100644
index 0000000..aface09
--- /dev/null
+++ b/test/test_result_json/http_hdr_value_empty.json
@@ -0,0 +1,35 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.131.33.47164>192.168.204.67.4445",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "POST",
+ "uri": "http://:4445/RPC2",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "User-Agent": "ulxmlrpcpp/1.7.5",
+ "Connection": "Close",
+ "Content-Type": "text/xml",
+ "Date": "Sat Sep 7 10:04:57 2019",
+ "Content-Length": "468",
+ "__X_HTTP_URL": "http://:4445/RPC2",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Connection": "Close",
+ "Content-Type": "text/xml",
+ "Transfer-Encoding": "chunked",
+ "X-Powered-By": "ulxmlrpcpp/1.7.4",
+ "Date": "Sat Sep 7 01:09:08 2019",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_hdrs_exceed_maximum.json b/test/test_result_json/http_hdrs_exceed_maximum.json
new file mode 100644
index 0000000..09b7311
--- /dev/null
+++ b/test/test_result_json/http_hdrs_exceed_maximum.json
@@ -0,0 +1,46 @@
+[{
+ "__X_HTTP_TUPLE4": "10.0.0.1.61462>10.0.0.2.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/x/xx/xxxxxxxxxxxxxxxxxxx/x/xxxxxx/xxxxxxxxxxxxxxx?xxx=1&xxx=1&x=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&vmf=xxxxxxxxxx.xxx.xxx.xxx&ce=UTF-8&ns=xxxxxxxxxx&pageName=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&g=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.jsp&r=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&events=xxxxxxxxxxxxxxxxxxxxxxxxxxx&products=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&v1=xxxxxxxxxxxxxxx&v2=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&v17=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&c49=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&AQE=1",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "xxxxx.xxxxxxxx.xxxxxxxxxx.xxx",
+ "Connection": "keep-alive",
+ "Accept": "image/webp,*/*;q=0.8",
+ "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36",
+ "Referer": "http://www.xxxxxxxxxx.xxx/xx/xxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxx.jsp",
+ "Accept-Encoding": "gzip,deflate,sdch",
+ "Accept-Language": "en-US,en;q=0.8,en-GB;q=0.6",
+ "__X_HTTP_URL": "xxxxx.xxxxxxxx.xxxxxxxxxx.xxx/x/xx/xxxxxxxxxxxxxxxxxxx/x/xxxxxx/xxxxxxxxxxxxxxx?xxx=1&xxx=1&x=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&vmf=xxxxxxxxxx.xxx.xxx.xxx&ce=UTF-8&ns=xxxxxxxxxx&pageName=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&g=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.jsp&r=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&events=xxxxxxxxxxxxxxxxxxxxxxxxxxx&products=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&v1=xxxxxxxxxxxxxxx&v2=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&v17=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&c49=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&AQE=1",
+ "Cookie": "xxxxxxxxxxxxxxxxxxx=ie; xxxxxxxxxxxxxxxxxxxxxx=true; lp=xxxxxx; rememberUn=false; xxx.xxxxxxxxxx.xxxxxxxxxx=xx; xxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; autocomplete=1; xxxx=xxxx; xxxx=xxxxv1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; xxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
+ "__X_HTTP_RESULT_INDEX": "1"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Date": "Mon, 30 Jun 2014 13:35:21 GMT",
+ "Server": "xxxxxxxxxxxxxxxxx",
+ "Access-Control-Allow-Origin": "*",
+ "Set-Cookie": "xxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; Expires=Wed, 29 Jun 2016 13:35:21 GMT; Domain=.xxxxxxxxxx.xxx; Path=/",
+ "X-C": "ms-4.9",
+ "Expires": "Sun, 29 Jun 2014 13:35:21 GMT",
+ "Last-Modified": "Tue, 01 Jul 2014 13:35:21 GMT",
+ "Cache-Control": "no-cache, no-store, max-age=0, no-transform, private",
+ "Pragma": "no-cache",
+ "ETag": "\"xxxxxxxxxxxxxxxxxxxxxx\"",
+ "Vary": "*",
+ "P3P": "policyref=\"/w3c/p3p.xml\", CP=\"NOI DSP COR NID PSA OUR IND COM NAV STA\"",
+ "xserver": "xxxxxx",
+ "Content-Length": "43",
+ "Keep-Alive": "timeout=15",
+ "Connection": "Keep-Alive",
+ "Content-Type": "image/gif",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }]
diff --git a/test/test_result_json/http_multi_parse_error.json b/test/test_result_json/http_multi_parse_error.json
new file mode 100644
index 0000000..8111a6f
--- /dev/null
+++ b/test/test_result_json/http_multi_parse_error.json
@@ -0,0 +1,35 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.131.33.47172>192.168.204.67.4445",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "POST",
+ "uri": "http://:4445/RPC2",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "User-Agent": "ulxmlrpcpp/1.7.5",
+ "Connection": "Close",
+ "Content-Type": "text/xml",
+ "Date": "Sat Sep 7 10:05:13 2019",
+ "Content-Length": "468",
+ "__X_HTTP_URL": "http://:4445/RPC2",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Connection": "Close",
+ "Content-Type": "text/xml",
+ "Transfer-Encoding": "chunked",
+ "X-Powered-By": "ulxmlrpcpp/1.7.4",
+ "Date": "Sat Sep 7 01:09:24 2019",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_no_content_length.json b/test/test_result_json/http_no_content_length.json
new file mode 100644
index 0000000..93ca066
--- /dev/null
+++ b/test/test_result_json/http_no_content_length.json
@@ -0,0 +1,45 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "10.0.0.1.50384>10.0.0.2.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/js/xxxxxx.js",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "xxxxxxx.xxxxxx.xx",
+ "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3",
+ "Accept": "*/*",
+ "Accept-Language": "en-us,en;q=0.5",
+ "Accept-Encoding": "gzip,deflate",
+ "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
+ "Keep-Alive": "115",
+ "Connection": "keep-alive",
+ "Referer": "http://www.xxxxxxxx.com/xxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxx.html",
+ "Cookie": "trafic_ranking=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
+ "__X_HTTP_URL": "xxxxxxx.xxxxxx.xx/js/xxxxxx.js",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.0",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 0,
+ "status_code": 200,
+ "Date": "Mon, 10 May 2010 08:31:02 GMT",
+ "Server": "Apache",
+ "Content-type": "application/x-javascript",
+ "Expires": "Thu, 11 Jan 1973 16:00:00 GMT",
+ "Last-Modified": "Mon, 10 May 2010 08:31:02 GMT",
+ "Cache-Control": "no-store, no-cache, must-revalidate, post-check=0, pre-check=0",
+ "Pragma": "no-cache",
+ "P3P": "policyref=\"/w3c/p3p.xml\", CP=\"ALL IND DSP COR ADM CONo CUR IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI\"",
+ "Set-Cookie": "trafic_ranking=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; expires=Sun, 11-Jan-2037 14:00:00 GMT; path=/; domain=.xxxxxx.xx",
+ "connection": "close",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_over_pppoe.json b/test/test_result_json/http_over_pppoe.json
new file mode 100644
index 0000000..23856ca
--- /dev/null
+++ b/test/test_result_json/http_over_pppoe.json
@@ -0,0 +1,35 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "2a00:5e80:101:212d:504:7b1:2572:db22.37034>2606:f200:0:7:bad:f00d:d00d:1.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "User-Agent": "curl/7.34.0",
+ "Host": "ipv6.icanhazip.com",
+ "Accept": "*/*",
+ "__X_HTTP_URL": "ipv6.icanhazip.com/",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Date": "Thu, 02 Jan 2014 08:38:06 GMT",
+ "Server": "Apache",
+ "Content-Length": "38",
+ "Content-Type": "text/plain; charset=UTF-8",
+ "X-RTFM": "Learn about this site at http://bit.ly/14DAh2o and don't abuse the service",
+ "X-YOU-SHOULD-APPLY-FOR-A-JOB": "If you're reading this, apply here: http://rackertalent.com/",
+ "X-ICANHAZNODE": "icanhazip1.nugget",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_over_tcp_keepalive.json b/test/test_result_json/http_over_tcp_keepalive.json
new file mode 100644
index 0000000..1481cb7
--- /dev/null
+++ b/test/test_result_json/http_over_tcp_keepalive.json
@@ -0,0 +1,40 @@
+[{
+ "__X_HTTP_TUPLE4": "192.168.56.66.55356>60.190.243.167.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ }, {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "www.yumi.com",
+ "Connection": "keep-alive",
+ "Cache-Control": "max-age=0",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "zh-CN,zh;q=0.9",
+ "Cookie": "UM_distinctid=17d37645f9c1a1-0281befa480414-b7a1a38-144000-17d37645f9d336; CNZZDATA1258295942=1778021578-1637307701-%7C1637307701; Hm_lvt_a6dc86f6e27435039966e994bd7f0792=1637311872; yumi_sid=JaMlFyTA07ikpZjTHZsRTWyGdMqFyFy%2B4hXGj%2FSoQRJYbrfBUQuOTIMZ8jUGmugDC594AYcbeRhg75xidhRxCW4zq9Y0gPwTmkhq4LQuprp4DrtDMLI3L5wLMqkG%2FuAX1aVFPfud5GRNxNFTSp%2Bos%2FKhfCFKhfN5%2BuT2xyVYSAjy2ftiSOGDi7FN13icuuyPhFCoWqOxWVu1CZ3AiYPJssv6kXqiR6paf75icdeROZY2bkFCDKkcIQcPy7o9EKpkL1Mbimeb40JMg9hUsWdmyhDkzVjSHJmC4z2ujpzSDTsjRIQOnxTy1PHZi%2FMwg3uyGLCusDwqbagpO4pcgEJ5ONDy%2BGwO7FmHXU3mFfR56c9HxxiiuLPnBt9ErpqqWKsxH6lUrlHaUp6AzyrgX7PFdksiMfPSk6%2F3%2FWOYr%2FkYuI4fopw7z8%2FLhxC9AiLr9Czz3MngFUGzkmaMVvAhZOSPzg%3D%3D; Hm_lpvt_a6dc86f6e27435039966e994bd7f0792=1637313847",
+ "__X_HTTP_URL": "www.yumi.com/",
+ "__X_HTTP_RESULT_INDEX": "1"
+ }, {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "Tengine",
+ "Date": "Fri, 19 Nov 2021 09:57:40 GMT",
+ "Content-Type": "text/html",
+ "Transfer-Encoding": "chunked",
+ "Connection": "keep-alive",
+ "Vary": "Accept-Encoding",
+ "Set-Cookie": "yumi_sid=V6EhlyovLp46BBzQWLVOBg%2F73RUD5E%2FfaRlkR8RLa8aKhGrPVdVHvHfFWRKKd9wZ%2BfFF4Tb2wnVOOn%2F9iXbBpyHsbxjmUqnbFSoAX7QIJjt%2BEEjAL3M7O7VSpAyMnrFKt7qu46oXV%2B6teyyTUY7Ucy285v6otvZcu8bN%2B5YxKZ1gYh56iJ0bHxnrnQ0vvAx3l%2BLwfw2y0c5IaF2tjrL%2Fn83nrHsPoYYRWAR2zLIXD%2FEMKRtyerwsM5LKhZZteFGWD2w%2B15alKF5T65i0lPvPcAdaqpceL5xz23twQULhs1tIJsOfJZ8JudLlRy6x3DvxQYqRe2xTCex5c77zJqfq%2FdryNbBycIq9gf6C2hXDRwDqRqVgXDMadwGnooKFkv%2ByCbohjHyBCZJypBcYFmglYhin23UC9i%2B%2BOA%2FxhlxcnU8kT8udpTNCktSmF950SQLOmvdvYuXGydKs8v05cxe5fg%3D%3D; expires=Fri, 19-Nov-2021 11:57:38 GMT; Max-Age=7200; path=/; domain=.yumi.com",
+ "Pragma": "no-cache",
+ "Cache-Control": "no-store",
+ "Content-Encoding": "gzip",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }]
diff --git a/test/test_result_json/http_over_tls.json b/test/test_result_json/http_over_tls.json
new file mode 100644
index 0000000..32960f8
--- /dev/null
+++ b/test/test_result_json/http_over_tls.json
@@ -0,0 +1,2 @@
+[
+] \ No newline at end of file
diff --git a/test/test_result_json/http_post_multipart_form_data.json b/test/test_result_json/http_post_multipart_form_data.json
new file mode 100644
index 0000000..3e761dd
--- /dev/null
+++ b/test/test_result_json/http_post_multipart_form_data.json
@@ -0,0 +1,101 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.8.97.11371>192.168.57.14.8080",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/fileupload/",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "192.168.57.14:8080",
+ "Connection": "keep-alive",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+ "User-Agent": "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36",
+ "Accept-Encoding": "gzip,deflate,sdch",
+ "Accept-Language": "zh-CN,zh;q=0.8",
+ "Cookie": "JSESSIONID=969AC5FBD069EE6218EB10513726B244; JSESSIONID=400CC78DF5784F303702CC7F02C6122C",
+ "__X_HTTP_URL": "192.168.57.14:8080/fileupload/",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "Apache-Coyote/1.1",
+ "Content-Type": "text/html;charset=UTF-8",
+ "Content-Length": "468",
+ "Date": "Thu, 28 Mar 2019 08:13:33 GMT",
+ "__X_HTTP_RESULT_INDEX": "2"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/fileupload/",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "192.168.57.14:8080",
+ "Connection": "keep-alive",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+ "User-Agent": "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36",
+ "Accept-Encoding": "gzip,deflate,sdch",
+ "Accept-Language": "zh-CN,zh;q=0.8",
+ "Cookie": "JSESSIONID=969AC5FBD069EE6218EB10513726B244; JSESSIONID=400CC78DF5784F303702CC7F02C6122C",
+ "__X_HTTP_URL": "192.168.57.14:8080/fileupload/",
+ "__X_HTTP_RESULT_INDEX": "3"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "Apache-Coyote/1.1",
+ "Content-Type": "text/html;charset=UTF-8",
+ "Content-Length": "468",
+ "Date": "Thu, 28 Mar 2019 08:13:33 GMT",
+ "__X_HTTP_RESULT_INDEX": "4"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "POST",
+ "uri": "/fileupload/servlet/UploadHandleServlet",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "192.168.57.14:8080",
+ "Connection": "keep-alive",
+ "Content-Length": "449",
+ "Cache-Control": "max-age=0",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+ "Origin": "http://192.168.57.14:8080",
+ "User-Agent": "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36",
+ "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryAe47vGj7ybAe6RwO",
+ "Referer": "http://192.168.57.14:8080/fileupload/",
+ "Accept-Encoding": "gzip,deflate,sdch",
+ "Accept-Language": "zh-CN,zh;q=0.8",
+ "Cookie": "JSESSIONID=969AC5FBD069EE6218EB10513726B244; JSESSIONID=400CC78DF5784F303702CC7F02C6122C",
+ "__X_HTTP_URL": "192.168.57.14:8080/fileupload/servlet/UploadHandleServlet",
+ "__X_HTTP_RESULT_INDEX": "5"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Server": "Apache-Coyote/1.1",
+ "Content-Type": "text/html;charset=UTF-8",
+ "Content-Length": "144",
+ "Date": "Thu, 28 Mar 2019 08:13:37 GMT",
+ "__X_HTTP_RESULT_INDEX": "6"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_req_1byte_sliding_window.json b/test/test_result_json/http_req_1byte_sliding_window.json
new file mode 100644
index 0000000..c295389
--- /dev/null
+++ b/test/test_result_json/http_req_1byte_sliding_window.json
@@ -0,0 +1,34 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.40.137.46180>192.168.42.40.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/index.html",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "User-Agent": "Wget/1.14 (linux-gnu)",
+ "Accept": "*/*",
+ "Host": "192.168.42.40",
+ "__X_HTTP_URL": "192.168.42.40/index.html",
+ "Connection": "Keep-Alive",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.0",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 0,
+ "status_code": 200,
+ "Server": "SimpleHTTP/0.6 Python/2.7.5",
+ "Date": "Fri, 29 Dec 2023 09:11:12 GMT",
+ "Content-type": "text/html",
+ "Content-Length": "144",
+ "Last-Modified": "Fri, 29 Dec 2023 08:50:53 GMT",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_res_1byte_sliding_window.json b/test/test_result_json/http_res_1byte_sliding_window.json
new file mode 100644
index 0000000..60b756d
--- /dev/null
+++ b/test/test_result_json/http_res_1byte_sliding_window.json
@@ -0,0 +1,34 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.42.40.36338>192.168.40.137.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/index.html",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "User-Agent": "Wget/1.14 (linux-gnu)",
+ "Accept": "*/*",
+ "Host": "192.168.40.137",
+ "Connection": "Keep-Alive",
+ "__X_HTTP_URL": "192.168.40.137/index.html",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.0",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 0,
+ "status_code": 200,
+ "Server": "SimpleHTTP/0.6 Python/2.7.5",
+ "Date": "Fri, 29 Dec 2023 09:32:21 GMT",
+ "Content-type": "text/html",
+ "Content-Length": "144",
+ "Last-Modified": "Fri, 29 Dec 2023 08:50:53 GMT",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_res_gzip.json b/test/test_result_json/http_res_gzip.json
new file mode 100644
index 0000000..357dbe9
--- /dev/null
+++ b/test/test_result_json/http_res_gzip.json
@@ -0,0 +1,44 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.69.2.34059>192.168.69.1.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/test/ethereal.html",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "cerberus",
+ "User-Agent": "Mozilla/5.0 (X11; U; Linux ppc; rv:1.7.3) Gecko/20041004 Firefox/0.10.1",
+ "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
+ "Accept-Language": "en-us,en;q=0.5",
+ "Accept-Encoding": "gzip,deflate",
+ "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
+ "Keep-Alive": "300",
+ "Connection": "keep-alive",
+ "Cookie": "FGNCLIID=05c04axp1yaqynldtcdiwis0ag1",
+ "__X_HTTP_URL": "cerberus/test/ethereal.html",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Date": "Fri, 29 Oct 2004 05:21:00 GMT",
+ "Server": "Apache/2.0.50 (Fedora)",
+ "Last-Modified": "Fri, 29 Oct 2004 05:20:21 GMT",
+ "ETag": "\"126e1f-6d-371b2f40\"",
+ "Accept-Ranges": "bytes",
+ "Vary": "Accept-Encoding",
+ "Content-Encoding": "gzip",
+ "Content-Length": "92",
+ "Connection": "close",
+ "Content-Type": "text/html; charset=UTF-8",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_trans_pipeline.json b/test/test_result_json/http_trans_pipeline.json
new file mode 100644
index 0000000..c9b5d37
--- /dev/null
+++ b/test/test_result_json/http_trans_pipeline.json
@@ -0,0 +1,368 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "223.72.39.14.2545>192.168.182.147.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/postinfo.html",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/postinfo.html",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_bin/_vti_aut/author.dll",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/_vti_aut/author.dll",
+ "__X_HTTP_RESULT_INDEX": "2"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_bin/_vti_aut/author.exe",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/_vti_aut/author.exe",
+ "__X_HTTP_RESULT_INDEX": "3"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_bin/_vti_aut/dvwssr.dll",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/_vti_aut/dvwssr.dll",
+ "__X_HTTP_RESULT_INDEX": "4"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_bin/_vti_adm/admin.dll",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/_vti_adm/admin.dll",
+ "__X_HTTP_RESULT_INDEX": "5"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_bin/_vti_adm/admin.exe",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/_vti_adm/admin.exe",
+ "__X_HTTP_RESULT_INDEX": "6"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_bin/fpcount.exe?Page=default.asp|Image=3",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/fpcount.exe?Page=default.asp|Image=3",
+ "__X_HTTP_RESULT_INDEX": "7"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:01 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "8"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:02 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "9"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:03 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "10"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:04 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "11"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:05 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "12"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_bin/shtml.dll",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/shtml.dll",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "13"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_bin/shtml.exe",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_bin/shtml.exe",
+ "__X_HTTP_RESULT_INDEX": "14"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_pvt/_x_todo.htm",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_pvt/_x_todo.htm",
+ "__X_HTTP_RESULT_INDEX": "15"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_pvt/_x_todoh.htm",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_pvt/_x_todoh.htm",
+ "__X_HTTP_RESULT_INDEX": "16"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_pvt/access.cnf",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_pvt/access.cnf",
+ "__X_HTTP_RESULT_INDEX": "17"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_pvt/administrator.pwd",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_pvt/administrator.pwd",
+ "__X_HTTP_RESULT_INDEX": "18"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_pvt/administrators.pwd",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_pvt/administrators.pwd",
+ "__X_HTTP_RESULT_INDEX": "19"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_pvt/authors.pwd",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_pvt/authors.pwd",
+ "__X_HTTP_RESULT_INDEX": "20"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:06 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "21"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:07 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "22"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:08 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "23"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:09 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "24"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:10 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "25"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/_vti_pvt/bots.cnf",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "116.181.2.152",
+ "User-Agent": "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)",
+ "Connection": "keep-alive",
+ "__X_HTTP_URL": "116.181.2.152/_vti_pvt/bots.cnf",
+ "__X_HTTP_RESULT_INDEX": "26"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Not Found",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 404,
+ "Server": "nginx",
+ "Date": "Thu, 29 Oct 2020 09:59:11 GMT",
+ "Content-Type": "text/html",
+ "Content-Length": "146",
+ "Connection": "keep-alive",
+ "__X_HTTP_RESULT_INDEX": "27"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_tunnel_for_pop3.json b/test/test_result_json/http_tunnel_for_pop3.json
new file mode 100644
index 0000000..7956a50
--- /dev/null
+++ b/test/test_result_json/http_tunnel_for_pop3.json
@@ -0,0 +1,33 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.10.58.51798>192.168.10.144.808",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "CONNECT",
+ "uri": "pop.163.com:110",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Content-Length": "0",
+ "Accept": "*/*",
+ "User-Agent": "Foxmail 7, 1, 3, 48[cn]",
+ "Accept-Encoding": "gzip, deflate",
+ "Proxy-Connection": "Keep-Alive",
+ "Connection": "Keep-Alive",
+ "Host": "192.168.10.144",
+ "__X_HTTP_URL": "192.168.10.144pop.163.com:110",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Connection established",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Proxy-agent": "CCProxy",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_upgrade_http2.json b/test/test_result_json/http_upgrade_http2.json
new file mode 100644
index 0000000..3d455a5
--- /dev/null
+++ b/test/test_result_json/http_upgrade_http2.json
@@ -0,0 +1,42 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "10.9.0.2.58038>139.162.123.134.80",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/robots.txt",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "nghttp2.org",
+ "User-Agent": "curl/7.61.0",
+ "Accept": "*/*",
+ "Connection": "Upgrade, HTTP2-Settings",
+ "Upgrade": "h2c",
+ "HTTP2-Settings": "AAMAAABkAARAAAAAAAIAAAAA",
+ "__X_HTTP_URL": "nghttp2.org/robots.txt",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "PRI",
+ "uri": "*",
+ "req_version": "2.0",
+ "major_version": 2,
+ "minor_version": 0,
+ "__X_HTTP_RESULT_INDEX": "2"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Switching Protocols",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 101,
+ "Connection": "Upgrade",
+ "Upgrade": "h2c",
+ "__X_HTTP_RESULT_INDEX": "3"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_upgrade_websocket.json b/test/test_result_json/http_upgrade_websocket.json
new file mode 100644
index 0000000..33e7336
--- /dev/null
+++ b/test/test_result_json/http_upgrade_websocket.json
@@ -0,0 +1,42 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "131.179.196.220.59631>131.179.196.46.9696",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "spurs.cs.ucla.edu:9696",
+ "Connection": "Upgrade",
+ "Pragma": "no-cache",
+ "Cache-Control": "no-cache",
+ "Upgrade": "websocket",
+ "Origin": "null",
+ "Sec-WebSocket-Version": "13",
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36",
+ "Accept-Encoding": "gzip, deflate, sdch",
+ "Accept-Language": "en-US,en;q=0.8,lv;q=0.6,ru;q=0.4",
+ "Cookie": "s_cc=true; s_sq=%5B%5BB%5D%5D; iwe_user_noticecount_urn%3amace%3aucla.edu%3appid%3aperson%3a1223EF7211FC4EC1965579D0B8D85FBA=2; __utma=125574670.1759122974.1407127284.1407127284.1415755402.2; __utmc=125574670; __utma=126236063.2139843507.1390525421.1433785187.1435706244.46; __utmc=126236063; __utmz=126236063.1427934389.33.5.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); _ucla_sso=2015-07-02T11%3A34%3A30-07%3A00; _ga=GA1.2.1759122974.1407127284",
+ "Sec-WebSocket-Key": "sgD1adxQ3mk6BbBqab7owA==",
+ "Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits",
+ "__X_HTTP_URL": "spurs.cs.ucla.edu:9696/",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.1",
+ "res_status": "Switching Protocols",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 101,
+ "Connection": "upgrade",
+ "Sec-WebSocket-Accept": "FRh9fmH0UaoLdY5BSFO4hP2Pcjw=",
+ "Server": "WebSocket++/0.5.1",
+ "Upgrade": "websocket",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_url_test_with_host.json b/test/test_result_json/http_url_test_with_host.json
new file mode 100644
index 0000000..a7fe660
--- /dev/null
+++ b/test/test_result_json/http_url_test_with_host.json
@@ -0,0 +1,35 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.244.1.52412>192.168.244.128.8080",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/urltest/ttt",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "192.168.244.128:8080",
+ "Connection": "keep-alive",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
+ "__X_HTTP_URL": "192.168.244.128:8080/urltest/ttt",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.0",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 0,
+ "status_code": 200,
+ "Server": "BaseHTTP/0.6 Python/3.6.8",
+ "Date": "Thu, 14 Mar 2024 07:37:43 GMT",
+ "Content-type": "application/json",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/http_url_test_without_host.json b/test/test_result_json/http_url_test_without_host.json
new file mode 100644
index 0000000..9c91498
--- /dev/null
+++ b/test/test_result_json/http_url_test_without_host.json
@@ -0,0 +1,29 @@
+[
+ {
+ "__X_HTTP_TUPLE4": "192.168.244.128.44868>192.168.244.128.8080",
+ "__X_HTTP_RESULT_INDEX": "0"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "request",
+ "method": "GET",
+ "uri": "/urltest/ttt",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "User-Agent": "no h",
+ "__X_HTTP_URL": "192.168.244.128:8080/urltest/ttt",
+ "__X_HTTP_RESULT_INDEX": "1"
+ },
+ {
+ "__X_HTTP_TRANSACTION": "response",
+ "res_version": "1.0",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 0,
+ "status_code": 200,
+ "Server": "BaseHTTP/0.6 Python/3.6.8",
+ "Date": "Thu, 14 Mar 2024 06:15:20 GMT",
+ "Content-type": "application/json",
+ "__X_HTTP_RESULT_INDEX": "2"
+ }
+] \ No newline at end of file
diff --git a/test/test_result_json/non_http.json b/test/test_result_json/non_http.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/test/test_result_json/non_http.json
@@ -0,0 +1 @@
+[] \ No newline at end of file