diff options
| -rw-r--r-- | plugin/business/pangu-http/src/pangu_http.cpp | 89 | ||||
| -rw-r--r-- | plugin/business/pangu-http/src/pattern_replace.cpp | 7 | ||||
| -rw-r--r-- | plugin/business/pangu-http/src/test_pattern_replace.cpp | 55 |
3 files changed, 147 insertions, 4 deletions
diff --git a/plugin/business/pangu-http/src/pangu_http.cpp b/plugin/business/pangu-http/src/pangu_http.cpp index 512dd83..86a07ba 100644 --- a/plugin/business/pangu-http/src/pangu_http.cpp +++ b/plugin/business/pangu-http/src/pangu_http.cpp @@ -9,6 +9,7 @@ #include <tfe_plugin.h> #include <tfe_resource.h> #include <tfe_scan.h> +#include <tfe_types.h> #include <MESA/Maat_rule.h> #include <MESA/MESA_handle_logger.h> @@ -1525,11 +1526,82 @@ static UNUSED void http_reject(const struct tfe_http_session * session, enum tfe return; } -static void http_redirect(const struct tfe_http_session * session, enum tfe_http_event events, +static void http_get_client_id(const struct tfe_stream * stream, char *replace_regex) +{ + const char *sip,*dip,*sport,*dport; + + tfe_stream_addr_str_split((char *)stream->str_stream_info, &sip, &sport, &dip, &dport); + + snprintf(replace_regex, TFE_SYMBOL_MAX, "%s=%s", "source_ip", sip); +} + +static void http_get_subscriber_id(const struct tfe_stream * stream, char *replace_regex) +{ + int ret = 0; + uint16_t opt_out_size; + char source_subscribe_id[TFE_STRING_MAX] = {0}; + struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(stream); + if (cmsg != NULL) + { + ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_SRC_SUB_ID, (unsigned char *)source_subscribe_id, sizeof(source_subscribe_id), &opt_out_size); + if (ret != 0) + { + TFE_LOG_ERROR(g_pangu_rt->local_logger, "fetch src sub id from cmsg failed, ret: %d addr: %s", ret, stream->str_stream_info); + } + } + snprintf(replace_regex, TFE_SYMBOL_MAX, "%s=%s", "user_id", source_subscribe_id); +} + +static int http_decoder_url(const struct tfe_stream * stream, char *rd_url, int profile_id, char **rewrite_uri) +{ + int i=0, n_rule=0; + char replace_with[TFE_SYMBOL_MAX]={0}; + struct replace_rule *rule; + + if(strstr(rd_url, "policy_id")==NULL && strstr(rd_url, "user_id")==NULL && strstr(rd_url, "source_ip")==NULL) + { + return 0; + } + + rule = ALLOC(struct replace_rule, 3); + n_rule=0; + rule[n_rule].zone = kZoneRequestUri; + rule[n_rule].find = tfe_strdup("policy_id={{tsg_policy_id}}"); + snprintf(replace_with, TFE_SYMBOL_MAX, "policy_id=%d", profile_id); + rule[n_rule].replace_with = tfe_strdup(replace_with); + + n_rule=1; + memset(replace_with, TFE_SYMBOL_MAX, 0); + rule[n_rule].zone = kZoneRequestUri; + rule[n_rule].find = tfe_strdup("user_id={{tsg_subscriber_id}}"); + http_get_subscriber_id(stream, replace_with); + rule[n_rule].replace_with = tfe_strdup(replace_with); + + n_rule=2; + memset(replace_with, TFE_SYMBOL_MAX, 0); + rule[n_rule].zone = kZoneRequestUri; + rule[n_rule].find = tfe_strdup("source_ip={{tsg_client_ip}}"); + http_get_client_id(stream, replace_with); + rule[n_rule].replace_with = tfe_strdup(replace_with); + + size_t rewrite_uri_sz = execute_replace_rule(rd_url, strlen(rd_url), kZoneRequestUri, rule, n_rule+1, rewrite_uri, 1); + + for(i=0; i<n_rule+1; i++) + { + FREE(&(rule[i].find)); + FREE(&(rule[i].replace_with)); + } + FREE(&rule); + + return rewrite_uri_sz; +} + +static void http_redirect(const struct tfe_stream * stream, const struct tfe_http_session * session, enum tfe_http_event events, struct pangu_http_ctx * ctx) { struct tfe_http_half * response = NULL; struct tfe_http_session * to_write = NULL; + size_t rewrite_uri_sz=0; char *rewrite_uri=NULL; struct policy_action_param *param = ctx->param; @@ -1566,7 +1638,18 @@ static void http_redirect(const struct tfe_http_session * session, enum tfe_http ATOMIC_INC(&(g_pangu_rt->stat_val[STAT_ACTION_REDIRECT])); response = tfe_http_session_response_create(to_write, resp_code); - tfe_http_std_field_write(response, TFE_HTTP_LOCATION, rd_url); + + rewrite_uri_sz = http_decoder_url(stream, rd_url, ctx->enforce_rules[0].config_id, &rewrite_uri); + if(rewrite_uri_sz>0 && rewrite_uri!= NULL) + { + tfe_http_std_field_write(response, TFE_HTTP_LOCATION, rewrite_uri); + FREE(&rewrite_uri); + } + else + { + tfe_http_std_field_write(response, TFE_HTTP_LOCATION, rd_url); + } + tfe_http_std_field_write(response, TFE_HTTP_CONT_LENGTH, "0"); tfe_http_half_append_body(response, NULL, 0, 0); @@ -1906,7 +1989,7 @@ static void http_manipulate(const struct tfe_stream * stream, const struct tfe_h switch(param->action) { case MA_ACTION_REDIRECT: - http_redirect(session, events, ctx); + http_redirect(stream, session, events, ctx); break; case MA_ACTION_BLOCK: http_block(session, events, ctx); diff --git a/plugin/business/pangu-http/src/pattern_replace.cpp b/plugin/business/pangu-http/src/pattern_replace.cpp index f24d2cf..4b7f2ad 100644 --- a/plugin/business/pangu-http/src/pattern_replace.cpp +++ b/plugin/business/pangu-http/src/pattern_replace.cpp @@ -336,10 +336,15 @@ void simple_replace(const char* find, const char* replacement, const char* input { char* exec_para=NULL; asprintf(&exec_para,"zone=http_resp_body;substitute=/%s/%s", find, replacement); - size_t n_got_rule=0; + 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; } diff --git a/plugin/business/pangu-http/src/test_pattern_replace.cpp b/plugin/business/pangu-http/src/test_pattern_replace.cpp index ccd9c1d..c993b06 100644 --- a/plugin/business/pangu-http/src/test_pattern_replace.cpp +++ b/plugin/business/pangu-http/src/test_pattern_replace.cpp @@ -173,6 +173,61 @@ TEST(PatternReplace, QueryAdd) printf("%s\n", output); free(output); + + return; +} + +TEST(PatternReplace, UrlReplace) +{ + int i=0, n_rule=0; + char replace_with[TFE_SYMBOL_MAX]={0}; + struct replace_rule *rule; + char *rewrite_uri=NULL; + + const char *rd_url = "http://www.example.com/query?pageid=12345&policy_id={{tsg_policy_id}}&user_id={{tsg_subscriber_id}}&source_ip={{tsg_client_ip}}"; + + if(strstr(rd_url, "policy_id")==NULL && strstr(rd_url, "user_id")==NULL && strstr(rd_url, "source_ip")==NULL) + { + return; + } + + rule = ALLOC(struct replace_rule, 3); + n_rule=0; + rule[n_rule].zone = kZoneRequestUri; + rule[n_rule].find = tfe_strdup("policy_id={{tsg_policy_id}}"); + snprintf(replace_with, TFE_SYMBOL_MAX, "policy_id=%d", 23); + rule[n_rule].replace_with = tfe_strdup(replace_with); + + n_rule=1; + memset(replace_with, TFE_SYMBOL_MAX, 0); + rule[n_rule].zone = kZoneRequestUri; + rule[n_rule].find = tfe_strdup("user_id={{tsg_subscriber_id}}"); + rule[n_rule].replace_with = tfe_strdup("user_id=te&st01"); + + n_rule=2; + memset(replace_with, TFE_SYMBOL_MAX, 0); + rule[n_rule].zone = kZoneRequestUri; + rule[n_rule].find = tfe_strdup("source_ip={{tsg_client_ip}}"); + rule[n_rule].replace_with = tfe_strdup("source_ip=192.168.50.71"); + + size_t rewrite_uri_sz = execute_replace_rule(rd_url, strlen(rd_url), kZoneRequestUri, rule, n_rule+1, &rewrite_uri, 1); + + for(i=0; i<n_rule+1; i++) + { + FREE(&(rule[i].find)); + FREE(&(rule[i].replace_with)); + } + FREE(&rule); + + if(rewrite_uri_sz > 0 && rewrite_uri != NULL) + { + printf("rewrite_uri = %s\n", rewrite_uri); + free(rewrite_uri); + } + else + { + printf("rd_url = %s\n", rd_url); + } return; } |
