diff --git a/plugin/business/pangu-http/src/pangu_http.cpp b/plugin/business/pangu-http/src/pangu_http.cpp index 80721b2..36a984a 100644 --- a/plugin/business/pangu-http/src/pangu_http.cpp +++ b/plugin/business/pangu-http/src/pangu_http.cpp @@ -1512,6 +1512,13 @@ static void http_redirect(const struct tfe_http_session * session, enum tfe_http ctx->enforce_rules[0].config_id); goto error_out; } + + if ((events & EV_HTTP_RESP_BODY_BEGIN) || (events & EV_HTTP_RESP_BODY_CONT) + || (events & EV_HTTP_RESP_BODY_END) || (events & EV_HTTP_RESP_END)) + { + return; + } + to_write = tfe_http_session_allow_write(session); if (to_write == NULL) { diff --git a/plugin/protocol/http2/src/http2_stream.cpp b/plugin/protocol/http2/src/http2_stream.cpp index 1c5d339..797f2f7 100644 --- a/plugin/protocol/http2/src/http2_stream.cpp +++ b/plugin/protocol/http2/src/http2_stream.cpp @@ -699,6 +699,24 @@ struct tfe_http_session_ops nghttp2_session_ops = .ops_response_create = h2_ops_response_create }; +static ssize_t +no_data_read_callback(nghttp2_session *session, int32_t stream_id, + uint8_t *buf, size_t length, + uint32_t *data_flags, + nghttp2_data_source *source, + void *user_data) +{ + (void)session; + (void)stream_id; + (void)buf; + (void)length; + (void)source; + (void)user_data; + + *data_flags |= NGHTTP2_DATA_FLAG_EOF; + return 0; +} + static ssize_t upstream_read_callback(nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, @@ -819,6 +837,28 @@ nghttp2_frame_submit_built_req(struct tfe_h2_stream *h2_stream_info, return ACTION_DROP_DATA; } +static void +nghttp2_submit_end_data_by_h2_half(struct tfe_h2_stream *h2_stream_info, int32_t stream_id, enum tfe_conn_dir dir) +{ + int xret = -1; + nghttp2_session *ngh2_session = tfe_h2_stream_get_nghttp2_session(h2_stream_info, dir); + + nghttp2_data_provider data_provider; + data_provider.read_callback = no_data_read_callback; + + xret = nghttp2_submit_data(ngh2_session, NGHTTP2_FLAG_END_STREAM, + stream_id, &data_provider); + if (xret != 0){ + return; + } + xret = nghttp2_session_send(ngh2_session); + if (xret != 0) { + TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret)); + } + + return; +} + static enum tfe_stream_action nghttp2_submit_data_by_h2_half(struct tfe_h2_stream *connection, struct tfe_h2_session *h2_session, @@ -1220,21 +1260,20 @@ nghttp2_submit_frame_data(struct tfe_h2_stream *h2_stream_info,const nghttp2_fra struct tfe_h2_session *h2_session = NULL; 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); + h2_session = (struct tfe_h2_session *)nghttp2_session_get_stream_user_data(ngh2_session, frame->hd.stream_id); if (!h2_session) { + h2_stream_info->stream_action = ACTION_DROP_DATA; 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) { + nghttp2_submit_end_data_by_h2_half(h2_stream_info, frame->hd.stream_id, dir); + h2_stream_info->stream_action = ACTION_DROP_DATA; return 0; } - if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { if (dir == CONN_DIR_UPSTREAM) @@ -1263,6 +1302,7 @@ static int tfe_half_session_init(struct tfe_h2_session *h2_session, int32_t stre if (direction == TFE_HTTP_RESPONSE){ struct tfe_h2_half_private *resp = h2_session->resp; tfe_session->resp = &resp->half_public; + tfe_session->session_id = stream_id; } return 0; } @@ -1275,6 +1315,7 @@ upstream_create_req(struct tfe_h2_stream *h2_stream_info, nghttp2_session *as_se struct tfe_h2_half_private *half_private = NULL; h2_session->ngh2_stream_id = stream_id; + h2_session->session = as_server; h2_session->req = tfe_half_private_init(TFE_HTTP_REQUEST, 0, NULL); tfe_half_session_init(h2_session, stream_id, TFE_HTTP_REQUEST); @@ -1376,7 +1417,6 @@ nghttp2_submit_frame_push_promise(struct tfe_h2_stream *h2_stream_info,const ngh } h2_stream_info->stream_action = stream_action; finish: - #ifdef TFE_LOG_HTTP2 TFE_LOG_DEBUG(logger()->handle, "%s, %d, submit push promise, stream_id:%d, action:%d", h2_stream_info->tf_stream->str_stream_info, dir, frame->hd.stream_id, h2_stream_info->stream_action); @@ -1700,7 +1740,8 @@ nghttp2_client_frame_submit_header(struct tfe_h2_stream *h2_stream_info, /*Create C' half_private_resp**/ 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); + /*Adapt inconsistent client and server stream ids ***/ + nghttp2_session_set_next_stream_id(h2_stream_info->as_client, h2_session->ngh2_stream_id); if (h2_session->plugin_built_resp) { @@ -2001,10 +2042,8 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags, struct tfe_h2_stream *h2_stream_info = (struct tfe_h2_stream *)user_data; /*proc build resp*/ - struct tfe_h2_session *h2_session = TAILQ_LIST_FIND(h2_stream_info, stream_id); - if (NULL == h2_session) - { - h2_stream_info->stream_action = ACTION_DROP_DATA; + struct tfe_h2_session *h2_session = (struct tfe_h2_session *)nghttp2_session_get_stream_user_data(session, stream_id); + if (h2_session == NULL){ return 0; } resp = h2_session->resp; @@ -2104,16 +2143,22 @@ create_upstream_data(nghttp2_session *session, int32_t stream_id, { struct tfe_h2_session *h2_session = NULL; struct user_event_dispatch *event = NULL; + struct tfe_h2_half_private *half_private = NULL; h2_session = TAILQ_LIST_FIND(h2_stream_info, stream_id); if (h2_session == NULL){ - /** todo:When the data of the reply is pushed as promised, - there is no stream id at the reply end. to create it*/ - goto finish; + goto resp; } if (h2_session->resp){ + /** todo:When the data of the reply is pushed as promised, + there is no stream id at the reply end. to create it*/ goto finish; } +resp: + h2_session = (struct tfe_h2_session *)ALLOC(struct tfe_h2_session, 1); + assert(h2_session); + h2_session->ngh2_stream_id = stream_id; + h2_session->tf_stream = h2_stream_info->tf_stream; h2_session->resp = tfe_half_private_init(TFE_HTTP_RESPONSE, stream_id, h2_stream_info->as_server); tfe_half_session_init(h2_session, stream_id, TFE_HTTP_RESPONSE); @@ -2125,9 +2170,20 @@ create_upstream_data(nghttp2_session *session, int32_t stream_id, event->tfe_session = &h2_session->tfe_session; half_set_callback(h2_session->resp, event, free); + half_private = h2_session->resp; + if (h2_session->frame_ctx == NULL) + { + half_private->frame_ctx = http_frame_alloc(); + if (half_private->frame_ctx == NULL){ + TFE_STREAM_LOG_ERROR(h2_session, "Failed at raising session begin event. "); + goto finish; + } + 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->resp->frame_ctx = h2_session->frame_ctx; - nghttp2_session_set_stream_user_data(session, stream_id, h2_session); finish: @@ -2501,6 +2557,7 @@ detect_up_stream_protocol(struct tfe_h2_stream *h2_stream_info, const struct tfe } if (h2_stream_info->kill_signal) { + nghttp2_disect_goaway(h2_stream_info); tfe_stream_kill(tfe_stream); }