summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlijia <[email protected]>2024-04-19 18:22:14 +0800
committerlijia <[email protected]>2024-04-19 18:30:11 +0800
commitba62d9af146b14e959f6dfd55331411f3ea8e4cd (patch)
tree249d963dbea1c1e7301ccaa5accc450100e038a3
parentf40db506ee7570e836ac97b7806a679bc36da155 (diff)
perf: Do not cache the uri, method if request line is complete, for TSG-20459.
-rw-r--r--src/http_decoder_half.c28
-rw-r--r--test/CMakeLists.txt4
-rw-r--r--test/http_decoder_perf.cpp141
3 files changed, 165 insertions, 8 deletions
diff --git a/src/http_decoder_half.c b/src/http_decoder_half.c
index d5f8336..7af1956 100644
--- a/src/http_decoder_half.c
+++ b/src/http_decoder_half.c
@@ -58,6 +58,9 @@ struct http_decoder_half
long long trans_counter;
long long err_counter;
long long transaction_seq;
+
+ const char *data;
+ int data_len;
};
// #define HTTP_DECODER_DEBUG
@@ -202,6 +205,17 @@ static int on_reset(llhttp_t *http)
return 0;
}
+static inline int is_line_eof(struct http_decoder_half *half)
+{
+ const char *chr_r = memrchr(half->data, '\r', half->data_len);
+ const char *chr_n = memrchr(half->data, '\n', half->data_len);
+ if (chr_r && chr_n && (chr_r + 1 == chr_n))
+ {
+ return 1;
+ }
+ return 0;
+}
+
static int on_method(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_method", at, length);
@@ -224,8 +238,7 @@ static int on_method_complete(llhttp_t *http)
container_of(http, struct http_decoder_half, parser);
assert(half);
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_METHOD) ==
- STRING_STATE_REFER)
+ if (is_line_eof(half) == 0)
{
http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_METHOD);
}
@@ -278,8 +291,7 @@ static int on_uri_complete(llhttp_t *http)
container_of(http, struct http_decoder_half, parser);
assert(half);
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_URI) ==
- STRING_STATE_REFER)
+ if (is_line_eof(half) == 0)
{
http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_URI);
}
@@ -317,8 +329,7 @@ static int on_version_complete(llhttp_t *http)
container_of(http, struct http_decoder_half, parser);
assert(half);
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_VERSION) ==
- STRING_STATE_REFER)
+ if (is_line_eof(half) == 0)
{
http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_VERSION);
}
@@ -363,8 +374,7 @@ static int on_status_complete(llhttp_t *http)
container_of(http, struct http_decoder_half, parser);
assert(half);
- if (http_decoder_table_state(half->ref_data->table, HTTP_ITEM_STATUS) ==
- STRING_STATE_REFER)
+ if (is_line_eof(half) == 0)
{
http_decoder_table_cache(half->ref_data->table, HTTP_ITEM_STATUS);
}
@@ -737,6 +747,8 @@ int http_decoder_half_parse(struct http_decoder_half *half, const char *data,
return -1;
}
+ half->data = (const char *)data;
+ half->data_len = data_len;
half->error = llhttp_execute(&half->parser, data, data_len);
int ret = 0;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index c326838..4869a90 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -5,6 +5,10 @@ add_dependencies(${DECODER_NAME}_test ${DECODER_NAME})
target_link_libraries(${DECODER_NAME}_test MESA_prof_load cjson-static)
set_target_properties(${DECODER_NAME}_test PROPERTIES PREFIX "")
+add_library(${DECODER_NAME}_perf SHARED http_decoder_perf.cpp)
+add_dependencies(${DECODER_NAME}_perf ${DECODER_NAME})
+set_target_properties(${DECODER_NAME}_perf PROPERTIES PREFIX "")
+
set(TEST_RUN_DIR ${CMAKE_BINARY_DIR}/testing)
include_directories(${CMAKE_SOURCE_DIR}/include)
diff --git a/test/http_decoder_perf.cpp b/test/http_decoder_perf.cpp
new file mode 100644
index 0000000..767de46
--- /dev/null
+++ b/test/http_decoder_perf.cpp
@@ -0,0 +1,141 @@
+
+#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"
+#include "md5.h"
+}
+#endif
+
+#define MAX_KEY_STR_LEN 2048
+
+static int g_result_count = 0;
+static int g_header_count = 1;
+static int g_exdata_idx = 0;
+static int g_topic_id = 0;
+
+extern "C" int http_decoder_perf_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);
+ void *ret1, *ret2;
+
+ switch (msg_type)
+ {
+ case HTTP_MESSAGE_REQ_LINE:
+ http_message_get_request_line(msg, &req_line);
+ if (req_line.uri.str)
+ {
+ ret1 = memmem(req_line.uri.str, req_line.uri.str_len, "index", 5);
+ }
+ break;
+ case HTTP_MESSAGE_REQ_HEADER:
+ while (http_message_header_next(msg, &header) >= 0)
+ {
+ ret1 = memmem(header.key.str, header.key.str_len, "key", 3);
+ ret2 = memmem(header.val.str, header.val.str_len, "val", 3);
+ }
+ break;
+ case HTTP_MESSAGE_REQ_BODY:
+ // http_message_get_request_raw_body(msg, &body);
+ // output_http_body(&body, 0);
+ http_message_get_decompress_body(msg, &body);
+ // output_http_body(&body, 1);
+ ret1 = memmem(body.str, body.str_len, "</html>", 7);
+ break;
+ case HTTP_MESSAGE_RES_LINE:
+ http_message_get_response_line(msg, &res_line);
+ ret1 = memmem(res_line.status.str, res_line.status.str_len, "OK", 2);
+ break;
+ case HTTP_MESSAGE_RES_HEADER:
+ while (http_message_header_next(msg, &header) >= 0)
+ {
+ ret1 = memmem(header.key.str, header.key.str_len, "key", 3);
+ ret2 = memmem(header.val.str, header.val.str_len, "val", 3);
+ }
+ break;
+ case HTTP_MESSAGE_RES_BODY:
+ // http_message_get_response_raw_body(msg, &body);
+ // output_http_body(&body, 0);
+ http_message_get_decompress_body(msg, &body);
+ // output_http_body(&body, 1);
+ ret1 = memmem(body.str, body.str_len, "</html>", 7);
+ break;
+
+ // to do: check payload
+ default:
+ break;
+ }
+
+ if(ret1 && ret2){
+ return 1;
+ }
+ return 0;
+}
+
+static int (*g_entry_fun)(struct session *sess, int topic_id, const void *data, void *cb_arg) = &http_decoder_perf_entry;
+
+static void http_decoder_test_exdata_free(struct session *sess, int idx, void *ex_ptr, void *arg)
+{
+ return;
+}
+
+extern "C" void *http_decoder_perf_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, g_entry_fun, NULL);
+ // printf("http_decoder_test_init OK!\n");
+
+ return NULL;
+}
+
+extern "C" void http_decoder_perf_exit(void *test_ctx)
+{
+ if (test_ctx != NULL)
+ {
+ FREE(test_ctx);
+ }
+
+ printf("http_decoder_perf plug exit OK!\n");
+}
+
+extern "C" void http_decoder_plug_set_entry_fuc(HTTP_DECODER_PLUG_ENTRY_FUN_T entry_fun)
+{
+ g_entry_fun = entry_fun;
+} \ No newline at end of file