diff --git a/plugin/protocol/http2/include/internal/http2_stream.h b/plugin/protocol/http2/include/internal/http2_stream.h index 2de2ce6..6f246dc 100644 --- a/plugin/protocol/http2/include/internal/http2_stream.h +++ b/plugin/protocol/http2/include/internal/http2_stream.h @@ -109,6 +109,7 @@ struct tfe_h2_stream TAILQ_HEAD(list_head, tfe_h2_session) h2_session_list; int goaway; + int kill_signal; enum tfe_stream_action stream_action; diff --git a/plugin/protocol/http2/src/http2_stream.cpp b/plugin/protocol/http2/src/http2_stream.cpp index 2f70b61..1c5d339 100644 --- a/plugin/protocol/http2/src/http2_stream.cpp +++ b/plugin/protocol/http2/src/http2_stream.cpp @@ -25,6 +25,7 @@ #include #include +#include /* --------------------------------------------------------------------------------------------------------------------------------- @@ -679,7 +680,9 @@ struct tfe_http_half * h2_ops_response_create(struct tfe_http_session * session, void h2_ops_kill(struct tfe_http_session * session) { - + struct tfe_h2_session *h2_session = nghttp2_to_stream_data(session); + struct tfe_h2_stream *h2_stream = h2_session->father_stream; + h2_stream->kill_signal = 1; } struct tfe_http_session_ops nghttp2_session_ops = @@ -726,8 +729,7 @@ upstream_read_callback(nghttp2_session *session, int32_t stream_id, static enum tfe_stream_action nghttp2_frame_submit_built_resp(struct tfe_h2_stream *h2_stream_info, - struct tfe_h2_session *h2_session, - nghttp2_data_provider *data_prd) + struct tfe_h2_session *h2_session) { int rv = -1; struct tfe_h2_header *h2_header = NULL; @@ -740,9 +742,8 @@ nghttp2_frame_submit_built_resp(struct tfe_h2_stream *h2_stream_info, } h2_header = &pangu_resp->header; if (h2_header->nvlen <= 0) - { return ACTION_FORWARD_DATA; - } + struct tfe_h2_payload *body = &pangu_resp->h2_payload; body->flags |= NGHTTP2_FLAG_END_STREAM; char str_sz_evbuf_body[TFE_STRING_MAX]; @@ -758,14 +759,15 @@ nghttp2_frame_submit_built_resp(struct tfe_h2_stream *h2_stream_info, tfe_http_field_write(&pangu_resp->half_public, &encoding_field, content_encoding); } - data_prd->source.ptr = (void *)body; - data_prd->read_callback = upstream_read_callback; + nghttp2_data_provider data_prd; + data_prd.source.ptr = (void *)body; + data_prd.read_callback = upstream_read_callback; nghttp2_nv hdrs[h2_header->nvlen]; /*Adapt Http uri Settings**/ 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); + h2_header->nvlen, &data_prd); if (rv != 0){ return ACTION_FORWARD_DATA; } @@ -776,8 +778,7 @@ nghttp2_frame_submit_built_resp(struct tfe_h2_stream *h2_stream_info, static enum tfe_stream_action nghttp2_frame_submit_built_req(struct tfe_h2_stream *h2_stream_info, - struct tfe_h2_session *h2_session, - nghttp2_data_provider *data_prd) + struct tfe_h2_session *h2_session) { int32_t stream_id = -1; struct tfe_h2_header *h2_header = NULL; @@ -798,14 +799,15 @@ nghttp2_frame_submit_built_req(struct tfe_h2_stream *h2_stream_info, const static struct http_field_name encoding_field = {TFE_HTTP_CONT_LENGTH, NULL}; tfe_http_field_write(&plugin_built_req->half_public, &encoding_field, str_sz_evbuf_body); - data_prd->source.ptr = (void *)body; - data_prd->read_callback = upstream_read_callback; + nghttp2_data_provider data_prd; + data_prd.source.ptr = (void *)body; + data_prd.read_callback = upstream_read_callback; nghttp2_nv hdrs[h2_header->nvlen]; /*Adapt Http uri Settings**/ stream_id = nghttp2_submit_request(h2_stream_info->as_client, NULL, tfe_h2_header_modify_field(h2_header, hdrs, ":path", plugin_built_req->url_storage), - h2_header->nvlen, data_prd, h2_session); + h2_header->nvlen, &data_prd, h2_session); if (stream_id < 0){ TFE_LOG_ERROR(logger()->handle, "Could not submit request: %s", @@ -819,9 +821,8 @@ nghttp2_frame_submit_built_req(struct tfe_h2_stream *h2_stream_info, static enum tfe_stream_action nghttp2_submit_data_by_h2_half(struct tfe_h2_stream *connection, - struct tfe_h2_session *h2_session, - nghttp2_data_provider *data_provider, - enum tfe_conn_dir dir) + struct tfe_h2_session *h2_session, + enum tfe_conn_dir dir) { enum tfe_stream_action stream_action = ACTION_DROP_DATA; @@ -830,21 +831,23 @@ nghttp2_submit_data_by_h2_half(struct tfe_h2_stream *connection, if (h2_session->plugin_built_resp) { - stream_action = nghttp2_frame_submit_built_resp(connection, h2_session, data_provider); + stream_action = nghttp2_frame_submit_built_resp(connection, h2_session); } else if (h2_session->plugin_built_req) { - stream_action = nghttp2_frame_submit_built_req(connection, h2_session, data_provider); + stream_action = nghttp2_frame_submit_built_req(connection, h2_session); } else { int rv = -1; struct tfe_h2_payload *body = &h2_half->h2_payload; - data_provider->source.ptr = (void *)body; - data_provider->read_callback = upstream_read_callback; + + nghttp2_data_provider upstream_data_provider; + upstream_data_provider.source.ptr = (void *)body; + upstream_data_provider.read_callback = upstream_read_callback; rv = nghttp2_submit_data(ngh2_session, body->flags, - h2_session->ngh2_stream_id, data_provider); + h2_session->ngh2_stream_id, &upstream_data_provider); if (rv != 0){ stream_action = ACTION_FORWARD_DATA; //printf("Fatal server submit data error: %s\n", nghttp2_strerror(rv)); @@ -1196,10 +1199,7 @@ nghttp2_submit_complete_data(struct tfe_h2_stream *h2_stream_info, h2_half->body_state = H2_READ_STATE_COMPLETE; h2_half->message_state = H2_READ_STATE_COMPLETE; - /*registeredSend data**/ - nghttp2_data_provider *data_provider; - data_provider = ALLOC(nghttp2_data_provider, 1); - stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, data_provider, CONN_DIR_UPSTREAM); + stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, CONN_DIR_UPSTREAM); if (stream_action == ACTION_DROP_DATA){ xret = nghttp2_session_send(ngh2_session); if (xret != 0) { @@ -1209,8 +1209,6 @@ nghttp2_submit_complete_data(struct tfe_h2_stream *h2_stream_info, } if (stream_action == ACTION_USER_DATA) stream_action = ACTION_DROP_DATA; - free(data_provider); - data_provider = NULL; h2_stream_info->stream_action = stream_action; return 1; } @@ -1221,13 +1219,22 @@ nghttp2_submit_frame_data(struct tfe_h2_stream *h2_stream_info,const nghttp2_fra { struct tfe_h2_session *h2_session = NULL; - h2_session = TAILQ_LIST_FIND(h2_stream_info, frame->hd.stream_id); - if (NULL == h2_session) + nghttp2_session *ngh2_session = tfe_h2_stream_get_nghttp2_peer_session(h2_stream_info, dir); + h2_session = (struct tfe_h2_session *)nghttp2_session_get_stream_user_data(ngh2_session, + frame->hd.stream_id); + if (!h2_session) { return 0; } + struct tfe_h2_half_private *h2_half = tfe_h2_stream_get_half(h2_session, dir); + /*HEAD STREMA_END + DATA(9)**/ + if (h2_half == NULL) + { + return 0; + } + if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { if (dir == CONN_DIR_UPSTREAM) @@ -1291,6 +1298,7 @@ upstream_create_req(struct tfe_h2_stream *h2_stream_info, nghttp2_session *as_se http_frame_raise_session_begin(half_private->frame_ctx, h2_stream_info->tf_stream, &h2_session->tfe_session, h2_stream_info->thread_id); h2_session->frame_ctx = half_private->frame_ctx; + h2_session->father_stream = h2_stream_info; TAILQ_INSERT_TAIL(&h2_stream_info->h2_session_list, h2_session, next); nghttp2_session_set_stream_user_data(as_server, stream_id, h2_session); @@ -1492,9 +1500,7 @@ nghttp2_submit_built_response(struct tfe_h2_stream *h2_stream_info, snprintf(value, sizeof(value), "%d", resp->method_or_status); tfe_h2_header_add_field(&resp->header, &field, (const char *)value, 0); - nghttp2_data_provider *data_prd; - data_prd = ALLOC(nghttp2_data_provider, 1); - stream_action = nghttp2_frame_submit_built_resp(h2_stream_info, h2_session, data_prd); + stream_action = nghttp2_frame_submit_built_resp(h2_stream_info, h2_session); if (stream_action == ACTION_DROP_DATA) { xret = nghttp2_session_send(h2_stream_info->as_server); @@ -1508,8 +1514,6 @@ nghttp2_submit_built_response(struct tfe_h2_stream *h2_stream_info, { stream_action = (enum tfe_stream_action)ACTION_USER_DATA; } - free(data_prd); - data_prd = NULL; return stream_action; } @@ -2050,10 +2054,7 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags, } if (uncompr_len) FREE(&uncompr); - - nghttp2_data_provider *data_provider = NULL; - data_provider = ALLOC(nghttp2_data_provider, 1); - stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, data_provider, CONN_DIR_UPSTREAM); + stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, CONN_DIR_UPSTREAM); if (stream_action == ACTION_DROP_DATA){ xret = nghttp2_session_send(h2_stream_info->as_server); if (xret != 0) { @@ -2063,8 +2064,6 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags, } if (stream_action == ACTION_USER_DATA) stream_action = ACTION_DROP_DATA; - free(data_provider); - data_provider = NULL; h2_stream_info->stream_action = stream_action; return 0; } @@ -2297,6 +2296,8 @@ create_serv_stream_data(nghttp2_session *session, int32_t stream_id, h2_session->frame_ctx = half_private->frame_ctx; http_frame_raise_session_begin(half_private->frame_ctx, h2_stream_info->tf_stream, &h2_session->tfe_session, h2_stream_info->thread_id); + h2_session->father_stream = h2_stream_info; + TAILQ_INSERT_TAIL(&h2_stream_info->h2_session_list, h2_session, next); nghttp2_session_set_stream_user_data(session, stream_id, h2_session); finish: @@ -2368,9 +2369,7 @@ nghttp2_server_on_data_chunk_recv(nghttp2_session *session, uint8_t flags, } if (uncompr_len) FREE(&uncompr); - nghttp2_data_provider *data_provider; - data_provider = ALLOC(nghttp2_data_provider, 1); - stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, data_provider, CONN_DIR_DOWNSTREAM); + stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, CONN_DIR_DOWNSTREAM); if (stream_action == ACTION_DROP_DATA){ xret = nghttp2_session_send(h2_stream_info->as_client); if (xret != 0) { @@ -2380,8 +2379,6 @@ nghttp2_server_on_data_chunk_recv(nghttp2_session *session, uint8_t flags, } if (stream_action == ACTION_USER_DATA) stream_action = ACTION_DROP_DATA; - free(data_provider); - data_provider = NULL; h2_stream_info->stream_action = stream_action; finish: return 0; @@ -2502,6 +2499,11 @@ detect_up_stream_protocol(struct tfe_h2_stream *h2_stream_info, const struct tfe nghttp2_disect_goaway(h2_stream_info); h2_stream_info->goaway = 0; } + if (h2_stream_info->kill_signal) + { + tfe_stream_kill(tfe_stream); + } + if (stream_action == ACTION_DROP_DATA){ tfe_stream_action_set_opt(tfe_stream, ACTION_OPT_DROP_BYTES, &len, sizeof(len)); return ACTION_DROP_DATA; diff --git a/plugin/protocol/http2/test/test_http2_stream.cpp b/plugin/protocol/http2/test/test_http2_stream.cpp index 2e29cc8..00d0fdd 100644 --- a/plugin/protocol/http2/test/test_http2_stream.cpp +++ b/plugin/protocol/http2/test/test_http2_stream.cpp @@ -30,6 +30,9 @@ int tfe_stream_write(const struct tfe_stream * stream, enum tfe_conn_dir dir, co return 0; } +void tfe_stream_kill(const struct tfe_stream * stream) +{} + int tfe_stream_action_set_opt(const struct tfe_stream * stream, enum tfe_stream_action_opt type, void * value, size_t size) {