From d27208756565b67fa2f071b9dd88b9c8c523adf7 Mon Sep 17 00:00:00 2001 From: fengweihao Date: Mon, 3 Jun 2019 15:12:59 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9hjack=E8=AF=BB=E5=8F=96prof?= =?UTF-8?q?ile=E6=96=87=E4=BB=B6=E6=96=B9=E5=BC=8F=202.=E5=91=BD=E4=B8=ADq?= =?UTF-8?q?uery=E6=9B=BF=E6=8D=A2=E8=A7=84=E5=88=99=E5=90=8E=EF=BC=8Chttp2?= =?UTF-8?q?=E9=80=82=E9=85=8Dhttp=E4=BF=AE=E6=94=B9=203.=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?URI=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/business/pangu-http/src/pangu_http.cpp | 38 +++--- .../business/pangu-http/src/pangu_logger.cpp | 1 + .../pangu-http/src/test_pattern_replace.cpp | 39 +++++- plugin/protocol/http2/src/http2_stream.cpp | 114 ++++++++++++------ 4 files changed, 136 insertions(+), 56 deletions(-) diff --git a/plugin/business/pangu-http/src/pangu_http.cpp b/plugin/business/pangu-http/src/pangu_http.cpp index 3097386..6e80e19 100644 --- a/plugin/business/pangu-http/src/pangu_http.cpp +++ b/plugin/business/pangu-http/src/pangu_http.cpp @@ -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); @@ -1378,7 +1372,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); @@ -1564,22 +1557,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); diff --git a/plugin/business/pangu-http/src/pangu_logger.cpp b/plugin/business/pangu-http/src/pangu_logger.cpp index 4ba4f93..4468e32 100644 --- a/plugin/business/pangu-http/src/pangu_logger.cpp +++ b/plugin/business/pangu-http/src/pangu_logger.cpp @@ -231,6 +231,7 @@ 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); diff --git a/plugin/business/pangu-http/src/test_pattern_replace.cpp b/plugin/business/pangu-http/src/test_pattern_replace.cpp index 5017ee5..23638a9 100644 --- a/plugin/business/pangu-http/src/test_pattern_replace.cpp +++ b/plugin/business/pangu-http/src/test_pattern_replace.cpp @@ -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; } diff --git a/plugin/protocol/http2/src/http2_stream.cpp b/plugin/protocol/http2/src/http2_stream.cpp index 7ebc7db..ed7f080 100644 --- a/plugin/protocol/http2/src/http2_stream.cpp +++ b/plugin/protocol/http2/src/http2_stream.cpp @@ -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) @@ -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); @@ -456,7 +483,7 @@ 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; - + if (body->gzip != HTTP2_CONTENT_ENCODING_NONE){ xret = deflate_write(&body->deflate, (const uint8_t *)data, sz_data, @@ -647,7 +674,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; @@ -666,15 +693,20 @@ nghttp2_server_frame_submit_response(struct tfe_h2_stream *h2_stream_info, 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; @@ -1003,10 +1035,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)); @@ -1129,7 +1161,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 +1202,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 +1288,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 +1375,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 +1442,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 +1462,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 +1493,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 +1541,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 +1577,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 +1598,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 +1694,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) @@ -1671,7 +1704,7 @@ 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); - } + } h2_header = &half->header; tfe_h2_header_add_field(h2_header, &field, (const char *)value, 1); h2_header->flag = frame->hd.flags; @@ -1695,7 +1728,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) @@ -1705,7 +1738,7 @@ 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); - } + } headers = &resp->promised; tfe_h2_header_add_field(headers, &field, (const char *)value, 1); headers->flag = frame->hd.flags; @@ -1865,6 +1898,7 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags, resp->body.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 +1976,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; @@ -2101,7 +2135,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; @@ -2155,6 +2189,8 @@ nghttp2_server_on_data_chunk_recv(nghttp2_session *session, uint8_t flags, } 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){