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 #include #include +#include #include #include @@ -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; iparam; @@ -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 0 && rewrite_uri != NULL) + { + printf("rewrite_uri = %s\n", rewrite_uri); + free(rewrite_uri); + } + else + { + printf("rd_url = %s\n", rd_url); + } return; }