TSG-11849 tfe增加从环境变量中读入处理机ip
TSG-11742 IP Libraries统一使用.分隔地理层级 TSG-10722 日志中开始时间从解析层获取
This commit is contained in:
968
plugin/business/tsg-http/src/edit_element.cpp
Normal file
968
plugin/business/tsg-http/src/edit_element.cpp
Normal file
@@ -0,0 +1,968 @@
|
||||
#include <tfe_utils.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if 0
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
#include <pcre2.h>
|
||||
#endif
|
||||
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xmlsave.h>
|
||||
#include <libxml/HTMLparser.h>
|
||||
#include <cjson/cJSON.h>
|
||||
|
||||
#include "edit_element.h"
|
||||
|
||||
int cjson_element_foreach(cJSON *a, int *depth, int *step, int *step_level, char **node, const struct edit_element_rule * rules, int *match_num, int loop);
|
||||
static void html_node_list(const struct edit_element_rule * rules, xmlNodePtr node, xmlNodePtr *parent_array, size_t *n_parent, int *match,size_t mark_tag);
|
||||
size_t parse_json_output_unformatted(const char * in, size_t in_sz, const struct edit_element_rule * rules, char** out);
|
||||
|
||||
enum search_scope scope_name_to_id(const char * name)
|
||||
{
|
||||
const char * std_name[] = {"inside_element","whole_file"};
|
||||
size_t i = 0;
|
||||
for (i = 0; i < sizeof(std_name) / sizeof(const char *); i++)
|
||||
{
|
||||
if (0 == strcasecmp(name, std_name[i]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (enum search_scope) i;
|
||||
}
|
||||
|
||||
int match_start_indicator(xmlNodePtr parent, char * start_indicator)
|
||||
{
|
||||
if(parent->properties == NULL)
|
||||
{
|
||||
if(parent->name == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(!strcasecmp((char *)parent->name, start_indicator))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct _xmlAttr *properties = parent->properties;
|
||||
if(properties->children == NULL || properties->children->content == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmlNodePtr children = properties->children;
|
||||
if(!strcasecmp((char *)children->content, start_indicator))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int match_start_indicator(xmlNodePtr parent, char * start_indicator)
|
||||
{
|
||||
if(parent->properties == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct _xmlAttr *properties = parent->properties;
|
||||
if(properties->children == NULL || properties->children->content == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmlNodePtr children = properties->children;
|
||||
if(!strcasecmp((char *)children->content, start_indicator))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int match_string(const char * in, size_t in_sz, char *contained_keyword)
|
||||
{
|
||||
assert(strlen(contained_keyword) != 0);
|
||||
|
||||
int error=0;
|
||||
PCRE2_SIZE erroffset=0;
|
||||
|
||||
const PCRE2_SPTR pattern = (PCRE2_SPTR)contained_keyword;
|
||||
uint32_t pcre2_options = PCRE2_UTF;
|
||||
|
||||
pcre2_code *re = pcre2_compile(pattern, strlen(contained_keyword), pcre2_options, &error, &erroffset, 0);
|
||||
if(!re)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL);
|
||||
int rc = 0;
|
||||
const PCRE2_SPTR subject = (PCRE2_SPTR)in;
|
||||
|
||||
rc = pcre2_match(re, subject, in_sz, 0, 0, match_data, NULL);
|
||||
|
||||
pcre2_match_data_free(match_data);
|
||||
pcre2_code_free(re);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
int construct_cjson_by_treatment(cJSON *a_element, char **node, int *step, int *step_array_level, const struct edit_element_rule * rules)
|
||||
{
|
||||
const char *element_treatment=rules->element_treatment;
|
||||
char * start_indicator = rules->start_indicator;
|
||||
|
||||
if(element_treatment != NULL && !strcasecmp(element_treatment, "mark"))
|
||||
{
|
||||
if (rules->scope == kScopeInside)
|
||||
{
|
||||
if(a_element->type == cJSON_Object)
|
||||
{
|
||||
if(*node != NULL && strcasecmp(*node, start_indicator) != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
if(a_element->type == cJSON_Array)
|
||||
{
|
||||
if(a_element->string != NULL && strcasecmp(a_element->string, start_indicator))
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(a_element->type==cJSON_Object)
|
||||
{
|
||||
cJSON_AddBoolToObject(a_element, "need_filter", true);
|
||||
}
|
||||
if(a_element->type == cJSON_Array)
|
||||
{
|
||||
cJSON *object = NULL;
|
||||
object = cJSON_GetArrayItem(a_element, step_array_level[*step]);
|
||||
if(object != NULL)
|
||||
{
|
||||
cJSON_AddBoolToObject(object, "need_filter", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(element_treatment != NULL && !strcasecmp(element_treatment, "remove"))
|
||||
{
|
||||
if (rules->scope == kScopeInside)
|
||||
{
|
||||
if(a_element->type == cJSON_Object)
|
||||
{
|
||||
if(*node != NULL && strcasecmp(*node, start_indicator) != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
if(a_element->type == cJSON_Array)
|
||||
{
|
||||
if(a_element->string != NULL && strcasecmp(a_element->string, start_indicator))
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(a_element->type == cJSON_Object && *node != NULL)
|
||||
{
|
||||
cJSON_DeleteItemFromObject(a_element, *node);
|
||||
}
|
||||
if(a_element->type == cJSON_Array)
|
||||
{
|
||||
cJSON_DeleteItemFromArray(a_element, step_array_level[*step]);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int construct_html_by_treatment(const struct edit_element_rule * rules, xmlNodePtr node, xmlNodePtr *parent_array, size_t *n_parent, int *match)
|
||||
{
|
||||
int k=0;
|
||||
char *new_out=NULL;
|
||||
size_t output_size=0;
|
||||
char * token = NULL, * saveptr = NULL;
|
||||
|
||||
if(strcasestr((char *)node->content, "var ytInitialData"))
|
||||
{
|
||||
token = strtok_r((char *)node->content, "=", &saveptr);
|
||||
if(token != NULL && ((saveptr[0] == '{') || (saveptr[1] == '{')))
|
||||
{
|
||||
output_size = parse_json_output_unformatted(saveptr, strlen(saveptr), rules, &new_out);
|
||||
if(output_size != 0 && new_out != NULL)
|
||||
{
|
||||
new_out[output_size] = ';';
|
||||
|
||||
FREE(&node->content);
|
||||
|
||||
node->content = (xmlChar*)new_out;
|
||||
*match =1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(match_string((char *)node->content, strlen((char *)node->content), rules->contained_keyword) < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if(strcasestr((char *)node->content, rules->contained_keyword) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * start_indicator = rules->start_indicator;
|
||||
const char *element_treatment=rules->element_treatment;
|
||||
int distane_from_matching = (rules->distane_from_matching + 1);
|
||||
|
||||
if(element_treatment != NULL && !strcasecmp(element_treatment, "mark"))
|
||||
{
|
||||
xmlNodePtr parent = node->parent;
|
||||
k++;
|
||||
while (parent != NULL)
|
||||
{
|
||||
if(k == distane_from_matching)
|
||||
{
|
||||
if (rules->scope == kScopeInside && match_start_indicator(parent, start_indicator) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
xmlNewProp(parent, (const xmlChar *)"need_filter", (const xmlChar *)"true");
|
||||
*match =1;
|
||||
break;
|
||||
}
|
||||
k++;
|
||||
parent = parent->parent;
|
||||
}
|
||||
}
|
||||
|
||||
if(element_treatment != NULL && !strcasecmp(element_treatment, "remove"))
|
||||
{
|
||||
xmlNodePtr parent = node->parent;
|
||||
k++;
|
||||
while (parent != NULL)
|
||||
{
|
||||
if(k == distane_from_matching)
|
||||
{
|
||||
if (rules->scope == kScopeInside && match_start_indicator(parent, start_indicator) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/*This is the top floor, Don't deal with**/
|
||||
if(parent->parent == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
parent_array[0] = parent;
|
||||
*n_parent = *n_parent+1;
|
||||
*match =1;
|
||||
break;
|
||||
}
|
||||
|
||||
k++;
|
||||
parent = parent->parent;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cjson_dump_array(cJSON *a, int *depth, int *step, int *step_array_level, char **node, const struct edit_element_rule * rules, int *match_num, int loop)
|
||||
{
|
||||
int xret=0, array_cnt=0;
|
||||
|
||||
cJSON *a_element = a->child;
|
||||
*step= *step + 1;
|
||||
for (; (a_element != NULL);)
|
||||
{
|
||||
xret = cjson_element_foreach(a_element, depth, step, step_array_level, node, rules, match_num, loop);
|
||||
if(xret == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(*depth == 0)
|
||||
{
|
||||
xret = construct_cjson_by_treatment(a_element, node, step, step_array_level, rules);
|
||||
}
|
||||
if(xret == 1 || xret == -2)
|
||||
{
|
||||
*step = (*step >= 2047) ? 2047 : *step;
|
||||
step_array_level[*step] = array_cnt;
|
||||
*node = a_element->string;
|
||||
*depth = *depth -1;
|
||||
return xret;
|
||||
}
|
||||
array_cnt++;
|
||||
a_element = a_element->next;
|
||||
}
|
||||
|
||||
return xret;
|
||||
}
|
||||
|
||||
int cjson_dump_object(cJSON *a, int *depth, int *step, int *step_array_level, char **node, const struct edit_element_rule * rules, int *match_num, int loop)
|
||||
{
|
||||
int xret=0;
|
||||
cJSON *a_element=NULL;
|
||||
|
||||
cJSON_ArrayForEach(a_element, a)
|
||||
{
|
||||
xret = cjson_element_foreach(a_element, depth, step, step_array_level, node, rules, match_num, loop);
|
||||
if(xret == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(*depth == 0)
|
||||
{
|
||||
xret = construct_cjson_by_treatment(a_element, node, step, step_array_level, rules);
|
||||
}
|
||||
if(xret == 1 || xret == -2)
|
||||
{
|
||||
*node = a_element->string;
|
||||
*depth = *depth -1;
|
||||
return xret;
|
||||
}
|
||||
}
|
||||
return xret;
|
||||
}
|
||||
|
||||
int cjson_dump_string(cJSON *a, int *depth, const struct edit_element_rule * rules, int *match_num, int loop)
|
||||
{
|
||||
int xret=0;
|
||||
|
||||
#if 0
|
||||
if((a->valuestring != NULL) && (match_string(a->valuestring, strlen(a->valuestring), rules->contained_keyword) > 0))
|
||||
#endif
|
||||
if((a->valuestring != NULL) && strcasestr(a->valuestring, rules->contained_keyword))
|
||||
{
|
||||
if(*depth != -1)
|
||||
{
|
||||
if(!strcasecmp(rules->element_treatment, "mark"))
|
||||
{
|
||||
if(*match_num == loop)
|
||||
{
|
||||
xret = 1;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xret = 1;
|
||||
goto finish;
|
||||
|
||||
}
|
||||
}
|
||||
*match_num = *match_num + 1;
|
||||
}
|
||||
finish:
|
||||
return xret;
|
||||
}
|
||||
|
||||
int cjson_element_foreach(cJSON *a, int *depth, int *step, int *step_array_level, char **node, const struct edit_element_rule * rules, int *match_num, int loop)
|
||||
{
|
||||
if ((a == NULL) || cJSON_IsInvalid(a))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (a->type & 0xFF)
|
||||
{
|
||||
case cJSON_String:
|
||||
case cJSON_Raw:
|
||||
return cjson_dump_string(a, depth, rules, match_num, loop);
|
||||
|
||||
case cJSON_Array:
|
||||
return cjson_dump_array(a, depth, step, step_array_level, node, rules, match_num, loop);
|
||||
|
||||
case cJSON_Object:
|
||||
return cjson_dump_object(a, depth, step, step_array_level, node, rules, match_num, loop);
|
||||
|
||||
case cJSON_Number:
|
||||
case cJSON_False:
|
||||
case cJSON_True:
|
||||
case cJSON_NULL:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void html_namespace_list(xmlNsPtr ns)
|
||||
{
|
||||
while (ns != NULL)
|
||||
{
|
||||
ns = ns->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void html_attr_list(const struct edit_element_rule * rules, xmlAttrPtr attr, xmlNodePtr *parent_array, size_t *n_parent, int *match, size_t mark_tag)
|
||||
{
|
||||
while (attr != NULL)
|
||||
{
|
||||
if (attr->children != NULL)
|
||||
{
|
||||
html_node_list(rules, attr->children, parent_array, n_parent, match, mark_tag);
|
||||
}
|
||||
|
||||
attr = attr->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void html_dump_one_node(const struct edit_element_rule * rules, xmlNodePtr node, xmlNodePtr *parent_array, size_t *n_parent, int *match, size_t mark_tag)
|
||||
{
|
||||
switch (node->type)
|
||||
{
|
||||
case XML_ELEMENT_NODE:
|
||||
case XML_ELEMENT_DECL:
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
case XML_ENTITY_REF_NODE:
|
||||
case XML_ENTITY_NODE:
|
||||
case XML_PI_NODE:
|
||||
case XML_COMMENT_NODE:
|
||||
case XML_DOCUMENT_TYPE_NODE:
|
||||
case XML_DOCUMENT_FRAG_NODE:
|
||||
case XML_NOTATION_NODE:
|
||||
case XML_TEXT_NODE:
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL))
|
||||
{
|
||||
html_namespace_list(node->nsDef);
|
||||
}
|
||||
|
||||
if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL))
|
||||
{
|
||||
html_attr_list(rules, node->properties, parent_array, n_parent, match, mark_tag);
|
||||
}
|
||||
|
||||
if (node->type != XML_ENTITY_REF_NODE)
|
||||
{
|
||||
if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL))
|
||||
{
|
||||
construct_html_by_treatment(rules, node, parent_array, n_parent, match);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void html_dump_node(const struct edit_element_rule * rules, xmlNodePtr node, xmlNodePtr *parent_array, size_t *n_parent, int *match, size_t mark_tag)
|
||||
{
|
||||
html_dump_one_node(rules, node, parent_array, n_parent, match, mark_tag);
|
||||
if(*match == 1 && mark_tag == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((node->type != XML_NAMESPACE_DECL) && (node->children != NULL) && (node->type != XML_ENTITY_REF_NODE))
|
||||
{
|
||||
html_node_list(rules, node->children, parent_array, n_parent, match, mark_tag);
|
||||
}
|
||||
}
|
||||
|
||||
static void html_node_list(const struct edit_element_rule * rules, xmlNodePtr node, xmlNodePtr *parent_array, size_t *n_parent, int *match, size_t mark_tag)
|
||||
{
|
||||
while (node != NULL)
|
||||
{
|
||||
html_dump_node(rules, node, parent_array, n_parent, match, mark_tag);
|
||||
if(*match == 1 && mark_tag == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void html_element_foreach(const struct edit_element_rule * rules, xmlDocPtr doc, xmlNodePtr *parent_array, size_t *n_parent, int *match, size_t mark_tag)
|
||||
{
|
||||
if (((doc->type == XML_DOCUMENT_NODE) || (doc->type == XML_HTML_DOCUMENT_NODE)) && (doc->children != NULL))
|
||||
{
|
||||
html_node_list(rules, doc->children, parent_array, n_parent, match, mark_tag);
|
||||
}
|
||||
}
|
||||
|
||||
size_t parse_json_output_unformatted(const char * in, size_t in_sz, const struct edit_element_rule * rules, char** out)
|
||||
{
|
||||
int match_num_peer=0;
|
||||
int step=0, depth=0, match_num=0,i=0, match=0;
|
||||
cJSON* interator=NULL;
|
||||
char* new_out = NULL, *node=NULL;
|
||||
size_t outlen=0;
|
||||
char *element_treatment=NULL;
|
||||
|
||||
int step_array_level[2048] = {0};
|
||||
|
||||
interator = cJSON_Parse(in);
|
||||
if(interator==NULL)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
depth = -1;
|
||||
element_treatment=rules->element_treatment;
|
||||
|
||||
cjson_element_foreach(interator, &depth, &step, step_array_level, &node, rules, &match_num, 0);
|
||||
match_num_peer = match_num;
|
||||
for(i=0; i< match_num_peer; i++)
|
||||
{
|
||||
depth = (rules->distane_from_matching + 1);
|
||||
step=0; node=NULL; match_num=0;
|
||||
memset(step_array_level, 0, sizeof(step_array_level));
|
||||
|
||||
match |= cjson_element_foreach(interator, &depth, &step, step_array_level, &node, rules, &match_num, i);
|
||||
|
||||
if(!strcasecmp(element_treatment, "remove") && match == 1 && node != NULL && depth == 0)
|
||||
{
|
||||
cJSON_DeleteItemFromObject(interator, node);
|
||||
}
|
||||
}
|
||||
|
||||
if(match==1 && element_treatment != NULL && !strcasecmp(element_treatment, "mark"))
|
||||
{
|
||||
if(interator->type==cJSON_Object)
|
||||
{
|
||||
cJSON_AddBoolToObject(interator, "need_check", true);
|
||||
}
|
||||
if(interator->type==cJSON_Array)
|
||||
{
|
||||
cJSON *child = interator->child;
|
||||
for (; (child != NULL);)
|
||||
{
|
||||
cJSON_AddBoolToObject(child, "need_check", true);
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(match == 0 || match == -2)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
new_out = cJSON_PrintUnformatted(interator);
|
||||
if(new_out!=NULL)
|
||||
{
|
||||
*out = new_out;
|
||||
outlen = strlen(new_out);
|
||||
}
|
||||
|
||||
finish:
|
||||
if(interator != NULL)
|
||||
cJSON_Delete(interator);
|
||||
return outlen;
|
||||
}
|
||||
|
||||
size_t format_json_file_type(const char * in, size_t in_sz, const struct edit_element_rule * rules, char** out)
|
||||
{
|
||||
int match_num_peer=0;
|
||||
int step=0, depth=0, match=0, i=0;
|
||||
cJSON* interator=NULL;
|
||||
char* new_out = NULL, *node=NULL;
|
||||
size_t outlen=0; int match_num=0;
|
||||
char *element_treatment=NULL;
|
||||
|
||||
int step_array_level[2048] = {0};
|
||||
|
||||
char*new_in = ALLOC(char, in_sz+1);
|
||||
memcpy(new_in, in, in_sz);
|
||||
|
||||
interator = cJSON_Parse(new_in);
|
||||
if(interator==NULL)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
depth = -1;
|
||||
element_treatment=rules->element_treatment;
|
||||
|
||||
/*When the node has inclusion relation, cjson is not null when deleted
|
||||
So multiple loops delete **/
|
||||
cjson_element_foreach(interator, &depth, &step, step_array_level, &node, rules, &match_num, 0);
|
||||
match_num_peer = match_num;
|
||||
for(i=0; i< match_num_peer; i++)
|
||||
{
|
||||
depth = (rules->distane_from_matching + 1);
|
||||
step=0; node=NULL; match_num=0;
|
||||
memset(step_array_level, 0, sizeof(step_array_level));
|
||||
|
||||
match |= cjson_element_foreach(interator, &depth, &step, step_array_level, &node, rules, &match_num, i);
|
||||
|
||||
if(!strcasecmp(element_treatment, "remove") && match == 1 && node != NULL && depth == 0)
|
||||
{
|
||||
cJSON_DeleteItemFromObject(interator, node);
|
||||
}
|
||||
|
||||
match_num--;
|
||||
}
|
||||
|
||||
if(match == 0 || match == -2)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if(element_treatment != NULL && !strcasecmp(element_treatment, "mark"))
|
||||
{
|
||||
if(interator->type==cJSON_Object)
|
||||
{
|
||||
cJSON_AddBoolToObject(interator, "need_check", true);
|
||||
}
|
||||
|
||||
if(interator->type==cJSON_Array)
|
||||
{
|
||||
cJSON *child = interator->child;
|
||||
for (; (child != NULL);)
|
||||
{
|
||||
cJSON_AddBoolToObject(child, "need_check", true);
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new_out = cJSON_PrintUnformatted(interator);
|
||||
if(new_out!=NULL)
|
||||
{
|
||||
*out = new_out;
|
||||
outlen = strlen(*out);
|
||||
}
|
||||
|
||||
finish:
|
||||
if(interator != NULL)
|
||||
cJSON_Delete(interator);
|
||||
FREE(&new_in);
|
||||
return outlen;
|
||||
}
|
||||
|
||||
size_t format_multidelete_json_type(const char * in, size_t in_sz, const struct edit_element_rule * rules, char** out)
|
||||
{
|
||||
char *new_out=NULL, *pre_out=NULL;
|
||||
char * tmp = ALLOC(char, in_sz+1);
|
||||
char * token = NULL, * sub_token = NULL, * saveptr = NULL;
|
||||
size_t output_size = 0;
|
||||
|
||||
size_t new_out_len=0;
|
||||
/**Follow-up optimization */
|
||||
new_out = ALLOC(char, in_sz+in_sz/3);
|
||||
|
||||
memcpy(tmp, in, in_sz);
|
||||
|
||||
for (token = tmp;; token = NULL)
|
||||
{
|
||||
sub_token = strtok_r(token, "\n", &saveptr);
|
||||
if (sub_token == NULL)
|
||||
{
|
||||
new_out[new_out_len-2]='\0';
|
||||
break;
|
||||
}
|
||||
output_size = parse_json_output_unformatted(sub_token, strlen(sub_token), rules, &pre_out);
|
||||
if(output_size>0 && pre_out!=NULL)
|
||||
{
|
||||
memcpy(new_out+new_out_len, pre_out, strlen(pre_out));
|
||||
new_out_len += strlen(pre_out);
|
||||
memcpy(new_out+new_out_len, "\r\n", 2);
|
||||
new_out_len +=2;
|
||||
FREE(&pre_out);
|
||||
}
|
||||
}
|
||||
|
||||
if(new_out)
|
||||
{
|
||||
*out = new_out;
|
||||
output_size = strlen(new_out);
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
return output_size;
|
||||
}
|
||||
|
||||
size_t construct_format_html(htmlDocPtr doc, char**out)
|
||||
{
|
||||
size_t outlen=0;
|
||||
xmlBufferPtr out_buffer;
|
||||
const xmlChar *xmlCharBuffer;
|
||||
xmlSaveCtxtPtr saveCtxtPtr;
|
||||
|
||||
out_buffer = xmlBufferCreate();
|
||||
if (out_buffer == NULL)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
saveCtxtPtr = xmlSaveToBuffer(out_buffer, "UTF-8", XML_SAVE_NO_DECL | XML_SAVE_AS_HTML);
|
||||
if (xmlSaveDoc(saveCtxtPtr, doc) < 0)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
xmlSaveClose(saveCtxtPtr);
|
||||
|
||||
xmlCharBuffer = xmlBufferContent(out_buffer);
|
||||
if(xmlCharBuffer != NULL)
|
||||
{
|
||||
char*new_out = ALLOC(char, strlen((char *)xmlCharBuffer)+1);
|
||||
memcpy(new_out, (char *)xmlCharBuffer, strlen((char *)xmlCharBuffer));
|
||||
|
||||
*out = new_out;
|
||||
outlen = strlen((char *)xmlCharBuffer);
|
||||
}
|
||||
|
||||
finish:
|
||||
if(out_buffer != NULL)
|
||||
{
|
||||
xmlBufferFree(out_buffer);
|
||||
}
|
||||
|
||||
return outlen;
|
||||
}
|
||||
|
||||
size_t format_input_html(const char * in, size_t in_sz, const struct edit_element_rule * rules, char** out)
|
||||
{
|
||||
size_t outlen=0, n_parent=0, n_parent_peer=0;
|
||||
int match=0, i=0;
|
||||
htmlDocPtr doc = NULL;
|
||||
const char *element_treatment=NULL;
|
||||
xmlNodePtr parent_array[16];
|
||||
int options = XML_PARSE_NOERROR | HTML_PARSE_NODEFDTD;
|
||||
|
||||
doc = htmlReadMemory(in, in_sz, NULL, NULL, options);
|
||||
if (doc == NULL)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/*Delete all at once, valgrind is invalid read **/
|
||||
html_element_foreach(rules, doc, parent_array, &n_parent, &match, 1);
|
||||
if(match != 1)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
n_parent_peer = n_parent;
|
||||
element_treatment=rules->element_treatment;
|
||||
|
||||
/*When the node has inclusion relation, libxml2 is not null when deleted
|
||||
So multiple loops delete **/
|
||||
if(element_treatment != NULL && !strcasecmp(element_treatment, "remove"))
|
||||
{
|
||||
for(i=0; i < (int)n_parent_peer; i++)
|
||||
{
|
||||
match =0; n_parent = 0;
|
||||
html_element_foreach(rules, doc, parent_array, &n_parent, &match, 0);
|
||||
if(match == 1 && n_parent > 0)
|
||||
{
|
||||
xmlUnlinkNode(parent_array[0]);
|
||||
xmlFreeNode(parent_array[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(element_treatment != NULL && !strcasecmp(element_treatment, "mark"))
|
||||
{
|
||||
if(doc->children != NULL && doc->children->next != NULL)
|
||||
{
|
||||
xmlNodePtr node = doc->children->next;
|
||||
while(node->type != XML_ELEMENT_NODE)
|
||||
{
|
||||
node = node->next;
|
||||
}
|
||||
xmlNewProp(node, (const xmlChar *)"need_check", (const xmlChar *)"true");
|
||||
}
|
||||
else if(doc->children != NULL)
|
||||
{
|
||||
xmlNewProp(doc->children, (const xmlChar *)"need_check", (const xmlChar *)"true");
|
||||
}
|
||||
}
|
||||
|
||||
outlen = construct_format_html(doc, out);
|
||||
if(outlen<=0)
|
||||
{
|
||||
outlen=0;
|
||||
}
|
||||
|
||||
finish:
|
||||
if(doc!=NULL)
|
||||
{
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
return outlen;
|
||||
}
|
||||
|
||||
size_t format_html_file_type(const char * interator, size_t interator_sz, const struct edit_element_rule *rule, char **new_out)
|
||||
{
|
||||
size_t output_size=0;
|
||||
|
||||
if((interator[0] == '{') || (interator[0] == '['))
|
||||
{
|
||||
output_size = format_multidelete_json_type(interator, interator_sz, rule, new_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_size = format_input_html(interator, interator_sz, rule, new_out);
|
||||
}
|
||||
|
||||
return output_size;
|
||||
}
|
||||
|
||||
size_t parse_string(const char * interator, size_t interator_sz, const struct edit_element_rule *rule, char **new_out, int options)
|
||||
{
|
||||
size_t output_size=0;
|
||||
|
||||
if(options)
|
||||
{
|
||||
output_size = format_json_file_type(interator, interator_sz, rule, new_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_size = format_html_file_type(interator, interator_sz, rule, new_out);
|
||||
}
|
||||
|
||||
return output_size;
|
||||
}
|
||||
|
||||
size_t execute_edit_element_rule(const char * in, size_t in_sz, const struct edit_element_rule *rules, size_t n_rule, char** out, int options)
|
||||
{
|
||||
const struct edit_element_rule * todo = rules;
|
||||
size_t i = 0, interator_sz=0, pre_out_sz=0;
|
||||
const char * interator = NULL;
|
||||
char* new_out = NULL, * pre_out = NULL;
|
||||
size_t output_size=0;
|
||||
if (in_sz == 0 || in==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
interator = in;
|
||||
interator_sz = in_sz;
|
||||
for (i = 0; i < n_rule; i++)
|
||||
{
|
||||
output_size = parse_string(interator, interator_sz, &(todo[i]), &new_out, options);
|
||||
if (output_size == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pre_out != NULL)
|
||||
{
|
||||
free(pre_out);
|
||||
pre_out = NULL;
|
||||
}
|
||||
pre_out = new_out;
|
||||
pre_out_sz = output_size;
|
||||
|
||||
interator = new_out;
|
||||
interator_sz = output_size;
|
||||
|
||||
new_out=NULL;
|
||||
output_size=0;
|
||||
}
|
||||
if(pre_out_sz>0)
|
||||
{
|
||||
*out=pre_out;
|
||||
return pre_out_sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t __attribute__((__unused__))
|
||||
format_edit_element_rule(struct edit_element_rule *edit_element, const char *user_region, size_t n_edit_element)
|
||||
{
|
||||
size_t idx=0;
|
||||
cJSON *json=NULL, *rules=NULL, *item=NULL, *sub_item=NULL;
|
||||
|
||||
json=cJSON_Parse(user_region);
|
||||
if(json !=NULL )
|
||||
{
|
||||
rules = cJSON_GetObjectItem(json, "rules");
|
||||
if(rules == NULL)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
for (item = rules->child; item != NULL; item = item->next)
|
||||
{
|
||||
sub_item=cJSON_GetObjectItem(item,"anchor_element");
|
||||
if(sub_item != NULL && sub_item->type ==cJSON_Object)
|
||||
{
|
||||
char * search_scope = cJSON_GetObjectItem(sub_item , "search_scope")->valuestring;
|
||||
if (search_scope == NULL) break;
|
||||
|
||||
edit_element[idx].scope = scope_name_to_id(search_scope);
|
||||
if (edit_element[idx].scope == KScopeMax)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(edit_element[idx].scope == kScopeInside)
|
||||
{
|
||||
edit_element[idx].start_indicator = tfe_strdup(cJSON_GetObjectItem(sub_item , "start_indicator")->valuestring);
|
||||
}
|
||||
edit_element[idx].contained_keyword = tfe_strdup(cJSON_GetObjectItem(sub_item,"contained_keyword")->valuestring);
|
||||
}
|
||||
|
||||
sub_item=cJSON_GetObjectItem(item,"target_element");
|
||||
if(sub_item != NULL && sub_item->type ==cJSON_Object)
|
||||
{
|
||||
edit_element[idx].distane_from_matching = cJSON_GetObjectItem(sub_item , "target_distance_from_matching")->valueint;
|
||||
edit_element[idx].element_treatment = tfe_strdup(cJSON_GetObjectItem(sub_item,"element_treatment")->valuestring);
|
||||
}
|
||||
|
||||
if (idx == n_edit_element)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
if (json) cJSON_Delete(json);
|
||||
return idx;
|
||||
}
|
||||
|
||||
void simple_edit_element(const char *user_region, const char* input, size_t in_sz, char** output, size_t *output_sz, int options)
|
||||
{
|
||||
size_t n_got_rule=0, i=0;
|
||||
struct edit_element_rule rules[16];
|
||||
memset(rules, 0, sizeof(struct edit_element_rule)*16);
|
||||
|
||||
n_got_rule=format_edit_element_rule(rules, user_region, sizeof(rules)/sizeof(rules[0]));
|
||||
*output_sz=execute_edit_element_rule(input, strlen(input), rules, n_got_rule, output, options);
|
||||
for(i=0; i<n_got_rule; i++)
|
||||
{
|
||||
if(rules[i].start_indicator!=NULL)
|
||||
{
|
||||
FREE(&(rules[i].start_indicator));
|
||||
}
|
||||
|
||||
FREE(&(rules[i].element_treatment));
|
||||
FREE(&(rules[i].contained_keyword));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
775
plugin/business/tsg-http/src/http_lua.cpp
Normal file
775
plugin/business/tsg-http/src/http_lua.cpp
Normal file
@@ -0,0 +1,775 @@
|
||||
#include "pattern_replace.h"
|
||||
#include "http_lua.h"
|
||||
|
||||
#include <tfe_utils.h>
|
||||
#include <tfe_http.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
static const char __attribute__((__unused__))*http_lua_log_get_url(struct tsg_script_ctx *tsg_ctx)
|
||||
{
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
if(events < EV_HTTP_REQ_HDR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
struct tfe_http_half * in_req_half = session->req;
|
||||
if(in_req_half == NULL)
|
||||
return NULL;
|
||||
struct tfe_http_req_spec * in_req_spec = &in_req_half->req_spec;
|
||||
if(in_req_spec == NULL)
|
||||
return NULL;
|
||||
|
||||
if (in_req_spec->url != NULL)
|
||||
{
|
||||
return in_req_spec->url;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int http_get_param_from_lua(struct elua_vm *vm, struct elua_data **out_lua_argv)
|
||||
{
|
||||
int i=0, out_lua_argc=0;
|
||||
struct elua_data *lua_argv=NULL;
|
||||
|
||||
out_lua_argc = elua_cbinding_get_input_params_num(vm);
|
||||
if(out_lua_argc <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_argv = ALLOC(struct elua_data, out_lua_argc);
|
||||
for (i = 0; i < out_lua_argc; i++)
|
||||
{
|
||||
elua_cbinding_get_input_param(vm, i+1, &lua_argv[i]);
|
||||
}
|
||||
*out_lua_argv = lua_argv;
|
||||
|
||||
return out_lua_argc;
|
||||
}
|
||||
|
||||
void http_free_params(struct elua_data *out_lua_argv)
|
||||
{
|
||||
if(out_lua_argv)
|
||||
FREE(&out_lua_argv);
|
||||
}
|
||||
|
||||
int http_set_string_to_lua(struct elua_vm *vm, const char *buff, size_t len)
|
||||
{
|
||||
struct elua_data edata;
|
||||
edata.type = STRING;
|
||||
edata.buff = (char *)buff;
|
||||
edata.len = len;
|
||||
elua_cbinding_append_output_params(vm, &edata, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int http_set_num_to_lua(struct elua_vm *vm, long num)
|
||||
{
|
||||
struct elua_data retvalue;
|
||||
retvalue.type = INTEGER;
|
||||
retvalue.len = sizeof(long);
|
||||
retvalue.integer = num;
|
||||
elua_cbinding_append_output_params(vm, &retvalue, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int http_set_table_to_lua(struct elua_vm *vm, struct elua_table *table)
|
||||
{
|
||||
struct elua_data retvalue;
|
||||
retvalue.type = TABLE;
|
||||
retvalue.table = table;
|
||||
retvalue.len = sizeof(struct elua_data);
|
||||
elua_cbinding_append_output_params(vm, &retvalue, 1);
|
||||
elua_destroy_table(table);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_log_debug(struct elua_vm *vm)
|
||||
{
|
||||
int out_lua_argc=0, i=0;
|
||||
struct elua_data *out_lua_argv=NULL;
|
||||
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
out_lua_argc = http_get_param_from_lua(vm, &out_lua_argv);
|
||||
if(out_lua_argc < 1 || out_lua_argv == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char buff[TFE_STRING_MAX]={0}, *p = NULL;
|
||||
p = buff;
|
||||
for(i=0; i<out_lua_argc; i++)
|
||||
{
|
||||
char *in=out_lua_argv[i].buff;
|
||||
size_t in_sz=out_lua_argv[i].len;
|
||||
if(in == NULL || in_sz ==0 || (sizeof(buff) - (p - buff)) <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
p += snprintf(p, sizeof(buff) - (p - buff), " %s", in);
|
||||
}
|
||||
|
||||
TFE_LOG_DEBUG(tsg_ctx->local_logger, "policy_id:%d, profile_id:%d, message:%20s", tsg_ctx->config_id, tsg_ctx->profile_id, buff);
|
||||
|
||||
http_free_params(out_lua_argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_log_info(struct elua_vm *vm)
|
||||
{
|
||||
int out_lua_argc=0, i=0;
|
||||
struct elua_data *out_lua_argv=NULL;
|
||||
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
out_lua_argc = http_get_param_from_lua(vm, &out_lua_argv);
|
||||
if(out_lua_argc < 1 || out_lua_argv == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char buff[TFE_STRING_MAX]={0}, *p = NULL;
|
||||
p = buff;
|
||||
for(i=0; i<out_lua_argc; i++)
|
||||
{
|
||||
char *in=out_lua_argv[i].buff;
|
||||
size_t in_sz=out_lua_argv[i].len;
|
||||
if(in == NULL || in_sz ==0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
p += snprintf(p, sizeof(buff) - (p - buff), " %s", in);
|
||||
}
|
||||
|
||||
TFE_LOG_INFO(tsg_ctx->local_logger, "policy_id:%d, profile_id:%d, message:%s", tsg_ctx->config_id, tsg_ctx->profile_id, buff);
|
||||
|
||||
http_free_params(out_lua_argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_log_error(struct elua_vm *vm)
|
||||
{
|
||||
int out_lua_argc=0, i=0;
|
||||
struct elua_data *out_lua_argv=NULL;
|
||||
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
out_lua_argc = http_get_param_from_lua(vm, &out_lua_argv);
|
||||
if(out_lua_argc < 1 || out_lua_argv == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char buff[TFE_STRING_MAX]={0}, *p = NULL;
|
||||
p = buff;
|
||||
for(i=0; i<out_lua_argc; i++)
|
||||
{
|
||||
char *in=out_lua_argv[i].buff;
|
||||
size_t in_sz=out_lua_argv[i].len;
|
||||
if(in == NULL || in_sz ==0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
p += snprintf(p, sizeof(buff) - (p - buff), " %s", in);
|
||||
}
|
||||
|
||||
TFE_LOG_ERROR(tsg_ctx->local_logger, "policy_id:%d, profile_id:%d, message:%s", tsg_ctx->config_id, tsg_ctx->profile_id, buff);
|
||||
|
||||
http_free_params(out_lua_argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_get_method(struct elua_vm *vm)
|
||||
{
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
if(tfe_http_in_response(events))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tfe_http_half * in_req_half = session->req;
|
||||
struct tfe_http_req_spec * in_req_spec = &in_req_half->req_spec;
|
||||
|
||||
const char *method_str = http_std_method_to_string(in_req_spec->method);
|
||||
if(method_str != NULL)
|
||||
{
|
||||
http_set_string_to_lua(vm, method_str, strlen(method_str));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_get_uri(struct elua_vm *vm)
|
||||
{
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
if(tfe_http_in_response(events) || !tsg_ctx->http_req_uri)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tfe_http_half * in_req_half = session->req;
|
||||
struct tfe_http_req_spec * in_req_spec = &in_req_half->req_spec;
|
||||
if (in_req_spec->uri != NULL)
|
||||
{
|
||||
http_set_string_to_lua(vm, in_req_spec->uri, strlen(in_req_spec->uri));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_set_uri(struct elua_vm *vm)
|
||||
{
|
||||
int out_lua_argc = 0;
|
||||
struct elua_data *out_lua_argv = NULL;
|
||||
|
||||
out_lua_argc = http_get_param_from_lua(vm, &out_lua_argv);
|
||||
if(out_lua_argc != 1 || out_lua_argv == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * rewrite_uri = out_lua_argv[0].buff;
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
if(tfe_http_in_response(events) || !tsg_ctx->http_req_uri)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tfe_http_half * in_req_half = session->req;
|
||||
struct tfe_http_req_spec * in_req_spec = &in_req_half->req_spec;
|
||||
if (in_req_spec->uri != NULL)
|
||||
{
|
||||
tsg_ctx->execut_lua_sucess=1;
|
||||
tsg_ctx->rewrite_uri = tfe_strdup(rewrite_uri);
|
||||
}
|
||||
http_free_params(out_lua_argv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_get_status_code(struct elua_vm *vm)
|
||||
{
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
if(tfe_http_in_request(events))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
struct tfe_http_half * in_resp_half = session->resp;
|
||||
struct tfe_http_resp_spec * in_resp_spec = &in_resp_half->resp_spec;
|
||||
|
||||
if (in_resp_spec != NULL)
|
||||
{
|
||||
http_set_num_to_lua(vm, in_resp_spec->resp_code);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_set_status_code(struct elua_vm *vm)
|
||||
{
|
||||
int out_lua_argc = 0;
|
||||
struct elua_data *out_lua_argv = NULL;
|
||||
|
||||
out_lua_argc = http_get_param_from_lua(vm, &out_lua_argv);
|
||||
if(out_lua_argc != 1 || out_lua_argv == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_resp_code = out_lua_argv[0].integer;
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
if(tfe_http_in_request(events))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tfe_http_half * in_resp_half = session->resp;
|
||||
struct tfe_http_resp_spec * in_resp_spec = &in_resp_half->resp_spec;
|
||||
|
||||
if(lua_resp_code != 0)
|
||||
{
|
||||
in_resp_spec->resp_code = lua_resp_code;
|
||||
}
|
||||
http_free_params(out_lua_argv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_exit(struct elua_vm *vm)
|
||||
{
|
||||
int out_lua_argc = 0;
|
||||
struct elua_data *out_lua_argv = NULL;
|
||||
|
||||
out_lua_argc = http_get_param_from_lua(vm, &out_lua_argv);
|
||||
if(out_lua_argc != 1 || out_lua_argv == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exit_code = out_lua_argv[0].integer;
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(exit_code == 0)
|
||||
{
|
||||
tsg_ctx->events = (enum tfe_http_event )0;
|
||||
return 0;
|
||||
}
|
||||
http_free_params(out_lua_argv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_get_current_stage(struct elua_vm *vm)
|
||||
{
|
||||
const char * stage_name[] = {"http_req_uri", "http_req_header","http_req_body","http_resp_header","http_resp_body","http_stage_test"};
|
||||
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
|
||||
//For test_http_lua
|
||||
if(tsg_ctx->http_req_uri==2)
|
||||
{
|
||||
http_set_string_to_lua(vm, stage_name[5], strlen(stage_name[5]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(events & EV_HTTP_REQ_HDR)
|
||||
{
|
||||
if(tsg_ctx->http_req_uri)
|
||||
{
|
||||
http_set_string_to_lua(vm, stage_name[0], strlen(stage_name[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
http_set_string_to_lua(vm, stage_name[1], strlen(stage_name[1]));
|
||||
}
|
||||
}
|
||||
|
||||
if((events & EV_HTTP_REQ_BODY_BEGIN) | (events & EV_HTTP_REQ_BODY_END) | (events & EV_HTTP_REQ_BODY_CONT))
|
||||
{
|
||||
http_set_string_to_lua(vm, stage_name[2], strlen(stage_name[2]));
|
||||
}
|
||||
|
||||
if(events & EV_HTTP_RESP_HDR)
|
||||
{
|
||||
http_set_string_to_lua(vm, stage_name[3], strlen(stage_name[3]));
|
||||
}
|
||||
|
||||
if((events & EV_HTTP_RESP_BODY_BEGIN) | (events & EV_HTTP_RESP_BODY_CONT) | (events & EV_HTTP_RESP_BODY_END))
|
||||
{
|
||||
http_set_string_to_lua(vm, stage_name[4], strlen(stage_name[4]));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_get_headers(struct elua_vm *vm)
|
||||
{
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
|
||||
struct tfe_http_half * in_req_half = session->req;
|
||||
struct tfe_http_half * in_resp_half = session->resp;
|
||||
|
||||
struct tfe_http_half * in_half = tfe_http_in_request(events) ? in_req_half : in_resp_half;
|
||||
if(in_half == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct http_field_name in_header_field{};
|
||||
const char * in_header_value = NULL;
|
||||
void * iterator = NULL;
|
||||
|
||||
struct elua_data in_field_name, in_field_value;
|
||||
struct elua_table *table = elua_create_table(vm);
|
||||
in_field_name.type = STRING;
|
||||
in_field_value.type = STRING;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if ((in_header_value = tfe_http_field_iterate(in_half, &iterator, &in_header_field)) == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
in_field_name.buff = (char *)http_field_name_to_string(&in_header_field);
|
||||
in_field_name.len = strlen(http_field_name_to_string(&in_header_field));
|
||||
|
||||
in_field_value.buff = (char *)in_header_value;
|
||||
in_field_value.len = strlen(in_header_value);
|
||||
elua_add_table(table, &in_field_name, &in_field_value);
|
||||
}
|
||||
|
||||
http_set_table_to_lua(vm, table);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_set_headers(struct elua_vm *vm)
|
||||
{
|
||||
int actually_write=0;
|
||||
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const struct tfe_http_session * session = tsg_ctx->session;
|
||||
if(session == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
enum tfe_http_event events = tsg_ctx->events;
|
||||
|
||||
struct tfe_http_half * in_req_half = session->req;
|
||||
struct tfe_http_half * in_resp_half = session->resp;
|
||||
|
||||
struct tfe_http_half * in_half = tfe_http_in_request(events) ? in_req_half : in_resp_half;
|
||||
if(in_half == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct http_field_name in_header_field{};
|
||||
const char * in_header_value = NULL;
|
||||
void * iterator = NULL;
|
||||
|
||||
int out_lua_argc = 0;
|
||||
struct elua_data *out_lua_argv = NULL;
|
||||
|
||||
const char *in_field_name;
|
||||
|
||||
out_lua_argc = http_get_param_from_lua(vm, &out_lua_argv);
|
||||
if(out_lua_argc != 2 || out_lua_argv == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *field_name=out_lua_argv[0].buff, *field_value=out_lua_argv[1].buff;
|
||||
|
||||
if(field_name == NULL || field_value == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if ((in_header_value = tfe_http_field_iterate(in_half, &iterator, &in_header_field)) == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
in_field_name = http_field_name_to_string(&in_header_field);
|
||||
if(strcasecmp(in_field_name, field_name)==0 && strcasecmp(field_value, "nil")!=0)
|
||||
{
|
||||
if(in_header_field.field_id == TFE_HTTP_UNKNOWN_FIELD)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tfe_http_std_field_write(in_half, in_header_field.field_id, NULL);
|
||||
tfe_http_std_field_write(in_half, in_header_field.field_id, field_value);
|
||||
actually_write=1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(strcasecmp(http_field_name_to_string(&in_header_field), field_name)==0 && strcasecmp(field_value, "nil")==0)
|
||||
{
|
||||
if(in_header_field.field_id == TFE_HTTP_UNKNOWN_FIELD)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tfe_http_std_field_write(in_half, in_header_field.field_id, NULL);
|
||||
actually_write=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(actually_write ==1)
|
||||
{
|
||||
tsg_ctx->execut_lua_sucess=1;
|
||||
}
|
||||
|
||||
if(actually_write!=1 && strcasecmp(field_value, "nil")!=0)
|
||||
{
|
||||
tfe_http_nonstd_field_write(in_half, field_name, field_value);
|
||||
tsg_ctx->execut_lua_sucess=1;
|
||||
}
|
||||
|
||||
http_free_params(out_lua_argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int http_lua_get_body(struct elua_vm *vm)
|
||||
{
|
||||
struct tsg_script_ctx *tsg_ctx = (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(tsg_ctx->http_body == NULL)
|
||||
{
|
||||
TFE_LOG_ERROR(tsg_ctx->local_logger, "policy_id:%d, profile_id:%d, message:%s", tsg_ctx->config_id, tsg_ctx->profile_id, "Can't to get req/resp body data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * __http_body = (char *) evbuffer_pullup(tsg_ctx->http_body, -1);
|
||||
size_t __http_body_len = evbuffer_get_length(tsg_ctx->http_body);
|
||||
|
||||
http_set_string_to_lua(vm, __http_body, __http_body_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int http_lua_set_body(struct elua_vm *vm)
|
||||
{
|
||||
int i=0;
|
||||
struct tsg_script_ctx *tsg_ctx= (struct tsg_script_ctx *)elua_get_execute_userdata(vm);
|
||||
if(tsg_ctx == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int out_lua_argc = 0;
|
||||
struct elua_data *out_lua_argv = NULL;
|
||||
|
||||
out_lua_argc=http_get_param_from_lua(vm, &out_lua_argv);
|
||||
if(out_lua_argc < 1 || out_lua_argv == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsg_ctx->http_lua_body = evbuffer_new();
|
||||
for(i=0; i<out_lua_argc; i++)
|
||||
{
|
||||
char *in=out_lua_argv[i].buff;
|
||||
size_t in_sz=strlen(out_lua_argv[i].buff);
|
||||
if(in == NULL || in_sz ==0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
evbuffer_add(tsg_ctx->http_lua_body, in, in_sz);
|
||||
}
|
||||
http_free_params(out_lua_argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct elua_context *http_lua_ctx_new(struct tsg_lua_script *lua_script, unsigned int thread_id)
|
||||
{
|
||||
return elua_create_context(lua_script->http_lua_handle[thread_id], "context");
|
||||
}
|
||||
|
||||
struct elua_script *http_lua_map_cache_script(struct elua_vm *vm, const char *script, size_t script_len, size_t timeout_ms)
|
||||
{
|
||||
return elua_cache_script(vm, script, script_len, timeout_ms);
|
||||
}
|
||||
|
||||
void http_lua_ctx_free(struct tsg_lua_script *lua_script, unsigned int thread_id, struct elua_context *elua_ctx)
|
||||
{
|
||||
if(elua_ctx)
|
||||
elua_destroy_context(elua_ctx);
|
||||
}
|
||||
|
||||
void http_lua_inject_http_consts(struct elua_vm *vm)
|
||||
{
|
||||
elua_register_cbinding(vm, NULL, "get_current_stage", http_lua_get_current_stage);
|
||||
elua_register_cbinding(vm, NULL, "log_debug", http_lua_log_debug);
|
||||
elua_register_cbinding(vm, NULL, "log_info", http_lua_log_info);
|
||||
elua_register_cbinding(vm, NULL, "log_error", http_lua_log_error);
|
||||
elua_register_cbinding(vm, NULL, "exit", http_lua_exit);
|
||||
}
|
||||
|
||||
void http_lua_inject_req_header_api(struct elua_vm *vm)
|
||||
{
|
||||
elua_register_cbinding(vm, "req", "get_method", http_lua_get_method);
|
||||
elua_register_cbinding(vm, "req", "get_uri", http_lua_get_uri);
|
||||
elua_register_cbinding(vm, "req", "set_uri", http_lua_set_uri);
|
||||
elua_register_cbinding(vm, "req", "get_headers", http_lua_get_headers);
|
||||
elua_register_cbinding(vm, "req", "set_header", http_lua_set_headers);
|
||||
}
|
||||
|
||||
void http_lua_inject_req_body_api(struct elua_vm *vm)
|
||||
{
|
||||
elua_register_cbinding(vm, "req", "get_body_data", http_lua_get_body);
|
||||
elua_register_cbinding(vm, "req", "set_body_data", http_lua_set_body);
|
||||
}
|
||||
|
||||
void http_lua_inject_resp_header_api(struct elua_vm *vm)
|
||||
{
|
||||
elua_register_cbinding(vm, "resp", "get_status_code", http_lua_get_status_code);
|
||||
elua_register_cbinding(vm, "resp", "set_status_code", http_lua_set_status_code);
|
||||
|
||||
elua_register_cbinding(vm, "resp", "get_headers", http_lua_get_headers);
|
||||
elua_register_cbinding(vm, "resp", "set_header", http_lua_set_headers);
|
||||
}
|
||||
|
||||
void http_lua_inject_resp_body_api(struct elua_vm *vm)
|
||||
{
|
||||
elua_register_cbinding(vm, "resp", "get_body_data", http_lua_get_body);
|
||||
elua_register_cbinding(vm, "resp", "set_body_data", http_lua_set_body);
|
||||
}
|
||||
|
||||
void http_lua_inject_api(struct elua_vm *vm)
|
||||
{
|
||||
http_lua_inject_http_consts(vm);
|
||||
http_lua_inject_req_header_api(vm);
|
||||
http_lua_inject_req_body_api(vm);
|
||||
http_lua_inject_resp_header_api(vm);
|
||||
http_lua_inject_resp_body_api(vm);
|
||||
}
|
||||
|
||||
int http_lua_handle_create(struct tsg_lua_script *lua_script, int thread_num, const char *name_space)
|
||||
{
|
||||
int id=0;
|
||||
struct elua_vm **http_lua_handle = NULL;
|
||||
|
||||
http_lua_handle = ALLOC(struct elua_vm *, thread_num);
|
||||
if(http_lua_handle == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(id=0; id < thread_num; id++)
|
||||
{
|
||||
http_lua_handle[id] = elua_create_vm(name_space);
|
||||
if(http_lua_handle[id] == NULL)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
http_lua_inject_api(http_lua_handle[id]);
|
||||
}
|
||||
lua_script->http_lua_handle=http_lua_handle;
|
||||
|
||||
return 1;
|
||||
finish:
|
||||
for(id=0; id < thread_num; id++)
|
||||
{
|
||||
if(http_lua_handle[id])
|
||||
FREE(&http_lua_handle[id])
|
||||
}
|
||||
free(http_lua_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t execute_lua_script_rule(struct tsg_lua_script *lua_script, int profile_id, struct elua_context *elua_ctx, unsigned int thread_id, void *user_data)
|
||||
{
|
||||
int ret=0;
|
||||
struct elua_script **escript=NULL;
|
||||
|
||||
ret=lua_script->http_lua_profile(profile_id, &escript);
|
||||
if(ret<0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *input="tfe";
|
||||
size_t input_len=strlen(input);
|
||||
|
||||
ret=elua_execute_script(escript[thread_id], input, input_len, user_data, elua_ctx, NULL);
|
||||
if(ret !=0 )
|
||||
{
|
||||
struct tsg_script_ctx *tsg_ctx= (struct tsg_script_ctx *)user_data;
|
||||
if(tsg_ctx != NULL && tsg_ctx->local_logger != NULL)
|
||||
{
|
||||
TFE_LOG_ERROR(tsg_ctx->local_logger, "policy_id:%d, profile_id:%d, error_code:%d, error: %s", tsg_ctx->config_id, tsg_ctx->profile_id, ret, elua_get_last_error_string(lua_script->http_lua_handle[thread_id]));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
352
plugin/business/tsg-http/src/pattern_replace.cpp
Normal file
352
plugin/business/tsg-http/src/pattern_replace.cpp
Normal file
@@ -0,0 +1,352 @@
|
||||
#include "pattern_replace.h"
|
||||
|
||||
#include <tfe_utils.h>
|
||||
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
#include <pcre2.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define MAX_EDIT_MATCHES 16
|
||||
|
||||
enum replace_zone zone_name_to_id(const char * name)
|
||||
{
|
||||
const char * std_name[] = {"http_req_uri",
|
||||
"http_req_header",
|
||||
"http_req_body",
|
||||
"http_resp_header",
|
||||
"http_resp_body",
|
||||
"http_resp_body"};
|
||||
size_t i = 0;
|
||||
for (i = 0; i < sizeof(std_name) / sizeof(const char *); i++)
|
||||
{
|
||||
if (0 == strcasecmp(name, std_name[i]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (enum replace_zone) i;
|
||||
}
|
||||
static char *__attribute__((__unused__))
|
||||
strchr_esc(char * s, const char delim)
|
||||
{
|
||||
char * token;
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
for (token = s; *token != '\0'; token++)
|
||||
{
|
||||
if (*token == '\\')
|
||||
{
|
||||
token++;
|
||||
continue;
|
||||
}
|
||||
if (*token == delim)
|
||||
break;
|
||||
}
|
||||
if (*token == '\0')
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return token;
|
||||
}
|
||||
}
|
||||
static char *__attribute__((__unused__))
|
||||
strtok_r_esc(char * s, const char delim, char ** save_ptr)
|
||||
{
|
||||
char * token;
|
||||
|
||||
if (s == NULL) s = *save_ptr;
|
||||
|
||||
/* Scan leading delimiters. */
|
||||
token = strchr_esc(s, delim);
|
||||
if (token == NULL)
|
||||
{
|
||||
*save_ptr = token;
|
||||
return s;
|
||||
}
|
||||
/* Find the end of the token. */
|
||||
*token = '\0';
|
||||
token++;
|
||||
*save_ptr = token;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t __attribute__((__unused__))
|
||||
format_replace_rule(const char * exec_para, struct replace_rule * replace, size_t n_replace)
|
||||
{
|
||||
char * tmp = ALLOC(char, strlen(exec_para) + 1);
|
||||
char * token = NULL, * sub_token = NULL, * saveptr = NULL, * saveptr2 = NULL;
|
||||
size_t idx = 0;
|
||||
|
||||
const char * str_zone = "zone=";
|
||||
const char * str_subs = "substitute=";
|
||||
memcpy(tmp, exec_para, strlen(exec_para));
|
||||
|
||||
for (token = tmp;; token = NULL)
|
||||
{
|
||||
sub_token = strtok_r(token, ";", &saveptr);
|
||||
if (sub_token == NULL) break;
|
||||
|
||||
if (0 == strncasecmp(sub_token, str_zone, strlen(str_zone)))
|
||||
{
|
||||
replace[idx].zone = zone_name_to_id(sub_token + strlen(str_zone));
|
||||
if (replace[idx].zone == kZoneMax)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sub_token = strtok_r(NULL, ";", &saveptr);
|
||||
if (0 == strncasecmp(sub_token, str_subs, strlen(str_subs)))
|
||||
{
|
||||
sub_token += strlen(str_subs) + 1;
|
||||
replace[idx].find = tfe_strdup(strtok_r_esc(sub_token, '/', &saveptr2));
|
||||
replace[idx].replace_with = tfe_strdup(strtok_r_esc(NULL, '/', &saveptr2));
|
||||
|
||||
idx++;
|
||||
if (idx == n_replace)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
return idx;
|
||||
}
|
||||
|
||||
size_t select_replace_rule(enum replace_zone zone, const struct replace_rule * replace, size_t n_replace,
|
||||
const struct replace_rule ** selected, size_t n_selected)
|
||||
{
|
||||
size_t i = 0, j = 0;
|
||||
for (i = 0; i < n_replace && j < n_selected; i++)
|
||||
{
|
||||
if (replace[i].zone == zone)
|
||||
{
|
||||
selected[j] = replace + i;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
size_t replace_string(const char * in, size_t in_sz, const struct replace_rule * zone, char** out, int options)
|
||||
{
|
||||
assert(strlen(zone->find) != 0);
|
||||
|
||||
int error=0;
|
||||
PCRE2_SIZE erroffset=0;
|
||||
|
||||
const PCRE2_SPTR pattern = (PCRE2_SPTR)zone->find;
|
||||
const PCRE2_SPTR subject = (PCRE2_SPTR)in;
|
||||
const PCRE2_SPTR replacement = (PCRE2_SPTR)zone->replace_with;
|
||||
uint32_t pcre2_options = options ? PCRE2_UTF : 0;
|
||||
|
||||
pcre2_code *re = pcre2_compile(pattern, strlen(zone->find), pcre2_options, &error, &erroffset, 0);
|
||||
if (!re)
|
||||
return 0;
|
||||
|
||||
pcre2_jit_compile(re, PCRE2_JIT_COMPLETE);
|
||||
|
||||
PCRE2_SIZE outbuff_size = in_sz+sizeof(replacement)*MAX_EDIT_MATCHES;
|
||||
PCRE2_SIZE outlen = 0;
|
||||
PCRE2_UCHAR* out_buffer = NULL;
|
||||
not_enough_mem_retry:
|
||||
out_buffer = (PCRE2_UCHAR*)malloc(sizeof(PCRE2_UCHAR)*outbuff_size);
|
||||
outlen = outbuff_size;
|
||||
int rc = pcre2_substitute(re, subject, in_sz, 0,
|
||||
PCRE2_SUBSTITUTE_GLOBAL | PCRE2_SUBSTITUTE_EXTENDED | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH,
|
||||
0, 0, //pcre2_match_data *match_data, pcre2_match_context
|
||||
replacement, strlen(zone->replace_with),
|
||||
out_buffer, &outlen);
|
||||
if(outlen>outbuff_size)
|
||||
{
|
||||
outbuff_size=outlen;
|
||||
free(out_buffer);
|
||||
out_buffer=NULL;
|
||||
goto not_enough_mem_retry;
|
||||
}
|
||||
if(rc<=0)
|
||||
{
|
||||
free(out_buffer);
|
||||
outlen=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out=(char*)out_buffer;
|
||||
}
|
||||
pcre2_code_free(re);
|
||||
return outlen;
|
||||
}
|
||||
|
||||
size_t execute_replace_rule(const char * in, size_t in_sz,
|
||||
enum replace_zone zone, const struct replace_rule * rules, size_t n_rule, char** out, int options)
|
||||
{
|
||||
const struct replace_rule * todo[n_rule];
|
||||
size_t n_todo = 0, i = 0, interator_sz=0, pre_out_sz=0;
|
||||
const char * interator = NULL;
|
||||
char* new_out = NULL, * pre_out = NULL;
|
||||
size_t output_size=0;
|
||||
if (in_sz == 0 || in==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
n_todo = select_replace_rule(zone, rules, n_rule, todo, n_rule);
|
||||
interator = in;
|
||||
interator_sz = in_sz;
|
||||
for (i = 0; i < n_todo; i++)
|
||||
{
|
||||
output_size = replace_string(interator, interator_sz, todo[i], &new_out, options);
|
||||
if (output_size == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pre_out != NULL)
|
||||
{
|
||||
free(pre_out);
|
||||
pre_out = NULL;
|
||||
}
|
||||
pre_out = new_out;
|
||||
pre_out_sz = output_size;
|
||||
|
||||
interator = new_out;
|
||||
interator_sz = output_size;
|
||||
|
||||
new_out=NULL;
|
||||
output_size=0;
|
||||
}
|
||||
if(pre_out_sz>0)
|
||||
{
|
||||
*out=pre_out;
|
||||
return pre_out_sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static char *find_insert_position(char * in)
|
||||
{
|
||||
char *insert_from = NULL;
|
||||
char *script_local = NULL;
|
||||
char *head_in = NULL;
|
||||
|
||||
if (in == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
head_in = strstr(in, "</head>");
|
||||
insert_from = strstr(in, "jquery");
|
||||
if (insert_from != NULL && head_in != NULL && (head_in - insert_from) > 0)
|
||||
{
|
||||
script_local=strstr(insert_from, "</script>");
|
||||
if (script_local)
|
||||
insert_from=script_local + sizeof("</script>");
|
||||
}
|
||||
else
|
||||
{
|
||||
insert_from=head_in;
|
||||
}
|
||||
return insert_from;
|
||||
}
|
||||
|
||||
size_t insert_string(char * in, size_t in_sz, const char *insert_on, const char *script, const char *type, char** out)
|
||||
{
|
||||
char *target=NULL;
|
||||
size_t target_size=0;
|
||||
|
||||
const char* js_style="<script type=\"text/javascript\" class=\"RQ_SCRIPT\">%s</script>";
|
||||
const char* css_style= "<style type=\"text/css\" class=\"RQ_SCRIPT\">%s</style>";
|
||||
const char* this_style=NULL;
|
||||
size_t concat_len=0, concat_size=0;
|
||||
char* concat_style=NULL;
|
||||
char* insert_from=NULL;
|
||||
size_t offset=0;
|
||||
|
||||
if (script == NULL || in == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (insert_on != NULL && 0==strcasecmp(insert_on, "after_page_load"))
|
||||
{
|
||||
insert_from=strstr(in, "</body>");
|
||||
}
|
||||
else
|
||||
{
|
||||
insert_from=find_insert_position(in);
|
||||
}
|
||||
if(!insert_from)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0==strcasecmp(type, "css"))
|
||||
{
|
||||
this_style=css_style;
|
||||
}
|
||||
else if (0==strcasecmp(type, "js"))
|
||||
{
|
||||
this_style=js_style;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
concat_size = strlen(script)+1+strlen(this_style);
|
||||
concat_style = ALLOC(char, concat_size);
|
||||
concat_len=snprintf(concat_style, concat_size,
|
||||
this_style,
|
||||
script);
|
||||
|
||||
target_size = in_sz+concat_len;
|
||||
target = ALLOC(char, target_size);
|
||||
assert((unsigned int)(insert_from-in) <= target_size);
|
||||
offset=0;
|
||||
memcpy(target+offset, in, insert_from-in);
|
||||
offset+=insert_from-in;
|
||||
memcpy(target+offset, concat_style, concat_len);
|
||||
offset+=concat_len;
|
||||
memcpy(target+offset, insert_from, in_sz-(insert_from-in));
|
||||
offset+=in_sz-(insert_from-in);
|
||||
assert(target_size==offset);
|
||||
|
||||
free(concat_style);
|
||||
concat_style = NULL;
|
||||
*out=target;
|
||||
return target_size;
|
||||
}
|
||||
|
||||
size_t execute_insert_rule(char * in, size_t in_sz, const struct insert_rule * rules, char** out)
|
||||
{
|
||||
return insert_string(in, in_sz, rules->position, rules->script, rules->type, out);
|
||||
}
|
||||
|
||||
void simple_replace(const char* find, const char* replacement, const char* input, size_t in_sz, char** output, size_t *output_sz, int options)
|
||||
{
|
||||
char* exec_para=NULL;
|
||||
asprintf(&exec_para,"zone=http_resp_body;substitute=/%s/%s", find, replacement);
|
||||
size_t n_got_rule=0, i=0;
|
||||
struct replace_rule rules[16];
|
||||
n_got_rule=format_replace_rule(exec_para, rules, sizeof(rules)/sizeof(rules[0]));
|
||||
*output_sz=execute_replace_rule(input, strlen(input), kZoneResponseBody, rules, n_got_rule, output, options);
|
||||
for(i=0; i<n_got_rule; i++)
|
||||
{
|
||||
FREE(&(rules[i].find));
|
||||
FREE(&(rules[i].replace_with));
|
||||
}
|
||||
free(exec_para);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
3222
plugin/business/tsg-http/src/tsg_http.cpp
Normal file
3222
plugin/business/tsg-http/src/tsg_http.cpp
Normal file
File diff suppressed because it is too large
Load Diff
397
plugin/business/tsg-http/src/tsg_logger.cpp
Normal file
397
plugin/business/tsg-http/src/tsg_logger.cpp
Normal file
@@ -0,0 +1,397 @@
|
||||
#include <cjson/cJSON.h>
|
||||
#include <MESA/MESA_prof_load.h>
|
||||
#include <tfe_kafka_logger.h>
|
||||
#include <cache_evbase_client.h>
|
||||
#include <tfe_utils.h>
|
||||
#include <tfe_resource.h>
|
||||
|
||||
#include "tsg_proxy_logger.h"
|
||||
|
||||
struct json_spec
|
||||
{
|
||||
const char *log_filed_name;
|
||||
enum tfe_http_std_field field_id;
|
||||
};
|
||||
struct proxy_logger
|
||||
{
|
||||
int entry_id;
|
||||
unsigned int en_hoslog;
|
||||
unsigned int en_sendlog;
|
||||
const char *device_id;
|
||||
const char *effective_device_tag;
|
||||
void* local_logger;
|
||||
|
||||
unsigned long long send_cnt;
|
||||
unsigned long long random_drop;
|
||||
unsigned long long user_abort;
|
||||
char local_log_path[TFE_STRING_MAX];
|
||||
tfe_kafka_logger_t *kafka_logger;
|
||||
struct cache_evbase_instance * log_file_upload_instance;
|
||||
};
|
||||
|
||||
enum _log_action //Bigger action number is prior.
|
||||
{
|
||||
LG_ACTION_NONE = 0x00,
|
||||
LG_ACTION_MONIT = 0x01,
|
||||
LG_ACTION_FORWARD = 0x02, /* N/A */
|
||||
LG_ACTION_REJECT = 0x10,
|
||||
LG_ACTION_DROP = 0x20, /* N/A */
|
||||
LG_ACTION_MANIPULATE = 0x30,
|
||||
LG_ACTION_RATELIMIT = 0x40, /* N/A */
|
||||
LG_ACTION_LOOP = 0x60, /* N/A */
|
||||
LG_ACTION_WHITELIST = 0x80,
|
||||
__LG_ACTION_MAX
|
||||
};
|
||||
|
||||
struct proxy_logger* proxy_log_handle_create(const char* profile, const char* section, void* local_logger)
|
||||
{
|
||||
struct tango_cache_parameter *log_file_upload_para=NULL;
|
||||
struct proxy_logger* instance=ALLOC(struct proxy_logger,1);
|
||||
instance->local_logger=local_logger;
|
||||
|
||||
TFE_LOG_INFO(local_logger,"Tsg-Pxy log is inititating from %s section %s.", profile, section);
|
||||
MESA_load_profile_int_def(profile, section, "ENTRANCE_ID",&(instance->entry_id),0);
|
||||
MESA_load_profile_uint_def(profile, section, "en_hoslog", &instance->en_hoslog, 1);
|
||||
MESA_load_profile_uint_def(profile, section, "en_sendlog", &instance->en_sendlog, 1);
|
||||
TFE_LOG_INFO(local_logger, "Tsg-Pxy sendlog : %s", instance->en_sendlog ? "ENABLE" : "DISABLE");
|
||||
|
||||
if (!instance->en_sendlog)
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
instance->device_id = (const char *)tfe_bussiness_resouce_get(DEVICE_ID);
|
||||
instance->effective_device_tag = (const char *)tfe_bussiness_resouce_get(EFFECTIVE_DEVICE_TAG);
|
||||
instance->kafka_logger = (tfe_kafka_logger_t *)tfe_bussiness_resouce_get(KAFKA_LOGGER);
|
||||
if (instance->kafka_logger && !instance->kafka_logger->enable)
|
||||
{
|
||||
TFE_LOG_ERROR(local_logger, "Tsg-Pxy sendlog ENABLE, but tfe kafka logger DISABLED.");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if(instance->en_hoslog==1)
|
||||
{
|
||||
log_file_upload_para=cache_evbase_parameter_new(profile, section, local_logger);
|
||||
if (log_file_upload_para == NULL)
|
||||
{
|
||||
TFE_LOG_ERROR(local_logger, "Tsg-Pxy failed to new cache evbase parameter.");
|
||||
goto error_out;
|
||||
}
|
||||
instance->log_file_upload_instance=cache_evbase_instance_new(log_file_upload_para, local_logger);
|
||||
}
|
||||
return instance;
|
||||
|
||||
error_out:
|
||||
free(instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned int proxy_log_get_fqdn_cat(struct tfe_cmsg *cmsg, unsigned int *category_id_val)
|
||||
{
|
||||
int ret=0;
|
||||
unsigned category_id_num=0;
|
||||
uint16_t opt_out_size;
|
||||
|
||||
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_FQDN_CAT_ID_NUM, (unsigned char *)&category_id_num, sizeof(category_id_num), &opt_out_size);
|
||||
if (ret != 0 || category_id_num == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_FQDN_CAT_ID_VAL, (unsigned char *)category_id_val, sizeof(category_id_val), &opt_out_size);
|
||||
if (ret != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return category_id_num > 8 ? 8 : category_id_num;
|
||||
}
|
||||
|
||||
int proxy_send_log(struct proxy_logger* handle, const struct proxy_log* log_msg)
|
||||
{
|
||||
const struct tfe_http_session* http=log_msg->http;
|
||||
const struct tfe_stream_addr* addr=log_msg->stream->addr;
|
||||
const char* tmp_val=NULL;
|
||||
cJSON *common_obj=NULL, *per_hit_obj=NULL;
|
||||
char* log_payload=NULL;
|
||||
int kafka_status=0;
|
||||
int send_cnt=0;
|
||||
int tmp=0;
|
||||
time_t cur_time;
|
||||
char src_ip_str[MAX(INET6_ADDRSTRLEN,INET_ADDRSTRLEN)] = {0};
|
||||
char dst_ip_str[MAX(INET6_ADDRSTRLEN,INET_ADDRSTRLEN)] = {0};
|
||||
|
||||
const char *app_proto[]= {"unkonw","http1", "http2"};
|
||||
|
||||
const char *manipulate_action_map[]= {"redirect","block","replace","hijack","insert","edit_element","run_script"};
|
||||
|
||||
const char *panggu_action_map[__LG_ACTION_MAX];
|
||||
panggu_action_map[LG_ACTION_MONIT]="monitor";
|
||||
panggu_action_map[LG_ACTION_REJECT]="deny";
|
||||
panggu_action_map[LG_ACTION_WHITELIST]="allow";
|
||||
|
||||
struct json_spec req_fields[]={ {"http_cookie", TFE_HTTP_COOKIE},
|
||||
{"http_referer", TFE_HTTP_REFERER},
|
||||
{"http_user_agent", TFE_HTTP_USER_AGENT},
|
||||
{"http_request_content_type", TFE_HTTP_CONT_TYPE},
|
||||
{"http_request_content_length", TFE_HTTP_CONT_LENGTH}};
|
||||
|
||||
struct json_spec resp_fields[]={ {"http_response_content_type", TFE_HTTP_CONT_TYPE},
|
||||
{"http_response_content_length", TFE_HTTP_CONT_LENGTH},
|
||||
{"http_set_cookie", TFE_HTTP_SET_COOKIE}};
|
||||
|
||||
if (!handle->en_sendlog)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
common_obj=cJSON_CreateObject();
|
||||
cur_time = time(NULL);
|
||||
|
||||
cJSON_AddNumberToObject(common_obj, "common_start_time", http->start_time);
|
||||
cJSON_AddNumberToObject(common_obj, "common_end_time", cur_time);
|
||||
cJSON_AddStringToObject(common_obj, "http_version", app_proto[http->major_version]);
|
||||
cJSON_AddStringToObject(common_obj, "common_schema_type", "HTTP");
|
||||
|
||||
unsigned int common_direction=0, category_id_val[8]={0};
|
||||
char opt_val[24]={0}; uint16_t opt_out_size;
|
||||
struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg(log_msg->stream);
|
||||
if (cmsg!=NULL)
|
||||
{
|
||||
int ret=tfe_cmsg_get_value(cmsg, TFE_CMSG_STREAM_TRACE_ID, (unsigned char *) opt_val, sizeof(opt_val), &opt_out_size);
|
||||
if (ret==0)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, "common_stream_trace_id", opt_val);
|
||||
}
|
||||
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_COMMON_DIRECTION, (unsigned char *)&common_direction, sizeof(common_direction), &opt_out_size);
|
||||
if (ret==0)
|
||||
{
|
||||
cJSON_AddNumberToObject(common_obj, "common_direction", common_direction); //0:域内->域外,1:域外->域内,描述的是CLIENT_IP信息
|
||||
}
|
||||
ret = proxy_log_get_fqdn_cat(cmsg, category_id_val);
|
||||
if (ret>0)
|
||||
{
|
||||
cJSON_AddItemToObject(common_obj, "common_service_category", cJSON_CreateIntArray((const int*)category_id_val, ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (http->req)
|
||||
{
|
||||
char *request_line=NULL;
|
||||
struct tfe_http_req_spec req_spec=http->req->req_spec;
|
||||
asprintf(&request_line, "%s %s HTTP/%d.%d", http_std_method_to_string(req_spec.method), req_spec.url, http->major_version, http->minor_version);
|
||||
cJSON_AddStringToObject(common_obj, "http_request_line", request_line);
|
||||
free(request_line);
|
||||
}
|
||||
|
||||
if (http->resp)
|
||||
{
|
||||
char *response_line=NULL;
|
||||
struct tfe_http_resp_spec resp_spec=http->resp->resp_spec;
|
||||
asprintf(&response_line, "HTTP/%d.%d %d OK", http->major_version, http->minor_version, resp_spec.resp_code);
|
||||
cJSON_AddStringToObject(common_obj, "http_response_line", response_line);
|
||||
free(response_line);
|
||||
}
|
||||
|
||||
switch(addr->addrtype)
|
||||
{
|
||||
case TFE_ADDR_STREAM_TUPLE4_V4:
|
||||
cJSON_AddNumberToObject(common_obj, "common_address_type", 4);
|
||||
inet_ntop(AF_INET, &addr->tuple4_v4->saddr, src_ip_str, sizeof(src_ip_str));
|
||||
inet_ntop(AF_INET, &addr->tuple4_v4->daddr, dst_ip_str, sizeof(dst_ip_str));
|
||||
cJSON_AddStringToObject(common_obj, "common_client_ip", src_ip_str);
|
||||
cJSON_AddStringToObject(common_obj, "common_server_ip", dst_ip_str);
|
||||
cJSON_AddNumberToObject(common_obj, "common_client_port", ntohs(addr->tuple4_v4->source));
|
||||
cJSON_AddNumberToObject(common_obj, "common_server_port", ntohs(addr->tuple4_v4->dest));
|
||||
cJSON_AddStringToObject(common_obj, "common_l4_protocol", "IPv4_TCP");
|
||||
break;
|
||||
case TFE_ADDR_STREAM_TUPLE4_V6:
|
||||
cJSON_AddNumberToObject(common_obj, "common_address_type", 6);
|
||||
inet_ntop(AF_INET6, &addr->tuple4_v6->saddr, src_ip_str, sizeof(src_ip_str));
|
||||
inet_ntop(AF_INET6, &addr->tuple4_v6->daddr, dst_ip_str, sizeof(dst_ip_str));
|
||||
cJSON_AddStringToObject(common_obj, "common_client_ip", src_ip_str);
|
||||
cJSON_AddStringToObject(common_obj, "common_server_ip", dst_ip_str);
|
||||
cJSON_AddNumberToObject(common_obj, "common_client_port", ntohs(addr->tuple4_v6->source));
|
||||
cJSON_AddNumberToObject(common_obj, "common_server_port", ntohs(addr->tuple4_v6->dest));
|
||||
cJSON_AddStringToObject(common_obj, "common_l4_protocol", "IPv6_TCP");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
size_t c2s_byte_num = 0, s2c_byte_num =0;
|
||||
tfe_stream_info_get(log_msg->stream, INFO_FROM_DOWNSTREAM_RX_OFFSET, &c2s_byte_num, sizeof(c2s_byte_num));
|
||||
tfe_stream_info_get(log_msg->stream, INFO_FROM_UPSTREAM_RX_OFFSET, &s2c_byte_num, sizeof(s2c_byte_num));
|
||||
|
||||
cJSON_AddNumberToObject(common_obj, "common_link_id", 0);
|
||||
cJSON_AddNumberToObject(common_obj, "common_stream_dir", 3); //1:c2s, 2:s2c, 3:double
|
||||
cJSON_AddStringToObject(common_obj, "common_sled_ip", handle->kafka_logger->local_ip_str);
|
||||
cJSON_AddNumberToObject(common_obj, "common_entrance_id", handle->entry_id);
|
||||
cJSON_AddStringToObject(common_obj, "common_device_id", handle->device_id);
|
||||
cJSON_AddNumberToObject(common_obj, "common_c2s_byte_num", c2s_byte_num);
|
||||
cJSON_AddNumberToObject(common_obj, "common_s2c_byte_num", s2c_byte_num);
|
||||
cJSON_AddStringToObject(common_obj, "http_url", http->req->req_spec.url);
|
||||
cJSON_AddStringToObject(common_obj, "http_host", http->req->req_spec.host);
|
||||
if(handle->effective_device_tag)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, "common_device_tag", handle->effective_device_tag);
|
||||
}
|
||||
|
||||
for(size_t i=0;i<sizeof(req_fields)/sizeof(struct json_spec);i++)
|
||||
{
|
||||
tmp_val=tfe_http_std_field_read(http->req, req_fields[i].field_id);
|
||||
if(tmp_val!=NULL)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj,req_fields[i].log_filed_name, tmp_val);
|
||||
}
|
||||
}
|
||||
for(size_t i=0;i<sizeof(resp_fields)/sizeof(struct json_spec) && http->resp!=NULL;i++)
|
||||
{
|
||||
tmp_val=tfe_http_std_field_read(http->resp, resp_fields[i].field_id);
|
||||
if(tmp_val!=NULL)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj,resp_fields[i].log_filed_name, tmp_val);
|
||||
}
|
||||
}
|
||||
|
||||
char log_file_upload_req_path[TFE_STRING_MAX]={0}, cont_type_whole[TFE_STRING_MAX]={0};
|
||||
char log_file_upload_resp_path[TFE_STRING_MAX]={0};
|
||||
memset(log_file_upload_req_path, 0, sizeof(log_file_upload_req_path));
|
||||
memset(log_file_upload_resp_path, 0, sizeof(log_file_upload_resp_path));
|
||||
memset(cont_type_whole, 0, sizeof(cont_type_whole));
|
||||
|
||||
for(size_t i=0; i<log_msg->result_num; i++)
|
||||
{
|
||||
if(log_msg->result[i].do_log!=1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(handle->en_hoslog!=1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
struct tango_cache_meta_put meta;
|
||||
char* log_file_key=NULL;;
|
||||
const char* cont_type_val;
|
||||
if(log_msg->req_body!=NULL)
|
||||
{
|
||||
if(log_file_upload_req_path[0] != '\0')
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, "http_request_body", log_file_upload_req_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&meta, 0, sizeof(meta));
|
||||
asprintf(&log_file_key, "%s.reqbody", http->req->req_spec.url);
|
||||
meta.url=log_file_key;
|
||||
cont_type_val=tfe_http_std_field_read(http->req, TFE_HTTP_CONT_TYPE);
|
||||
if(cont_type_val!=NULL)
|
||||
{
|
||||
snprintf(cont_type_whole, sizeof(cont_type_whole), "Content-Type:%s", cont_type_val);
|
||||
meta.std_hdr[0]=cont_type_whole;
|
||||
}
|
||||
meta.user_log_name=1;
|
||||
tmp=cache_evbase_upload_once_evbuf(handle->log_file_upload_instance, NULL,
|
||||
log_msg->req_body,
|
||||
&meta,
|
||||
log_file_upload_req_path, sizeof(log_file_upload_req_path));
|
||||
if(tmp==0)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, "http_request_body", log_file_upload_req_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
TFE_LOG_ERROR(handle->local_logger, "Upload req_body failed.");
|
||||
}
|
||||
free(log_file_key);
|
||||
}
|
||||
}
|
||||
if(log_msg->resp_body!=NULL)
|
||||
{
|
||||
if(log_file_upload_resp_path[0] != '\0')
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, "http_response_body", log_file_upload_resp_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&meta, 0, sizeof(meta));
|
||||
asprintf(&log_file_key, "%s.respbody", http->req->req_spec.url);
|
||||
meta.url=log_file_key;
|
||||
cont_type_val=tfe_http_std_field_read(http->resp, TFE_HTTP_CONT_TYPE);
|
||||
if(cont_type_val!=NULL)
|
||||
{
|
||||
snprintf(cont_type_whole, sizeof(cont_type_whole), "Content-Type:%s", cont_type_val);
|
||||
meta.std_hdr[0]=cont_type_whole;
|
||||
}
|
||||
meta.user_log_name=1;
|
||||
tmp=cache_evbase_upload_once_evbuf(handle->log_file_upload_instance, NULL,
|
||||
log_msg->resp_body,
|
||||
&meta,
|
||||
log_file_upload_resp_path, sizeof(log_file_upload_resp_path));
|
||||
|
||||
if(tmp==0)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, "http_response_body", log_file_upload_resp_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
TFE_LOG_ERROR(handle->local_logger, "Upload resp_body failed.");
|
||||
}
|
||||
free(log_file_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i=0; i<log_msg->result_num; i++)
|
||||
{
|
||||
|
||||
TFE_LOG_DEBUG(handle->local_logger, "URL: %s, policy_id: %d, service: %d, do_log:%d",
|
||||
http->req->req_spec.url,
|
||||
log_msg->result[i].config_id,
|
||||
log_msg->result[i].service_id,
|
||||
log_msg->result[i].do_log);
|
||||
|
||||
if(log_msg->result[i].do_log==0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
per_hit_obj=cJSON_Duplicate(common_obj, 1);
|
||||
cJSON_AddNumberToObject(per_hit_obj, "common_policy_id", log_msg->result[i].config_id);
|
||||
cJSON_AddNumberToObject(per_hit_obj, "common_service", log_msg->result[i].service_id);
|
||||
cJSON_AddNumberToObject(per_hit_obj, "common_action", LG_ACTION_MANIPULATE);
|
||||
if(log_msg->result[i].action == LG_ACTION_MANIPULATE)
|
||||
{
|
||||
cJSON_AddStringToObject(per_hit_obj, "common_sub_action", manipulate_action_map[log_msg->action]);
|
||||
cJSON_AddNumberToObject(per_hit_obj, "http_action_file_size", log_msg->inject_sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
cJSON_AddStringToObject(per_hit_obj, "common_sub_action", panggu_action_map[(unsigned char)(log_msg->result[i].action)]);
|
||||
}
|
||||
if(log_msg->location_client)
|
||||
{
|
||||
cJSON_AddStringToObject(per_hit_obj, "common_client_location", log_msg->location_client);
|
||||
}
|
||||
if(log_msg->location_server)
|
||||
{
|
||||
cJSON_AddStringToObject(per_hit_obj, "common_server_location", log_msg->location_server);
|
||||
}
|
||||
|
||||
log_payload = cJSON_PrintUnformatted(per_hit_obj);
|
||||
|
||||
TFE_LOG_DEBUG(handle->local_logger, "%s", log_payload);
|
||||
|
||||
kafka_status = tfe_kafka_logger_send(handle->kafka_logger, log_payload, strlen(log_payload));
|
||||
free(log_payload);
|
||||
cJSON_Delete(per_hit_obj);
|
||||
if(kafka_status<0)
|
||||
{
|
||||
TFE_LOG_ERROR(handle->local_logger, "Kafka produce failed: %s", rd_kafka_err2name(rd_kafka_last_error()));
|
||||
}
|
||||
send_cnt++;
|
||||
}
|
||||
|
||||
cJSON_Delete(common_obj);
|
||||
return send_cnt;
|
||||
}
|
||||
1438
plugin/business/tsg-http/src/tsg_web_cache.cpp
Normal file
1438
plugin/business/tsg-http/src/tsg_web_cache.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user