summaryrefslogtreecommitdiff
path: root/adapter
diff options
context:
space:
mode:
Diffstat (limited to 'adapter')
-rw-r--r--adapter/CMakeLists.txt3
-rw-r--r--adapter/http_adapter/conf/http_adapter.inf9
-rw-r--r--adapter/http_adapter/lua/conflist_lua.inf2
-rw-r--r--adapter/http_adapter/lua/http_request/http_request.inf3
-rw-r--r--adapter/http_adapter/lua/http_request/http_request.lua87
-rw-r--r--adapter/http_adapter/lua/http_response/http_response.inf3
-rw-r--r--adapter/http_adapter/lua/http_response/http_response.lua57
-rw-r--r--adapter/http_adapter/script/deploy.sh11
-rw-r--r--adapter/http_adapter/src/adapter.cpp458
-rw-r--r--adapter/http_adapter/src/adapter.h112
10 files changed, 745 insertions, 0 deletions
diff --git a/adapter/CMakeLists.txt b/adapter/CMakeLists.txt
new file mode 100644
index 0000000..92dedbf
--- /dev/null
+++ b/adapter/CMakeLists.txt
@@ -0,0 +1,3 @@
+### http_adapter
+add_library(http_adapter SHARED http_adapter/src/adapter.cpp)
+target_link_libraries(http_adapter lua-static dl MESA_handle_logger MESA_htable MESA_prof_load) \ No newline at end of file
diff --git a/adapter/http_adapter/conf/http_adapter.inf b/adapter/http_adapter/conf/http_adapter.inf
new file mode 100644
index 0000000..d9b827c
--- /dev/null
+++ b/adapter/http_adapter/conf/http_adapter.inf
@@ -0,0 +1,9 @@
+[PLUGINFO]
+PLUGNAME = http_adapter
+SO_PATH = ./plug/business/http_adapter/libhttp_adapter.so
+INIT_FUNC = http_adapter_init
+DESTROY_FUNC = http_adapter_destroy
+
+[HTTP]
+FUNC_FLAG = ALL
+FUNC_NAME = http_adapter_http_entry
diff --git a/adapter/http_adapter/lua/conflist_lua.inf b/adapter/http_adapter/lua/conflist_lua.inf
new file mode 100644
index 0000000..401ea6b
--- /dev/null
+++ b/adapter/http_adapter/lua/conflist_lua.inf
@@ -0,0 +1,2 @@
+./plug/lua/http_request/http_request.inf
+./plug/lua/http_response/http_response.inf
diff --git a/adapter/http_adapter/lua/http_request/http_request.inf b/adapter/http_adapter/lua/http_request/http_request.inf
new file mode 100644
index 0000000..d8d37d6
--- /dev/null
+++ b/adapter/http_adapter/lua/http_request/http_request.inf
@@ -0,0 +1,3 @@
+[main]
+file_path = ./plug/lua/http_request/http_request.lua
+entry_type = http \ No newline at end of file
diff --git a/adapter/http_adapter/lua/http_request/http_request.lua b/adapter/http_adapter/lua/http_request/http_request.lua
new file mode 100644
index 0000000..9d9197f
--- /dev/null
+++ b/adapter/http_adapter/lua/http_request/http_request.lua
@@ -0,0 +1,87 @@
+---http_request.lua: 结果打印出来
+function printf(s,...)
+ io.write(s:format(...))
+ io.flush()
+end
+
+function format_write_file(file, s, ...)
+ file:write(s:format(...))
+ file:flush()
+end
+
+function init()
+ ---init something
+end
+
+function print_header(header)
+ for k, v in pairs(header) do
+ if k == "HTTP_OTHER_REGIONS" then
+ format_write_file(file, "%s: ", k)
+ for k, v in pairs(header["HTTP_OTHER_REGIONS"]) do
+ format_write_file(file, "{%s} ", v)
+ end
+ format_write_file(file, "\n")
+ else
+ format_write_file(file, "%s: %s\n", k, v)
+ end
+ end
+end
+
+function process()
+ printf("\nprint stream: \n")
+ stream_info = get_stream_info()
+ for k, v in pairs(stream_info) do
+ printf("%s: %s\n", k, v)
+ end
+
+ printf("\nprint header:\n")
+ local regions = {"ALL"}
+ header = get_http_request_header(regions)
+ for k, v in pairs(header) do
+ printf("%s: %s\n", k, v)
+ end
+
+ printf("\nprint body: \n")
+ while true do
+ body = get_http_request_body()
+ for k, v in pairs(body) do
+ printf("%s: %s\n", k, v)
+ end
+ if body['data_end'] == true then
+ break
+ end
+ end
+
+ --[[
+ file = io.open("./log/lua_sapp/http_adapter/lua/http_request.log", "a+")
+ format_write_file(file, "lua: call process\n")
+
+ format_write_file(file, "\nprint stream info: \n")
+ stream_info = get_stream_info()
+ for k, v in pairs(stream_info) do
+ format_write_file(file, "%s: %s\n", k, v)
+ end
+
+ format_write_file(file, "\nprint request headers: \n")
+ local req_regions = {"HTTP_HOST", "HTTP_REQ_LINE", "HTTP_OTHER_REGIONS"}
+ req_header = get_http_request_header(req_regions)
+ print_header(req_header)
+
+
+ format_write_file(file, "\nprint request body: \n")
+ while true do
+ body = get_http_request_body()
+ for k, v in pairs(body) do
+ format_write_file(file, "%s: %s\n", k, v)
+ end
+ if body['data_end'] == true then
+ format_write_file(file, "request body end\n")
+ break
+ end
+ format_write_file(file, "\n");
+ end
+ format_write_file(file, "\nlua: process end\n")
+ io.close(file)
+ ]]
+
+end \ No newline at end of file
diff --git a/adapter/http_adapter/lua/http_response/http_response.inf b/adapter/http_adapter/lua/http_response/http_response.inf
new file mode 100644
index 0000000..e80eef9
--- /dev/null
+++ b/adapter/http_adapter/lua/http_response/http_response.inf
@@ -0,0 +1,3 @@
+[main]
+file_path = ./plug/lua/http_response/http_response.lua
+entry_type = http \ No newline at end of file
diff --git a/adapter/http_adapter/lua/http_response/http_response.lua b/adapter/http_adapter/lua/http_response/http_response.lua
new file mode 100644
index 0000000..7e23fa3
--- /dev/null
+++ b/adapter/http_adapter/lua/http_response/http_response.lua
@@ -0,0 +1,57 @@
+
+---结果输出到文件中: ./log/lua_sapp/http_adapter/lua/http_response.log
+function printf(s,...)
+ io.write(s:format(...))
+ io.flush()
+end
+
+function format_write_file(file, s, ...)
+ file:write(s:format(...))
+ file:flush()
+end
+
+function init()
+ ---init something
+end
+
+function print_header(header)
+ for k, v in pairs(header) do
+ if k == "HTTP_OTHER_REGIONS" then
+ format_write_file(file, "%s: ", k)
+ for k, v in pairs(header["HTTP_OTHER_REGIONS"]) do
+ format_write_file(file, "{%s} ", v)
+ end
+ format_write_file(file, "\n")
+ else
+ format_write_file(file, "%s: %s\n", k, v)
+ end
+ end
+end
+
+function process()
+ file = io.open("./log/lua_sapp/http_adapter/lua/http_response.log", "a+")
+ format_write_file(file, "lua: call process\n")
+ format_write_file(file, "\nprint stream info: \n")
+ stream_info = get_stream_info()
+ for k, v in pairs(stream_info) do
+ format_write_file(file, "%s: %s\n", k, v)
+ end
+
+ local resp_regions = {"HTTP_SERVER", "HTTP_RES_LINE", "HTTP_OTHER_REGIONS"}
+ format_write_file(file, "\nprint response headers: \n")
+ resp_header = get_http_response_header(resp_regions)
+ print_header(resp_header)
+
+ format_write_file(file, "\nprint response body: \n")
+ while true do
+ body = get_http_response_body()
+ for k, v in pairs(body) do
+ format_write_file(file, "%s: %s\n", k, v)
+ end
+ if body['data_end'] == true then
+ format_write_file(file, "response body end\n")
+ break
+ end
+ end
+ format_write_file(file, "\nlua: process end\n")
+end \ No newline at end of file
diff --git a/adapter/http_adapter/script/deploy.sh b/adapter/http_adapter/script/deploy.sh
new file mode 100644
index 0000000..574960a
--- /dev/null
+++ b/adapter/http_adapter/script/deploy.sh
@@ -0,0 +1,11 @@
+SAPP_RUN=$1
+if [ "${SAPP_RUN}" = "" ]; then
+echo "USAGE: sh build_rpm.sh sapp_path" && exit 0
+fi
+mkdir -p $SAPP_RUN/plug/business/http_adapter
+/bin/cp -f adapter/libhttp_adapter.so $SAPP_RUN/plug/business/http_adapter/libhttp_adapter.so
+/bin/cp -f ../adapter/http_adapter/conf/http_adapter.inf $SAPP_RUN/plug/business/http_adapter/http_adapter.inf
+/bin/cp -rf ../adapter/http_adapter/lua $SAPP_RUN/plug
+mkdir -p $SAPP_RUN/log/lua_sapp/http_adapter/lua/
+cat $SAPP_RUN/plug/business/conflist_business.inf | grep "http_adapter.inf" >/dev/null 2>&1 && exit
+echo ./plug/business/http_adapter/http_adapter.inf >> $SAPP_RUN/plug/business/conflist_business.inf \ No newline at end of file
diff --git a/adapter/http_adapter/src/adapter.cpp b/adapter/http_adapter/src/adapter.cpp
new file mode 100644
index 0000000..94cd70f
--- /dev/null
+++ b/adapter/http_adapter/src/adapter.cpp
@@ -0,0 +1,458 @@
+#include "adapter.h"
+
+//TODO:
+//每个函数都要判断返回值 done
+// lua错误处理,比如函数没有注册,resume的返回值判断然后打印错误, 不再resume该协程 done
+//压栈之前要check_stack done
+//流结束clear_ctx之外还要释放该协程,自动垃圾回收?做实验验证一下 done
+//destroy,释放lua_state done
+//多线程 m * n个虚拟机(m是线程数量,n是lua插件数量) done
+//错误处理,日志, 工程化,日志完备
+
+static void* g_logger = NULL;
+static std::vector<std::vector<lua_State*>> g_http_lua_states;
+extern int g_iThreadNum;
+
+static void lua_traceback(const char *func_name, lua_State *lua_state, int ret){
+ int n = lua_gettop(lua_state);
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "%s error: ret is %d, traceback is: ", func_name, ret);
+ for(int i = -1; i >= 0 - n; i--){
+ std::string type = std::string(lua_typename(lua_state, lua_type(lua_state, i)));
+ if(type == "string"){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "%s", lua_tostring(lua_state, i));
+ }
+ }
+ lua_pop(lua_state, n);
+}
+
+std::string _inet_ntoa(uint32_t ip)
+{
+ const char *_ip = inet_ntoa(*(struct in_addr *)&ip);
+ return std::string(_ip);
+}
+
+//copy from suricata
+static int lua_push_string_buffer(lua_State *lua_state, const char *input, size_t input_len)
+{
+ if (input_len % 4 != 0) {
+ /* we're using a buffer sized at a multiple of 4 as lua_pushlstring generates
+ * invalid read errors in valgrind otherwise. Adding in a nul to be sure.
+ * Buffer size = len + 1 (for nul) + whatever makes it a multiple of 4 */
+ size_t buflen = input_len + 1 + ((input_len + 1) % 4);
+ char buf[buflen];
+ memset(buf, 0x00, buflen);
+ memcpy(buf, input, input_len);
+ buf[input_len] = '\0';
+ /* return value through lua_state, as a luastring */
+ lua_pushlstring(lua_state, buf, input_len);
+ } else {
+ lua_pushlstring(lua_state, input, input_len);
+ }
+ return 1;
+}
+
+static int get_stream_tuple5(lua_State *lua_state){
+ lua_getglobal(lua_state, "cur_http_sess_ctx");
+ http_sess_ctx *sess_ctx = (http_sess_ctx *)lua_touserdata(lua_state, -1);
+ lua_pop(lua_state, 1);
+ if(sess_ctx == NULL){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "sess_ctx is null");
+ return -1;
+ }
+ stream_tuple5& tuple5 = sess_ctx->tuple5;
+ if(tuple5.parse_done == true){
+ lua_newtable(lua_state);
+ lua_push_string_buffer(lua_state, "ip_version", std::string("ip_version").length());
+ lua_push_string_buffer(lua_state, tuple5.ip_version.c_str(), tuple5.ip_version.length());
+ lua_settable(lua_state, -3);
+ lua_push_string_buffer(lua_state, "stream_type", std::string("stream_type").length());
+ lua_push_string_buffer(lua_state, tuple5.stream_type.c_str(), tuple5.stream_type.length());
+ lua_settable(lua_state, -3);
+ lua_push_string_buffer(lua_state, "sip", std::string("sip").length());
+ lua_push_string_buffer(lua_state, tuple5.sip.c_str(), tuple5.sip.length());
+ lua_settable(lua_state, -3);
+ lua_push_string_buffer(lua_state, "dip", std::string("dip").length());
+ lua_push_string_buffer(lua_state, tuple5.dip.c_str(), tuple5.dip.length());
+ lua_settable(lua_state, -3);
+ lua_push_string_buffer(lua_state, "sport", std::string("sport").length());
+ lua_pushinteger(lua_state, tuple5.sport);
+ lua_settable(lua_state, -3);
+ lua_push_string_buffer(lua_state, "dport", std::string("dport").length());
+ lua_pushinteger(lua_state, tuple5.dport);
+ lua_settable(lua_state, -3);
+ return 0;
+ }
+ return -1;
+}
+
+static int _get_stream_info(lua_State *lua_state, int status, lua_KContext yieldk_ctx){
+ int ret = get_stream_tuple5(lua_state);
+ if(ret < 0){
+ lua_yieldk(lua_state, 0, 0, _get_stream_info);
+ }
+ return 1;
+}
+
+static int get_stream_info(lua_State* lua_state){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_DEBUG, LOG_MODULE_NAME, "call get_strem_info");
+ return _get_stream_info(lua_state, 0, 0);
+}
+
+static int get_http_header(lua_State *lua_state, int type){
+ lua_getglobal(lua_state, "cur_http_sess_ctx");
+ http_sess_ctx *sess_ctx = (http_sess_ctx *)lua_touserdata(lua_state, -1);
+ lua_pop(lua_state, 1);
+ if(sess_ctx == NULL){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "sess_ctx is null");
+ return -1;
+ }
+ std::unordered_set<std::string> required_regions;
+ lua_pushnil(lua_state);
+ while(lua_next(lua_state, -2) != 0){
+ required_regions.insert(std::string(lua_tostring(lua_state, -1)));
+ lua_pop(lua_state, 1);
+ }
+ http_header& header = (type == HTTP_TYPE_REQUEST ? sess_ctx->req_header : sess_ctx->resp_header);
+ if(header.parse_done == true){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_DEBUG, LOG_MODULE_NAME, "header parse done");
+ lua_newtable(lua_state);
+ for(auto region : header.std_regions){
+ if(required_regions.find("ALL") != required_regions.end() || required_regions.find(region.first) != required_regions.end()){
+ lua_push_string_buffer(lua_state, region.first.c_str(), region.first.length());
+ lua_push_string_buffer(lua_state, region.second.c_str(), region.second.length());
+ lua_settable(lua_state, -3);
+ }
+ }
+ if(!header.other_regions.empty()){
+ if(required_regions.find("ALL") != required_regions.end() || required_regions.find("HTTP_OTHER_REGIONS") != required_regions.end()){
+ lua_push_string_buffer(lua_state, "HTTP_OTHER_REGIONS", std::string("HTTP_OTHER_REGIONS").length());
+ lua_newtable(lua_state);
+ int i = 1;
+ for(auto region : header.other_regions){
+ lua_push_string_buffer(lua_state, region.c_str(), region.length());
+ lua_rawseti(lua_state, -2, i++);
+ }
+ lua_settable(lua_state, -3);
+ }
+ }
+ return 0;
+ }
+ return -1;
+}
+
+static int _get_http_request_header(lua_State *lua_state, int status, lua_KContext yieldk_ctx){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_DEBUG, LOG_MODULE_NAME, "call get_http_request_header");
+ int ret = get_http_header(lua_state, HTTP_TYPE_REQUEST);
+ if(ret < 0){
+ lua_yieldk(lua_state, 0, 0, _get_http_request_header);
+ }
+ return 1;
+}
+
+static int get_http_request_header(lua_State* lua_state){
+ return _get_http_request_header(lua_state, 0, 0);
+}
+
+static int _get_http_response_header(lua_State *lua_state, int status, lua_KContext yieldk_ctx){
+ int ret = get_http_header(lua_state, HTTP_TYPE_RESPONSE);
+ if(ret < 0){
+ lua_yieldk(lua_state, 0, 0, _get_http_response_header);
+ }
+ return 1;
+}
+
+static int get_http_response_header(lua_State* lua_state){
+ return _get_http_response_header(lua_state, 0, 0);
+}
+
+static int get_http_body(lua_State *lua_state, int type){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_DEBUG, LOG_MODULE_NAME, "call _get_http_response_body");
+ lua_getglobal(lua_state, "cur_http_sess_ctx");
+ http_sess_ctx *sess_ctx = (http_sess_ctx *)lua_touserdata(lua_state, -1);
+ lua_pop(lua_state, 1);
+ if(sess_ctx == NULL){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "sess_ctx is null");
+ return -1;
+ }
+ http_body& body = (type == HTTP_TYPE_REQUEST? sess_ctx->req_body : sess_ctx->resp_body);
+ if(body.data_end == true || body.buf != nullptr){
+ lua_newtable(lua_state);
+ lua_push_string_buffer(lua_state, "block_id", std::string("block_id").length());
+ lua_pushinteger(lua_state, body.block_id);
+ lua_settable(lua_state, -3);
+ lua_push_string_buffer(lua_state, "data_end", std::string("data_end").length());
+ lua_pushboolean(lua_state, body.data_end);
+ lua_settable(lua_state, -3);
+ lua_push_string_buffer(lua_state, "buf", std::string("buf").length());
+ lua_pushlightuserdata(lua_state, body.buf);
+ lua_settable(lua_state, -3);
+ lua_push_string_buffer(lua_state, "buflen", std::string("buflen").length());
+ lua_pushinteger(lua_state, body.buflen);
+ lua_settable(lua_state, -3);
+ body.buf = nullptr;
+ body.buflen = 0;
+ return 0;
+ }
+ return -1;
+}
+
+static int _get_http_request_body(lua_State *lua_state, int status, lua_KContext yieldk_ctx){
+ int ret = get_http_body(lua_state, HTTP_TYPE_REQUEST);
+ if(ret < 0){
+ lua_yieldk(lua_state, 0, 0, _get_http_request_body);
+ }
+ return 1;
+}
+
+static int get_http_request_body(lua_State* lua_state){
+ return _get_http_request_body(lua_state, 0, 0);
+}
+
+static int _get_http_response_body(lua_State *lua_state, int status, lua_KContext yieldk_ctx){
+ int ret = get_http_body(lua_state, HTTP_TYPE_RESPONSE);
+ if(ret < 0){
+ lua_yieldk(lua_state, 0, 0, _get_http_response_body);
+ }
+ return 1;
+}
+
+static int get_http_response_body(lua_State* lua_state){
+ return _get_http_response_body(lua_state, 0, 0);
+}
+
+
+static int load_lua_http_plug(const char *profile, int thread_num){
+ const char *section = "main";
+ char file_path[LUA_SAPP_PATH_MAX] = "";
+ char entry_type[LUA_SAPP_SYMBOL_MAX] = "";
+ MESA_load_profile_string_def(profile, section, "file_path", file_path, sizeof(file_path), "");
+ MESA_load_profile_string_def(profile, section, "entry_type", entry_type, sizeof(entry_type), "");
+ MESA_handle_runtime_log(g_logger, RLOG_LV_INFO, LOG_MODULE_NAME, "MESA_prof_load: profile is %s, section is %s,"
+ "file_path is %s, entry_type is %s\n", profile, section, file_path, entry_type);
+ if(strncmp(entry_type, "http", LUA_SAPP_SYMBOL_MAX) == 0){
+ for(int i = 0; i < thread_num; i++){
+ lua_State *lua_state = luaL_newstate();
+ if(lua_state == NULL){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "failed to LuaL_newstate");
+ return -1;
+ }
+ luaL_openlibs(lua_state);
+ int ret = luaL_dofile(lua_state, file_path);
+ if(ret){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "error: ret is %d, file_path is %s\n", ret, file_path);
+ return -1;
+ }
+ lua_register(lua_state, "get_stream_info", get_stream_info);
+ lua_register(lua_state, "get_http_request_header", get_http_request_header);
+ lua_register(lua_state, "get_http_response_header", get_http_response_header);
+ lua_register(lua_state, "get_http_request_body", get_http_request_body);
+ lua_register(lua_state, "get_http_response_body", get_http_response_body);
+ g_http_lua_states[i].push_back(lua_state);
+ }
+ }
+ return 0;
+}
+
+static int process_lua_plug_conflist(const char* filename, int thread_num)
+{
+ char lua_plug_conf_path[LUA_SAPP_PATH_MAX] = {0};
+ FILE* fp = fopen(filename, "r");
+ if(fp == NULL){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "process_conflist() fopen %s error!\n", filename);
+ return -1;
+ }
+ while(feof(fp) == 0){
+ if((fgets(lua_plug_conf_path, LUA_SAPP_PATH_MAX, fp)) == NULL){
+ fclose(fp);
+ fp=NULL;
+ return 0;
+ }
+ if(lua_plug_conf_path[0]=='#'){
+ continue;
+ }
+ int len = strnlen(lua_plug_conf_path, LUA_SAPP_PATH_MAX);
+ lua_plug_conf_path[len - 1] = '\0';
+ int ret = load_lua_http_plug(lua_plug_conf_path, thread_num);
+ if(ret < 0){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "failed to load_lua_plug: conf_path is %s\n", lua_plug_conf_path);
+ }
+ }
+ fclose(fp);
+ fp=NULL;
+ return 0;
+}
+
+static http_sess_ctx* init_http_sess_ctx(int thread_seq){
+ http_sess_ctx *ctx = new http_sess_ctx();
+ for(lua_State *lua_state : g_http_lua_states[thread_seq]){
+ lua_State* coroutine = lua_newthread(lua_state);
+ int ret = lua_checkstack(lua_state, 1);
+ if(ret != 1){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "do not have enough space, ret is %d\n", ret);
+ continue;
+ }
+ ctx->coroutines.push_back(coroutine);
+ }
+ return ctx;
+}
+
+static void clear_http_sess_ctx(http_sess_ctx *ctx){
+ delete ctx;
+ ctx = NULL;
+}
+
+
+std::string utils_inet_ntoa(uint32_t ip)
+{
+ const char *_ip = inet_ntoa(*(struct in_addr *)&ip);
+ return std::string(_ip);
+}
+
+extern "C" uchar http_adapter_http_entry(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet){
+ uchar ret = PROT_STATE_GIVEME;
+ http_sess_ctx *ctx = (http_sess_ctx*)*param;
+ http_infor *a_http = (http_infor *)(session_info->app_info);
+ bool stream_begin = false;
+ if(session_info == nullptr){
+ return PROT_STATE_DROPME;
+ }
+ if(ctx == nullptr){
+ ctx = init_http_sess_ctx(thread_seq);
+ *param = ctx;
+ stream_begin = true;
+ }
+ if(ctx->tuple5.parse_done == false){
+ struct stream_tuple4_v4 *tuple4_v4 = a_tcp->addr.tuple4_v4;
+ ctx->tuple5.ip_version = "IPV4";
+ if(a_tcp->type == STREAM_TYPE_TCP){
+ ctx->tuple5.stream_type = "TCP";
+ }
+ if(a_tcp->type == STREAM_TYPE_UDP){
+ ctx->tuple5.stream_type = "UDP";
+ }
+ ctx->tuple5.sip = utils_inet_ntoa(tuple4_v4->saddr);
+ ctx->tuple5.dip = utils_inet_ntoa(tuple4_v4->daddr);
+ ctx->tuple5.sport = ntohs(tuple4_v4->source);
+ ctx->tuple5.dport = ntohs(tuple4_v4->dest);
+ ctx->tuple5.parse_done = true;
+ }
+ uchar curdir = a_http->curdir;
+ switch(session_info->prot_flag)
+ {
+ case HTTP_STATE:
+ case HTTP_CONTENT:
+ break;
+ case HTTP_UNGZIP_CONTENT:
+ if(curdir == DIR_C2S){
+ ctx->req_body.block_id++;
+ ctx->req_body.buf = session_info->buf;
+ ctx->req_body.buflen = session_info->buflen;
+ }
+ if(curdir == DIR_S2C){
+ ctx->resp_body.block_id++;
+ ctx->resp_body.buf = session_info->buf;
+ ctx->resp_body.buflen = session_info->buflen;
+ }
+ break;
+ default:
+ std::string key(http_proto_flag2region(session_info->prot_flag));
+ std::string value((const char*)(session_info->buf), session_info->buflen);
+ if(curdir == DIR_C2S){
+ if(key == "HTTP_OTHER_REGIONS"){
+ ctx->req_header.other_regions.insert(value);
+ }
+ else{
+ ctx->req_header.std_regions.insert({key, value});
+ }
+ }
+ else{
+ if(key == "HTTP_OTHER_REGIONS"){
+ ctx->resp_header.other_regions.insert(value);
+ }
+ else{
+ ctx->resp_header.std_regions.insert({key, value});
+ }
+ }
+ break;
+ }
+ uchar http_state = a_http->http_state;
+ //header over
+ if(http_state == HTTP_DATA_BEGIN){
+ if(curdir == DIR_C2S){
+ ctx->req_header.parse_done = true;
+ }
+ if(curdir == DIR_S2C){
+ ctx->resp_header.parse_done = true;
+ }
+ }
+ //data over
+ if(http_state == HTTP_DATA_END){
+ if(curdir == DIR_C2S){
+ ctx->req_body.data_end = true;
+ }
+ if(curdir == DIR_S2C){
+ ctx->resp_body.data_end = true;
+ }
+ }
+ //resume coroutine
+ for(lua_State*& coroutine : ctx->coroutines){
+ if(coroutine == nullptr){
+ continue;
+ }
+ /*
+ int ret = lua_checkstack(coroutine, 1);
+ if(ret != 1){
+ //do log
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "do not have enough space, ret is %d", ret);
+ continue;
+ }
+ */
+ lua_pushlightuserdata(coroutine, (void *)ctx);
+ lua_setglobal(coroutine, "cur_http_sess_ctx");
+ if(stream_begin){
+ lua_getglobal(coroutine, "process");
+ }
+ ret = lua_resume(coroutine, NULL, 0);
+ if(ret == LUA_OK){
+ coroutine = nullptr;
+ continue;
+ }
+ if(ret != LUA_YIELD){
+ lua_traceback("lua_resume", coroutine, ret);
+ coroutine = nullptr;
+ }
+ }
+ if(session_info->session_state & SESSION_STATE_CLOSE){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_INFO, LOG_MODULE_NAME, "close tcp stream");
+ clear_http_sess_ctx(ctx);
+ *param = NULL;
+ }
+ return ret;
+}
+
+extern "C" int http_adapter_init(void){
+ g_logger = MESA_create_runtime_log_handle("./log/lua_sapp/http_adapter/http_adapter.log", 10);
+ if(g_logger == NULL){
+ MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "%s init : get log handle error!", HTTP_SERVICE_PLUGNAME);
+ return -1;
+ }
+ int thread_num = g_iThreadNum;;
+ for(int i = 0; i < thread_num; i++){
+ g_http_lua_states.push_back(std::vector<lua_State*>());
+ }
+
+ // get all business lua script which register http
+ const char *conflist_path = "./plug/lua/conflist_lua.inf";
+ process_lua_plug_conflist(conflist_path, thread_num);
+ return 0;
+}
+
+extern "C" void http_adapter_destroy(void){
+ for(auto states : g_http_lua_states){
+ for(auto state : states){
+ lua_close(state);
+ }
+ }
+ return;
+}
+
diff --git a/adapter/http_adapter/src/adapter.h b/adapter/http_adapter/src/adapter.h
new file mode 100644
index 0000000..1c4a790
--- /dev/null
+++ b/adapter/http_adapter/src/adapter.h
@@ -0,0 +1,112 @@
+/*
+ * HTTP_Service.h
+ *
+ * Created on: 2013-8-19
+ * Author: lishu
+ */
+
+#ifndef HTTP_SERVICE_H_
+#define HTTP_SERVICE_H_
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <unordered_map>
+#include <unordered_set>
+
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <regex.h>
+#include "stream.h"
+#include "http.h"
+#include "MESA/MESA_prof_load.h"
+#include "MESA/MESA_handle_logger.h"
+
+extern "C" {
+ #include "lua.h"
+ #include "lualib.h"
+ #include "lauxlib.h"
+}
+#define HTTP_SERVICE_PLUGNAME "new_http_service.so"
+#define LOG_PATH "./log/new_http_service/"
+
+#define LOG_MODULE_NAME "SAPP_LUA"
+#define LUA_SAPP_SYMBOL_MAX 64
+#define LUA_SAPP_PATH_MAX 256
+#define LUA_SAPP_STRING_MAX 2048
+#define LUA_ENTRY_TYPE_NUM 8
+enum lua_entry_type{
+ LUA_ENTRY_TYPE_IP = 0,
+ LUA_ENTRY_TYPE_TCP,
+ LUA_ENTRY_TYPE_UDP,
+ LUA_ENTRY_TYPE_HTTP,
+ LUA_ENTRY_TYPE_TLS,
+ LUA_ENTRY_TYPE_DNS,
+ LUA_ENTRY_TYPE_MAIL,
+ LUA_ENTRY_TYPE_FTP
+};
+
+enum http_type{
+ HTTP_TYPE_REQUEST = 0,
+ HTTP_TYPE_RESPONSE
+};
+class http_header{
+public:
+ bool parse_done;
+ std::unordered_map<std::string, std::string> std_regions;
+ std::unordered_set<std::string> other_regions;
+ http_header() : parse_done(false){}
+};
+
+class http_body{
+public:
+ bool data_end;
+ int block_id;
+ void *buf;
+ int buflen;
+ http_body() : data_end(false), block_id(-1), buf(nullptr), buflen(0){}
+};
+
+class stream_tuple5{
+public:
+ bool parse_done;
+ std::string ip_version; //IPV4 or IPV6
+ std::string stream_type; //TCP or UDP
+ std::string sip;
+ std::string dip;
+ uint16_t sport;
+ uint16_t dport;
+ stream_tuple5() : parse_done(false){}
+};
+
+class http_sess_ctx{
+public:
+ stream_tuple5 tuple5;
+ http_header req_header;
+ http_header resp_header;
+ http_body req_body;
+ http_body resp_body;
+ std::vector<lua_State*> coroutines;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uchar NEW_HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet);
+int NEW_HTTP_SERVICE_INIT(void);
+void NEW_HTTP_SERVICE_DESTROY(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HTTP_SERVICE_H_ */