Merge branch 'develop-tfe4a' of git.mesalab.cn:tango/tfe into develop-tfe4a

This commit is contained in:
zhengchao
2019-06-05 20:43:55 +08:00
7 changed files with 232 additions and 122 deletions

View File

@@ -5,6 +5,7 @@ log_level=10
nic_name=eth4
entrance_id=0
kafka_brokerlist=10.4.34.10:9092,10.4.34.11:9092,10.4.34.12:9092,10.4.34.13:9092,10.4.34.14:9092,10.4.34.15:9092,10.4.34.16:9092,10.4.34.17:9092,10.4.34.18:9092,10.4.34.19:9092
kafka_topic=policy-event-log
#Addresses of minio. Format is defined by WiredLB.
minio_ip_list=10.4.35.42-46;
minio_listen_port=9000

View File

@@ -667,16 +667,10 @@ void ma_hijack_profile_table_new_cb(int table_id, const char* key, const char* t
return;
}
struct manipulate_profile* ply_profile=ALLOC(struct manipulate_profile, 1);
memset(ply_profile, 0, sizeof(struct manipulate_profile));
ply_profile->profile_id=profile_id;
ply_profile->ref_cnt=1;
ply_profile->profile_msg = execute_read_file(profile_path, &ply_profile->msg_len);
if (ply_profile->profile_msg == NULL)
{
TFE_LOG_ERROR(g_pangu_rt->local_logger, "Read file failed %d:%s:%s", profile_id, profile_name, profile_path);
}
ply_profile->profile_id=profile_id;
ply_profile->profile_msg=tfe_strdup(profile_path);
ply_profile->profile_name=tfe_strdup(hijack_name);
ply_profile->profile_type=tfe_strdup(formate);
@@ -734,6 +728,7 @@ int maat_table_ex_init(int profile_idx,
Maat_plugin_EX_dup_func_t* dup_func)
{
int table_id = 0;
const char *table_name_map[] = {"PXY_PROFILE_RESPONSE_PAGES",
"PXY_PROFILE_INSERT_SCRIPTS",
"PXY_PROFILE_HIJACK_FILES"};
@@ -1195,7 +1190,15 @@ static void template_generate(int status_code, int cfg_id, const char* msg, char
{
ctemplate::TemplateDictionary dict("pg_page_dict"); //dict is automatically finalized after function returned.
dict.SetIntValue("cfg_id", cfg_id);
dict.SetValue("msg", msg);
if (NULL == msg)
{
dict.SetValue("msg", "NULL");
}
else
{
dict.SetValue("msg", msg);
}
std::string output;
ctemplate::Template * tpl = NULL;
@@ -1378,7 +1381,6 @@ void http_replace(const struct tfe_stream * stream, const struct tfe_http_sessio
rewrite_sz = execute_replace_rule(__http_body, __http_body_len, r_zone,
rep_ctx->rule, rep_ctx->n_rule, &rewrite_buff);
if (rewrite_sz >0 )
{
tfe_http_half_append_body(rep_ctx->replacing, rewrite_buff, rewrite_sz, 0);
@@ -1425,7 +1427,7 @@ static void http_reject(const struct tfe_http_session * session, enum tfe_http_e
resp_code = param->status_code;
msg = param->message;
if (resp_code <= 0 || msg != NULL){
if (resp_code <= 0){
TFE_LOG_ERROR(g_pangu_rt->local_logger, "Invalid block rule %d", ctx->enforce_rules[0].config_id);
ctx->action = PG_ACTION_NONE;
return;
@@ -1564,22 +1566,35 @@ static void http_hijack(const struct tfe_http_session * session, enum tfe_http_e
return;
}
char * hijack_buff=NULL; size_t hijack_size=0;
hijack_buff = execute_read_file(hijack_profile->profile_msg, &hijack_size);
if (NULL == hijack_buff){
TFE_LOG_ERROR(g_pangu_rt->local_logger, "read hijack file faild, path = %s", hijack_profile->profile_msg);
ctx->action = PG_ACTION_NONE;
return;
}
struct tfe_http_session * to_write_sess = NULL;
char cont_len_str[16];
to_write_sess = tfe_http_session_allow_write(session);
response = tfe_http_session_response_create(to_write_sess, 200);
int hijack_len = strlen(hijack_profile->profile_name)+strlen("filename=\"\"")+1;
char *hijack_name = ALLOC(char, hijack_len);
snprintf(hijack_name, hijack_len, "filename=\"%s\"", hijack_profile->profile_name);
tfe_http_nonstd_field_write(response, "Content-Disposition", hijack_name);
FREE(&hijack_name);
if (0!=strcasecmp(hijack_profile->profile_name, "null"))
{
int hijack_file_len = strlen(hijack_profile->profile_name)+strlen("filename=\"\"")+1;
char *hijack_file_name = ALLOC(char, hijack_file_len);
snprintf(hijack_file_name, hijack_file_len, "filename=\"%s\"", hijack_profile->profile_name);
tfe_http_nonstd_field_write(response, "Content-Disposition", hijack_file_name);
FREE(&hijack_file_name);
}
tfe_http_std_field_write(response, TFE_HTTP_CONT_TYPE, hijack_profile->profile_type);
snprintf(cont_len_str, sizeof(cont_len_str), "%lu", hijack_profile->msg_len);
snprintf(cont_len_str, sizeof(cont_len_str), "%lu", hijack_size);
tfe_http_std_field_write(response, TFE_HTTP_CONT_LENGTH, cont_len_str);
tfe_http_half_append_body(response, hijack_profile->profile_msg, hijack_profile->msg_len, 0);
tfe_http_half_append_body(response, hijack_buff, hijack_size, 0);
tfe_http_half_append_body(response, NULL, 0, 0);
tfe_http_session_response_set(to_write_sess, response);
tfe_http_session_detach(session);
@@ -1638,7 +1653,7 @@ static void http_insert(const struct tfe_stream * stream, const struct tfe_http_
int ret=format_insert_rule(param->profile_id, param->position, ins_ctx->rule);
if (ret<0)
{
TFE_LOG_ERROR(g_pangu_rt->local_logger, "Failed to get policy table, table_id = %d", param->profile_id);
TFE_LOG_ERROR(g_pangu_rt->local_logger, "Failed to get policy table, profile_id = %d", param->profile_id);
ctx->action = PG_ACTION_NONE;
return;
}

View File

@@ -31,14 +31,14 @@ struct pangu_logger
unsigned int en_sendlog;
unsigned int en_sendlog_meta;
unsigned int en_sendlog_body;
unsigned int local_ip_nr;
void* global_logger;
rd_kafka_t *kafka_handle;
rd_kafka_topic_t* kafka_topic;
pthread_mutex_t mutex;
char brokerlist[TFE_STRING_MAX];
const char* topic_name;
char topic_name[TFE_STRING_MAX];
void* local_logger;
@@ -56,7 +56,7 @@ static unsigned int get_ip_by_eth_name(const char *ifname)
unsigned int ip;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sockfd)
if (-1 == sockfd)
{
goto error;
}
@@ -81,7 +81,7 @@ error:
static rd_kafka_t * create_kafka_handle(const char* brokerlist)
{
char kafka_errstr[1024];
rd_kafka_t *handle=NULL;
rd_kafka_t *handle=NULL;
rd_kafka_conf_t *rdkafka_conf = NULL;
rdkafka_conf = rd_kafka_conf_new();
@@ -133,7 +133,7 @@ struct pangu_logger* pangu_log_handle_create(const char* profile, const char* s
{
return instance;
}
MESA_load_profile_string_def(profile, section, "NIC_NAME",nic_name,sizeof(nic_name),"eth0");
instance->local_ip_nr=get_ip_by_eth_name(nic_name);
if(instance->local_ip_nr==INADDR_NONE)
@@ -143,7 +143,7 @@ struct pangu_logger* pangu_log_handle_create(const char* profile, const char* s
}
inet_ntop(AF_INET,&(instance->local_ip_nr),instance->local_ip_str,sizeof(instance->local_ip_str));
MESA_load_profile_int_def(profile, section, "ENTRANCE_ID",&(instance->entry_id),0);
ret=MESA_load_profile_string_def(profile, section,"KAFKA_BROKERLIST", instance->brokerlist, sizeof(instance->brokerlist), NULL);
if(ret<0)
@@ -155,17 +155,21 @@ struct pangu_logger* pangu_log_handle_create(const char* profile, const char* s
instance->kafka_handle=create_kafka_handle(instance->brokerlist);
if(instance->kafka_handle==NULL)
{
TFE_LOG_ERROR(local_logger,"Pangu log init failed. Cannot create lafka handle with brokerlist: %s.", instance->brokerlist);
TFE_LOG_ERROR(local_logger,"Pangu log init failed. Cannot create lafka handle with brokerlist: %s.", instance->brokerlist);
goto error_out;
}
instance->topic_name="PXY-HTTP-LOG";
MESA_load_profile_string_def(profile, section,"KAFKA_TOPIC", instance->topic_name, sizeof(instance->topic_name), "POLICY-EVENT-LOG");
TFE_LOG_INFO(local_logger, "Pangu kafka brokerlist : %s", instance->brokerlist);
TFE_LOG_INFO(local_logger, "Pangu kafka topic : %s", instance->topic_name);
instance->kafka_topic = rd_kafka_topic_new(instance->kafka_handle,instance->topic_name, NULL);
log_file_upload_para=cache_evbase_parameter_new(profile, section, local_logger);
instance->log_file_upload_instance=cache_evbase_instance_new(log_file_upload_para, local_logger);
pthread_mutex_init(&(instance->mutex), NULL);
return instance;
error_out:
free(instance);
return NULL;
@@ -185,11 +189,12 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg)
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.0", "http2.0"};
struct json_spec req_fields[]={ {"cookie", TFE_HTTP_COOKIE},
struct json_spec req_fields[]={ {"cookie", TFE_HTTP_COOKIE},
{"referer", TFE_HTTP_REFERER},
{"user_agent", TFE_HTTP_USER_AGENT} };
struct json_spec resp_fields[]={ {"content_type", TFE_HTTP_CONT_TYPE},
{"content_len", TFE_HTTP_CONT_LENGTH} };
@@ -203,7 +208,7 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg)
cJSON_AddNumberToObject(common_obj, "start_time", cur_time);
cJSON_AddNumberToObject(common_obj, "end_time", cur_time);
cJSON_AddNumberToObject(common_obj, "recv_time", cur_time);
cJSON_AddStringToObject(common_obj, "app_proto", app_proto[http->major_version]);
switch(addr->addrtype)
{
@@ -231,11 +236,13 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg)
break;
}
cJSON_AddNumberToObject(common_obj, "direction", 0); //0域内->域外1域外->域内描述的是CLIENT_IP信息
cJSON_AddNumberToObject(common_obj, "Link_id", 0);
cJSON_AddNumberToObject(common_obj, "stream_dir", 3); //1:c2s, 2:s2c, 3:double
cJSON_AddStringToObject(common_obj, "cap_ip", handle->local_ip_str);
cJSON_AddNumberToObject(common_obj, "entrance_id", handle->entry_id);
cJSON_AddNumberToObject(common_obj, "device_id", 0);
cJSON_AddStringToObject(common_obj, "url", http->req->req_spec.url);
cJSON_AddStringToObject(common_obj, "host", http->req->req_spec.host);
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);
@@ -267,9 +274,9 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg)
snprintf(cont_type_whole, sizeof(cont_type_whole), "Content-Type:%s", cont_type_val);
meta.std_hdr[0]=cont_type_whole;
}
tmp=cache_evbase_upload_once_evbuf(handle->log_file_upload_instance, NULL,
log_msg->req_body,
&meta,
tmp=cache_evbase_upload_once_evbuf(handle->log_file_upload_instance, NULL,
log_msg->req_body,
&meta,
log_file_upload_path, sizeof(log_file_upload_path));
if(tmp==0)
{
@@ -292,9 +299,9 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg)
snprintf(cont_type_whole, sizeof(cont_type_whole), "Content-Type:%s", cont_type_val);
meta.std_hdr[0]=cont_type_whole;
}
tmp=cache_evbase_upload_once_evbuf(handle->log_file_upload_instance, NULL,
log_msg->resp_body,
&meta,
tmp=cache_evbase_upload_once_evbuf(handle->log_file_upload_instance, NULL,
log_msg->resp_body,
&meta,
log_file_upload_path, sizeof(log_file_upload_path));
if(tmp==0)
@@ -311,7 +318,7 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg)
for(size_t i=0; i<log_msg->result_num; i++)
{
TFE_LOG_DEBUG(handle->local_logger, "URL: %s , hit cfg_id: %d service: %d",
http->req->req_spec.url,
log_msg->result[i].config_id,
@@ -330,7 +337,7 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg)
TFE_LOG_DEBUG(handle->local_logger, "%s", log_payload);
kafka_status = rd_kafka_produce(handle->kafka_topic, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_COPY,
kafka_status = rd_kafka_produce(handle->kafka_topic, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_COPY,
log_payload, strlen(log_payload), NULL, 0, NULL);
free(log_payload);
cJSON_Delete(per_hit_obj);
@@ -339,7 +346,7 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg)
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;

View File

@@ -152,7 +152,44 @@ TEST(PatternReplace, CaseInsensitiveRussian)
EXPECT_TRUE(output_sz>0);
EXPECT_TRUE(NULL==strstr(output, find));
EXPECT_TRUE(NULL!=strstr(output, replacement));
free(output);
return;
}
TEST(PatternReplace, QueryAdd)
{
const char * find = "(?<=\\?|^|&)q=([^&|^#]*)(?=&|$)";
const char* replacement="q=find";
const char* input="https://cn.bing.com/search?ei=pQnxXPS-LPSGr7wP3u6usAY&q=test&oq=test&gs_l=psy-ab.3..0i131i67j0l8j0i131.26791.27227..27885...0.0..0.235.683.0j3j1......0....1..gws-wiz.......0i71j0i67.klHdqBPS88k";
char* output=NULL;
size_t output_sz=0;
simple_replace(find, replacement, input, strlen(input),&output, &output_sz);
EXPECT_TRUE(output_sz>0);
EXPECT_TRUE(NULL==strstr(output, find));
EXPECT_TRUE(NULL!=strstr(output, replacement));
printf("%s\n", output);
free(output);
return;
}
TEST(PatternReplace, QueryDel)
{
const char * find = "(?<=\\?|^|&)sk=([^&|^#]*)(&|$)";
const char* replacement="";
const char* input="https://cn.bing.com/&search?q=find&qs=n&form=QBLH&sp=-1&pq=find&sk=";
char* output=NULL;
size_t output_sz=0;
simple_replace(find, replacement, input, strlen(input),&output, &output_sz);
EXPECT_TRUE(output_sz>0);
EXPECT_TRUE(NULL==strstr(output, find));
EXPECT_TRUE(NULL!=strstr(output, replacement));
printf("%s\n", output);
free(output);
return;
}

View File

@@ -184,7 +184,7 @@ enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_p
param=(struct intercept_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->table_id, policy_id_str);
if(param==NULL)
{
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %d.", param->policy_id);
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %d.", policy_id);
return SSL_ACTION_PASSTHROUGH;
}
int pinning_staus=0, is_ev=0, is_ct=0, is_mauth=0, has_error=0;

View File

@@ -59,7 +59,7 @@ struct tfe_h2_half_private
int by_stream;
char * url_storage;
struct tfe_h2_payload body;
struct tfe_h2_payload h2_payload;
struct tfe_h2_header header;
struct tfe_h2_header promised;

View File

@@ -113,7 +113,7 @@ TAILQ_LIST_FIND(struct tfe_h2_stream *h2_stream_info, int32_t stream_id)
return stream;
}
static void
static void
tfe_h2_header_add_field(struct tfe_h2_header *h2_header, const struct http_field_name * field, const char * value, int at_tail)
{
struct tfe_h2_field *peer_h2_field = ALLOC(struct tfe_h2_field, 1);
@@ -137,6 +137,32 @@ tfe_h2_header_add_field(struct tfe_h2_header *h2_header, const struct http_field
TAILQ_INSERT_HEAD(&h2_header->h2_field_list, peer_h2_field, next);
}
static nghttp2_nv*
tfe_h2_header_modify_field(struct tfe_h2_header *header, nghttp2_nv *hdrs, const char *field_name, const char *filed_value)
{
int nvlen = 0;
struct tfe_h2_field *h2_field = NULL, *peer_h2_field = NULL;
TAILQ_FOREACH_SAFE(h2_field, &header->h2_field_list, next, peer_h2_field)
{
hdrs[nvlen].name = h2_field->nv.name;
hdrs[nvlen].namelen = h2_field->nv.namelen;
if (filed_value && (0==strcasecmp((const char*)h2_field->nv.name, field_name)))
{
hdrs[nvlen].value = (uint8_t *)filed_value;
hdrs[nvlen].valuelen = strlen(filed_value);
}
else
{
hdrs[nvlen].value = h2_field->nv.value;
hdrs[nvlen].valuelen = h2_field->nv.valuelen;
}
hdrs[nvlen].flags = h2_field->nv.flags;
nvlen++;
}
return hdrs;
}
static inline void
headers_init(struct tfe_h2_header *header)
{
@@ -169,12 +195,12 @@ method_to_str_idx(const char * method)
}
static nghttp2_nv*
nghttp2_nv_packet(struct tfe_h2_header *header, nghttp2_nv *hdrs)
tfe_h2_header_convert_nv(struct tfe_h2_header *header, nghttp2_nv *hdrs)
{
int nvlen = 0;
struct tfe_h2_field *h2_field = NULL, *peer_h2_field = NULL;
struct tfe_h2_field *h2_field = NULL, *peer_h2_field = NULL;
TAILQ_FOREACH_SAFE(h2_field, &header->h2_field_list, next, peer_h2_field){
TAILQ_FOREACH_SAFE(h2_field, &header->h2_field_list, next, peer_h2_field){
hdrs[nvlen].name = h2_field->nv.name;
hdrs[nvlen].namelen = h2_field->nv.namelen;
hdrs[nvlen].value = h2_field->nv.value;
@@ -238,7 +264,7 @@ delete_nv_packet_data(struct tfe_h2_header *header)
free(h2_filed->field);
h2_filed->field = NULL;
free(h2_filed);
h2_filed = NULL;
}
@@ -267,15 +293,15 @@ void half_set_callback(struct tfe_h2_half_private * half_private,
}
const char * h2_half_ops_field_read(const struct tfe_http_half * half, const struct http_field_name * field)
{
{
const struct tfe_h2_half_private *half_private = nghttp2_to_half_private(half);
if (unlikely(half_private == NULL))
return NULL;
struct tfe_h2_field *h2_field=NULL, *peer_h2_field=NULL;
const struct tfe_h2_header *h2_header =&(half_private->header);
TAILQ_FOREACH(h2_field, &h2_header->h2_field_list, next)
{
if (http_field_name_compare(h2_field->field, field) != 0) continue;
@@ -297,7 +323,7 @@ int h2_half_ops_field_write(struct tfe_http_half * half, const struct http_field
if (http_field_name_compare(h2_field->field, field) != 0) continue;
peer_h2_field = h2_field;
break;
}
}
if (peer_h2_field != NULL && value != NULL)
{
@@ -334,7 +360,7 @@ h2_half_ops_allow_write(const struct tfe_http_half * half)
const char * h2_half_ops_field_iterate(const struct tfe_http_half * half, void ** iter, struct http_field_name * field)
{
struct tfe_h2_field **h2_filed = (struct tfe_h2_field **)iter;
const struct tfe_h2_half_private *half_private = nghttp2_to_half_private(half);
const struct tfe_h2_half_private *half_private = nghttp2_to_half_private(half);
const struct tfe_h2_header *header = &half_private->header;
if (*h2_filed == NULL)
@@ -359,25 +385,25 @@ h2_half_ops_append_body(struct tfe_http_half * half, char * buff, size_t size, i
{
int xret = -1;
struct tfe_h2_half_private * resp = nghttp2_to_half_private(half);
struct tfe_h2_payload *body = &resp->body;
struct tfe_h2_payload *body = &resp->h2_payload;
if (buff == NULL && size == 0){
if (body->gzip != HTTP2_CONTENT_ENCODING_NONE){
xret = deflate_write(&body->deflate, NULL, 0, resp->body.evbuf_body, body->gzip, 1);
xret = deflate_write(&body->deflate, NULL, 0, resp->h2_payload.evbuf_body, body->gzip, 1);
}
resp->message_state = H2_READ_STATE_COMPLETE;
goto finish;
}
if (resp->body.evbuf_body == NULL){
resp->body.evbuf_body = evbuffer_new();
if (resp->h2_payload.evbuf_body == NULL){
resp->h2_payload.evbuf_body = evbuffer_new();
}
if (body->gzip != HTTP2_CONTENT_ENCODING_NONE){
xret = deflate_write(&body->deflate, (const uint8_t *)buff, size,
resp->body.evbuf_body, body->gzip, 0);
resp->h2_payload.evbuf_body, body->gzip, 0);
}else{
xret = evbuffer_add(resp->body.evbuf_body, buff, size);
xret = evbuffer_add(resp->h2_payload.evbuf_body, buff, size);
}
finish:
@@ -389,7 +415,7 @@ void delete_stream_half_data(struct tfe_h2_half_private **data,
{
if (*data){
struct tfe_h2_payload *body = &((*data)->body);
struct tfe_h2_payload *body = &((*data)->h2_payload);
inflate_finished(&body->inflate);
deflate_finished(&body->deflate);
@@ -400,6 +426,7 @@ void delete_stream_half_data(struct tfe_h2_half_private **data,
if ((*data)->url_storage)
FREE(&((*data)->url_storage));
delete_nv_packet_data(&((*data)->header));
if((*data)->event_cb_user_deleter != NULL)
(*data)->event_cb_user_deleter((*data)->event_cb_user);
free(*data);
@@ -423,7 +450,7 @@ void h2_half_ops_free(struct tfe_http_half * half)
int h2_half_ops_body_begin(struct tfe_http_half * half, int by_stream)
{
struct tfe_h2_half_private * resp = nghttp2_to_half_private(half);
struct tfe_h2_payload *body = &resp->body;
struct tfe_h2_payload *body = &resp->h2_payload;
assert(body->evbuf_body == NULL);
@@ -455,14 +482,14 @@ int h2_half_ops_body_data(struct tfe_http_half * h2_response, const unsigned cha
{
int xret = -1;
struct tfe_h2_half_private * h2_resp_priv = nghttp2_to_half_private(h2_response);
struct tfe_h2_payload *body = &h2_resp_priv->body;
struct tfe_h2_payload *body = &h2_resp_priv->h2_payload;
if (body->gzip != HTTP2_CONTENT_ENCODING_NONE){
xret = deflate_write(&body->deflate, (const uint8_t *)data, sz_data,
h2_resp_priv->body.evbuf_body, body->gzip, 0);
h2_resp_priv->h2_payload.evbuf_body, body->gzip, 0);
}else{
xret = evbuffer_add(h2_resp_priv->body.evbuf_body, data, sz_data);
xret = evbuffer_add(h2_resp_priv->h2_payload.evbuf_body, data, sz_data);
}
return xret;
}
@@ -557,17 +584,16 @@ tfe_half_private_init(enum tfe_http_direction direction, int32_t stream_id,
struct tfe_h2_half_private *half_private = ALLOC(struct tfe_h2_half_private, 1);
assert(half_private);
memset(half_private, 0, sizeof(struct tfe_h2_half_private));
half_private->half_public.direction = direction;
half_private->half_public.major_version = 2;
half_private->half_public.ops = &h2_half_ops;
headers_init(&half_private->header);
headers_init(&half_private->promised);
half_private->body.evbuf_body = evbuffer_new();
half_private->body.gzip = HTTP2_CONTENT_ENCODING_NONE;
half_private->body.padlen = 0;
half_private->h2_payload.inflate = NULL;
half_private->h2_payload.deflate = NULL;
half_private->h2_payload.evbuf_body = evbuffer_new();
half_private->h2_payload.gzip = HTTP2_CONTENT_ENCODING_NONE;
half_private->h2_payload.padlen = 0;
half_private->stream_id = stream_id;
half_private->session = session;
@@ -597,7 +623,7 @@ struct tfe_http_half * h2_ops_response_create(struct tfe_http_session * session,
resp->method_or_status = resp_code;
if (stream->resp)
resp->body.gzip = stream->resp->body.gzip;
resp->h2_payload.gzip = stream->resp->h2_payload.gzip;
return &resp->half_public;
}
@@ -647,7 +673,7 @@ upstream_read_callback(nghttp2_session *session, int32_t stream_id,
static enum tfe_stream_action
nghttp2_server_frame_submit_response(struct tfe_h2_stream *h2_stream_info,
struct tfe_h2_session *h2_session)
struct tfe_h2_session *h2_session)
{
int rv = -1;
struct tfe_h2_header *h2_header = NULL;
@@ -662,19 +688,24 @@ nghttp2_server_frame_submit_response(struct tfe_h2_stream *h2_stream_info,
if (h2_header->nvlen <= 0)
return ACTION_FORWARD_DATA;
struct tfe_h2_payload *body = &pangu_resp->body;
struct tfe_h2_payload *body = &pangu_resp->h2_payload;
char str_sz_evbuf_body[TFE_STRING_MAX];
snprintf(str_sz_evbuf_body, sizeof(str_sz_evbuf_body) - 1, "%lu", evbuffer_get_length(body->evbuf_body));
const static struct http_field_name __cont_encoding_length_name = {TFE_HTTP_CONT_LENGTH, NULL};
tfe_http_field_write(&pangu_resp->half_public, &__cont_encoding_length_name, str_sz_evbuf_body);
const static struct http_field_name encoding_field = {TFE_HTTP_CONT_LENGTH, NULL};
tfe_http_field_write(&pangu_resp->half_public, &encoding_field, str_sz_evbuf_body);
nghttp2_data_provider data_prd;
data_prd.source.ptr = (void *)body;
data_prd.read_callback = upstream_read_callback;
nghttp2_nv hdrs[h2_header->nvlen];
rv = nghttp2_submit_response(h2_stream_info->as_server, h2_session->ngh2_stream_id, nghttp2_nv_packet(h2_header, hdrs),
/*Adapt Http uri Settings**/
tfe_http_field_write(&pangu_resp->half_public, &encoding_field, str_sz_evbuf_body);
rv = nghttp2_submit_response(h2_stream_info->as_server, h2_session->ngh2_stream_id, tfe_h2_header_convert_nv(h2_header, hdrs),
h2_header->nvlen, &data_prd);
if (rv != 0){
return ACTION_FORWARD_DATA;
@@ -698,7 +729,7 @@ server_frame_submit_data(struct tfe_h2_stream *connection,
stream_action = nghttp2_server_frame_submit_response(connection, h2_session);
}else{
int rv = -1;
struct tfe_h2_payload *body = &resp->body;
struct tfe_h2_payload *body = &resp->h2_payload;
nghttp2_data_provider upstream_data_provider;
upstream_data_provider.source.ptr = (void *)body;
@@ -931,7 +962,7 @@ nghttp2_submit_frame_goaway(struct tfe_h2_stream *connection, const nghttp2_fram
{
int xret = -1;
enum tfe_stream_action stream_action = ACTION_DROP_DATA;
char error[1024] = {0};
char *error = NULL; size_t eroro_len=0;
const nghttp2_goaway *goaway = &frame->goaway;
nghttp2_session *ngh2_session = tfe_h2_stream_get_nghttp2_session(connection, dir);
@@ -951,10 +982,12 @@ nghttp2_submit_frame_goaway(struct tfe_h2_stream *connection, const nghttp2_fram
dir, nghttp2_strerror(xret));
}
finish:
snprintf(error, goaway->opaque_data_len, "%s", goaway->opaque_data);
eroro_len = goaway->opaque_data_len;
error = ALLOC(char, eroro_len + 1);
snprintf(error, eroro_len, "%s", goaway->opaque_data);
TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit goaway, stream_id:%d, action:%d, errod_code:%d, data:%s", connection->tf_stream->str_stream_info,
dir, goaway->last_stream_id, connection->stream_action, goaway->error_code, goaway->opaque_data);
FREE(&error);
connection->goaway = 1;
connection->stream_action = stream_action;
return 0;
@@ -1003,10 +1036,10 @@ nghttp2_submit_end_header(struct tfe_h2_stream *h2_stream_info,
if (headers.nvlen <= 0 || ((headers.flag & NGHTTP2_FLAG_END_STREAM)!=1) ){
return 0;
}
nghttp2_nv hdrs[headers.nvlen];
stream_id = nghttp2_submit_headers(h2_stream_info->as_server, headers.flag,
h2_session->ngh2_stream_id, NULL, nghttp2_nv_packet(&headers, hdrs),
h2_session->ngh2_stream_id, NULL, tfe_h2_header_convert_nv(&headers, hdrs),
headers.nvlen, h2_session);
if (stream_id < 0){
printf("Fatal headers error: %s\n", nghttp2_strerror(stream_id));
@@ -1044,7 +1077,7 @@ nghttp2_submit_end_stream_payload(struct tfe_h2_stream *h2_stream_info,
resp->event_cb_user);
}
}
struct tfe_h2_payload *payload = &resp->body;
struct tfe_h2_payload *payload = &resp->h2_payload;
payload->flags |= NGHTTP2_FLAG_END_STREAM;
resp->body_state = H2_READ_STATE_COMPLETE;
resp->message_state = H2_READ_STATE_COMPLETE;
@@ -1083,7 +1116,7 @@ nghttp2_submit_frame_data(struct tfe_h2_stream *h2_stream_info,const nghttp2_fra
goto finish;
}
resp = h2_session->resp;
resp->body.padlen = frame->data.padlen;
resp->h2_payload.padlen = frame->data.padlen;
if (resp->body_state != H2_READ_STATE_COMPLETE){
nghttp2_submit_end_stream_payload(h2_stream_info, h2_session);
}
@@ -1097,6 +1130,7 @@ static int tfe_half_session_init(struct tfe_h2_session *h2_session, int32_t stre
{
struct tfe_http_session *tfe_session = &h2_session->tfe_session;
tfe_session->major_version = 2;
if (direction == TFE_HTTP_REQUEST){
struct tfe_h2_half_private *req = h2_session->req;
tfe_session->ops = &nghttp2_session_ops;
@@ -1129,7 +1163,7 @@ upstream_create_req(struct tfe_h2_stream *h2_stream_info, nghttp2_session *as_se
event->tf_stream = h2_stream_info->tf_stream;
event->tfe_session = &h2_session->tfe_session;
half_set_callback(h2_session->req, event, NULL);
half_set_callback(h2_session->req, event, free);
/* Call business plugin */
half_private = h2_session->req;
@@ -1170,10 +1204,10 @@ nghttp2_server_frame_submit_push_promise(struct tfe_h2_stream *h2_stream_info,
/* Create s' half req*/
peer_h2_stream = (struct tfe_h2_session *)ALLOC(struct tfe_h2_session, 1);
assert(peer_h2_stream);
nghttp2_nv hdrs[headers->nvlen];
stream_id = nghttp2_submit_push_promise(h2_stream_info->as_server, headers->flag,
h2_session->ngh2_stream_id, nghttp2_nv_packet(headers, hdrs),
h2_session->ngh2_stream_id, tfe_h2_header_convert_nv(headers, hdrs),
headers->nvlen, peer_h2_stream);
if (stream_id < 0){
free(peer_h2_stream);
@@ -1256,7 +1290,7 @@ suspend_start(struct tfe_h2_session *h2_session,
static void
fill_resp_spec_from_handle(struct tfe_h2_half_private *half_private)
{
struct tfe_h2_field *h2_field = NULL, *peer_h2_field = NULL;
struct tfe_h2_field *h2_field = NULL, *peer_h2_field = NULL;
struct tfe_h2_header *header = &half_private->header;
struct tfe_http_resp_spec *resp_spec = &(half_private->half_public.resp_spec);
@@ -1343,10 +1377,10 @@ nghttp2_server_frame_submit_header(struct tfe_h2_stream *h2_stream_info,
headers = &resp->header;
if (headers->nvlen <= 0){
return ACTION_FORWARD_DATA;
}
}
nghttp2_nv hdrs[headers->nvlen];
xret = nghttp2_submit_headers(h2_stream_info->as_server, headers->flag,
h2_session->ngh2_stream_id, NULL, nghttp2_nv_packet(headers, hdrs),
h2_session->ngh2_stream_id, NULL, tfe_h2_header_convert_nv(headers, hdrs),
headers->nvlen, h2_session);
if (xret < 0){
printf("Fatal headers error: %s\n", nghttp2_strerror(xret));
@@ -1410,7 +1444,7 @@ static void
fill_req_spec_from_handle(struct tfe_h2_half_private *half_private)
{
int urllen = 0;
struct tfe_h2_field *h2_field = NULL, *peer_h2_field = NULL;
struct tfe_h2_field *h2_field = NULL, *peer_h2_field = NULL;
struct tfe_h2_header *header = &half_private->header;
struct tfe_http_req_spec *req_spec = &(half_private->half_public.req_spec);
@@ -1430,7 +1464,7 @@ fill_req_spec_from_handle(struct tfe_h2_half_private *half_private)
continue;
}
}
char *urltmp = NULL;
char *urltmp = half_private->url_storage;
urltmp = (char *)malloc(urllen + 1);
if(urltmp){
sprintf(urltmp, "%s%s", (char *)req_spec->host, (char *)req_spec->uri);
@@ -1461,10 +1495,10 @@ static enum tfe_stream_action
nghttp2_submit_built_response(struct tfe_h2_stream *h2_stream_info,
struct tfe_h2_session *h2_session)
{
int xret = -1;
int xret = -1;
char value[128] = {0};
enum tfe_stream_action stream_action = ACTION_FORWARD_DATA;
struct tfe_h2_half_private *resp = h2_session->plugin_built_resp;
struct tfe_h2_half_private *resp = h2_session->plugin_built_resp;
struct http_field_name field;
field.field_id = TFE_HTTP_UNKNOWN_FIELD;
@@ -1509,7 +1543,7 @@ downstream_create_resp(struct tfe_h2_session *h2_session, nghttp2_session *as_cl
event->tf_stream = tf_stream;
event->tfe_session = &h2_session->tfe_session;
half_set_callback(h2_session->resp, event, NULL);
half_set_callback(h2_session->resp, event, free);
h2_session->resp->frame_ctx = h2_session->frame_ctx;
@@ -1545,17 +1579,18 @@ nghttp2_client_frame_submit_header(struct tfe_h2_stream *h2_stream_info,
downstream_create_resp(h2_session, h2_stream_info->as_client, h2_stream_info->as_server,
h2_stream_info->tf_stream, h2_stream_info->thread_id);
nghttp2_session_set_next_stream_id(h2_stream_info->as_client, h2_session->ngh2_stream_id);
nghttp2_nv hdrs[headers->nvlen];
method = nghttp2_get_method(h2_session->req);
if (method == (enum tfe_http_std_method)NGHTTP2_METHOD_POST ||
method == (enum tfe_http_std_method)NGHTTP2_METHOD_PUT){
stream_id = nghttp2_submit_headers(h2_stream_info->as_client, headers->flag,
-1, NULL, nghttp2_nv_packet(headers, hdrs),
-1, NULL, tfe_h2_header_modify_field(headers, hdrs, ":path", req->url_storage),
headers->nvlen, h2_session);
}else{
stream_id = nghttp2_submit_request(h2_stream_info->as_client, NULL,
nghttp2_nv_packet(headers, hdrs),
tfe_h2_header_modify_field(headers, hdrs, ":path", req->url_storage),
headers->nvlen, NULL, h2_session);
}
if (stream_id < 0){
@@ -1565,7 +1600,7 @@ nghttp2_client_frame_submit_header(struct tfe_h2_stream *h2_stream_info,
goto finish;
}
stream_action = ACTION_DROP_DATA;
finish:
finish:
delete_nv_packet_data(headers);
return stream_action;
}
@@ -1661,7 +1696,7 @@ nghttp2_fill_up_header(nghttp2_session *ngh2_session, const nghttp2_frame *frame
return 0;
}
struct tfe_h2_half_private *half = (dir == CONN_DIR_UPSTREAM) ? h2_session->resp : h2_session->req;
struct http_field_name field;
field.field_id = (enum tfe_http_std_field)str_to_val((const char *)name, header_vals);
if (field.field_id == TFE_HTTP_UNKNOWN_FIELD)
@@ -1670,8 +1705,8 @@ nghttp2_fill_up_header(nghttp2_session *ngh2_session, const nghttp2_frame *frame
}
if (field.field_id == TFE_HTTP_CONT_ENCODING)
{
half->body.gzip = method_to_str_idx((const char *)value);
}
half->h2_payload.gzip = method_to_str_idx((const char *)value);
}
h2_header = &half->header;
tfe_h2_header_add_field(h2_header, &field, (const char *)value, 1);
h2_header->flag = frame->hd.flags;
@@ -1695,7 +1730,7 @@ nghttp2_fill_up_promise(nghttp2_session *ngh2_session, const nghttp2_frame *fram
frame->hd.stream_id);
return 0;
}
resp = h2_session->resp;
resp = h2_session->resp;
struct http_field_name field;
field.field_id = (enum tfe_http_std_field)str_to_val((const char *)name, header_vals);
if (field.field_id == TFE_HTTP_UNKNOWN_FIELD)
@@ -1704,8 +1739,8 @@ nghttp2_fill_up_promise(nghttp2_session *ngh2_session, const nghttp2_frame *fram
}
if (field.field_id == TFE_HTTP_CONT_ENCODING)
{
resp->body.gzip = method_to_str_idx((const char *)value);
}
resp->h2_payload.gzip = method_to_str_idx((const char *)value);
}
headers = &resp->promised;
tfe_h2_header_add_field(headers, &field, (const char *)value, 1);
headers->flag = frame->hd.flags;
@@ -1758,9 +1793,14 @@ nghttp2_on_stream_close(nghttp2_session *session, const nghttp2_frame *frame, co
h2_stream_info->stream_action != ACTION_DEFER_DATA)
nghttp2_submit_end_header(h2_stream_info, h2_session);
goto end;
}
}
finish:
TAILQ_REMOVE(&h2_stream_info->h2_session_list, h2_session, next);
if (h2_session->frame_ctx){
http_frame_raise_session_end(h2_session->frame_ctx, h2_session->tf_stream, &h2_session->tfe_session,
h2_stream_info->thread_id);
h2_session->frame_ctx = NULL;
}
delete_http2_stream_data(h2_session, h2_stream_info->tf_stream, 1);
free(h2_session);
h2_session = NULL;
@@ -1829,14 +1869,17 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
goto finish;
}
resp = h2_session->resp;
evbuffer_add(resp->body.evbuf_body, input, input_len);
evbuffer_add(resp->h2_payload.evbuf_body, input, input_len);
if (resp->body.gzip != HTTP2_CONTENT_ENCODING_NONE){
if (resp->h2_payload.gzip != HTTP2_CONTENT_ENCODING_NONE){
ret = inflate_read(input, input_len, &uncompr, &uncompr_len,
&resp->body.inflate, resp->body.gzip);
&resp->h2_payload.inflate, resp->h2_payload.gzip);
if (((ret == Z_STREAM_END) || (ret == Z_OK)) && uncompr > 0){
input = (const uint8_t*)uncompr;
input_len = uncompr_len;
}else
{
if (uncompr_len) FREE(&uncompr);
}
}
data = input;
@@ -1848,9 +1891,9 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
resp->event_cb_user);
}
if (flags == NGHTTP2_FLAG_END_STREAM){
resp->body.flags = 0;
resp->h2_payload.flags = 0;
}else{
resp->body.flags = flags;
resp->h2_payload.flags = flags;
}
resp->body_state = H2_READ_STATE_READING;
}
@@ -1860,11 +1903,12 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
resp->event_cb_user);
}
if (flags == NGHTTP2_FLAG_END_STREAM){
resp->body.flags = 0;
resp->h2_payload.flags = 0;
}else{
resp->body.flags = flags;
resp->h2_payload.flags = flags;
}
}
if (uncompr_len) FREE(&uncompr);
stream_action = server_frame_submit_data(h2_stream_info, h2_session, CONN_DIR_UPSTREAM);
if (stream_action == ACTION_DROP_DATA){
@@ -1942,7 +1986,7 @@ create_upstream_data(nghttp2_session *session, int32_t stream_id,
event->tf_stream = h2_stream_info->tf_stream;
event->tfe_session = &h2_session->tfe_session;
half_set_callback(h2_session->resp, event, NULL);
half_set_callback(h2_session->resp, event, free);
h2_session->resp->frame_ctx = h2_session->frame_ctx;
@@ -1966,7 +2010,7 @@ static ssize_t nghttp2_client_select_padding_callback(nghttp2_session *session,
if (!resp)
return frame->hd.length;
return (ssize_t)MIN(max_payloadlen, frame->hd.length + (resp->body.padlen));
return (ssize_t)MIN(max_payloadlen, frame->hd.length + (resp->h2_payload.padlen));
}
static int
@@ -2101,7 +2145,7 @@ create_serv_stream_data(nghttp2_session *session, int32_t stream_id,
event->tf_stream = h2_stream_info->tf_stream;
event->tfe_session = &h2_session->tfe_session;
half_set_callback(h2_session->req, event, NULL);
half_set_callback(h2_session->req, event, free);
/* Call business plugin */
half_private = h2_session->req;
@@ -2142,19 +2186,25 @@ nghttp2_server_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
goto finish;
}
req = h2_session->req;
req->body.flags = flags;
evbuffer_add(req->body.evbuf_body, input, input_len);
req->h2_payload.flags = flags;
evbuffer_add(req->h2_payload.evbuf_body, input, input_len);
if (req->body.gzip != HTTP2_CONTENT_ENCODING_NONE){
if (req->h2_payload.gzip != HTTP2_CONTENT_ENCODING_NONE){
ret = inflate_read(input, input_len, &uncompr, &uncompr_len,
&req->body.inflate, req->body.gzip);
&req->h2_payload.inflate, req->h2_payload.gzip);
if (((ret == Z_STREAM_END) || (ret == Z_OK)) && uncompr > 0){
input = (const uint8_t*)uncompr;
input_len = uncompr_len;
}
else
{
if (uncompr_len) FREE(&uncompr);
}
}
data = input;
len = input_len;
/*todo post data scan**/
if (uncompr_len) FREE(&uncompr);
stream_action = server_frame_submit_data(h2_stream_info, h2_session, CONN_DIR_DOWNSTREAM);
if (stream_action == ACTION_DROP_DATA){