diff --git a/plugin/protocol/http2/src/http2_stream.cpp b/plugin/protocol/http2/src/http2_stream.cpp index 4528f20..db603c7 100644 --- a/plugin/protocol/http2/src/http2_stream.cpp +++ b/plugin/protocol/http2/src/http2_stream.cpp @@ -825,7 +825,7 @@ nghttp2_submit_frame_settings(struct tfe_session_info_t *session_info,const nght goto finish; } rv = nghttp2_submit_settings(session, settings.hd.flags, - nghttp2_iv_packet(settings, iv), settings.niv); + nghttp2_iv_packet(settings, iv), settings.niv); if (rv != 0) { stream_action = ACTION_FORWARD_DATA; TFE_LOG_ERROR(logger()->handle, "dir(%d), Submit settings error: %s\n", @@ -1024,26 +1024,111 @@ finish: } static int -nghttp2_set_padlen(struct tfe_session_info_t *session_info,const nghttp2_frame *frame, - enum tfe_conn_dir dir) +nghttp2_end_submit_header2(struct tfe_session_info_t *session_info, + struct h2_stream_data_t *h2_stream) { - struct http2_half_private *resp = NULL; + int xret = -1; + int32_t stream_id = 0; + nghttp2_nv hdrs[128] = {0}; + struct http2_headers headers; + struct http2_half_private *resp = h2_stream->resp; + enum tfe_stream_action stream_action = ACTION_DROP_DATA; + + headers = resp->headers; + if (headers.nvlen <= 0){ + goto finish; + } + stream_id = nghttp2_submit_headers(session_info->as_server, headers.flag, + h2_stream->stream_id, NULL, nghttp2_nv_packet(&headers, hdrs), + headers.nvlen, h2_stream); + if (stream_id < 0){ + printf("Fatal headers error: %s\n", nghttp2_strerror(stream_id)); + stream_action = ACTION_FORWARD_DATA; + } + delete_nv_packet_data(&headers); + + if (stream_action == ACTION_DROP_DATA){ + xret = nghttp2_session_send(session_info->as_server); + if (xret != 0) { + stream_action = ACTION_FORWARD_DATA; + TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret)); + } + } +finish: + session_info->stream_action = stream_action; + return 0; +} + +static int +submit_end_data(struct tfe_session_info_t *session_info, + struct h2_stream_data_t *h2_stream) +{ + int xret = -1; + enum tfe_stream_action stream_action = ACTION_DROP_DATA; + + struct http2_half_private *resp = h2_stream->resp; + + if (resp->body_state == MANAGE_STAGE_INIT){ + nghttp2_end_submit_header2(session_info, h2_stream); + //return 1; + } + + if (resp->body_state != MANAGE_STAGE_INIT){ + if (resp->event_cb) { + resp->event_cb(resp, EV_HTTP_RESP_BODY_END, NULL, 0, + resp->event_cb_user); + } + if (resp->event_cb) { + resp->event_cb(resp, EV_HTTP_RESP_END, NULL, 0, + resp->event_cb_user); + } + } + struct data_t *body = &resp->body; + body->flags |= NGHTTP2_FLAG_END_STREAM; + resp->body_state = MANAGE_STAGE_COMPLETE; + resp->message_state = MANAGE_STAGE_COMPLETE; + + stream_action = server_frame_submit_data(session_info, h2_stream, CONN_DIR_UPSTREAM); + if (stream_action == ACTION_DROP_DATA){ + xret = nghttp2_session_send(session_info->as_server); + if (xret != 0) { + stream_action = ACTION_FORWARD_DATA; + TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret)); + } + } + TFE_LOG_INFO(logger()->handle, "%s, 1, End of stream submit, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, + h2_stream->stream_id, session_info->stream_action); + + if (stream_action == ACTION_USER_DATA) + stream_action = ACTION_DROP_DATA; + session_info->stream_action = stream_action; + return 1; +} + +static int +nghttp2_submit_frame_data(struct tfe_session_info_t *session_info,const nghttp2_frame *frame, + enum tfe_conn_dir dir) +{ + struct http2_half_private *resp = NULL; struct h2_stream_data_t *h2_stream = NULL; if (dir == CONN_DIR_DOWNSTREAM) goto finish; + if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM){ h2_stream = (struct h2_stream_data_t *)nghttp2_session_get_stream_user_data(session_info->as_client, - frame->hd.stream_id); + frame->hd.stream_id); if (!h2_stream){ TFE_LOG_ERROR(logger()->handle, "Upstream id %d, can't find stream information(addr = %p)", - frame->hd.stream_id, session_info); + frame->hd.stream_id, session_info); goto finish; } resp = h2_stream->resp; resp->body.padlen = frame->data.padlen; + if (resp->body_state != MANAGE_STAGE_COMPLETE){ + submit_end_data(session_info, h2_stream); + } } - finish: return 0; } @@ -1303,42 +1388,6 @@ nghttp2_headers_write_log(struct h2_stream_data_t *h2_stream, const char * str_s return 0; } -static int -nghttp2_end_submit_header2(struct tfe_session_info_t *session_info, - struct h2_stream_data_t *h2_stream) -{ - int xret = -1; - int32_t stream_id = 0; - nghttp2_nv hdrs[128] = {0}; - struct http2_headers headers; - struct http2_half_private *resp = h2_stream->resp; - enum tfe_stream_action stream_action = ACTION_DROP_DATA; - - headers = resp->headers; - if (headers.nvlen <= 0){ - goto finish; - } - stream_id = nghttp2_submit_headers(session_info->as_server, headers.flag, - h2_stream->stream_id, NULL, nghttp2_nv_packet(&headers, hdrs), - headers.nvlen, h2_stream); - if (stream_id < 0){ - printf("Fatal headers error: %s\n", nghttp2_strerror(stream_id)); - stream_action = ACTION_FORWARD_DATA; - } - delete_nv_packet_data(&headers); - - if (stream_action == ACTION_DROP_DATA){ - xret = nghttp2_session_send(session_info->as_server); - if (xret != 0) { - stream_action = ACTION_FORWARD_DATA; - TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret)); - } - } -finish: - session_info->stream_action = stream_action; - return 0; -} - static int nghttp2_server_submit_header(struct tfe_session_info_t *session_info, int32_t stream_id) { @@ -1649,7 +1698,7 @@ nghttp2_submit_frame_header(struct tfe_session_info_t *session_info,const nghttp } nghttp2_frame_callback nghttp2_frame_callback_array[] = { - [NGHTTP2_DATA] = nghttp2_set_padlen, + [NGHTTP2_DATA] = nghttp2_submit_frame_data, [NGHTTP2_HEADERS] = nghttp2_submit_frame_header, [NGHTTP2_PRIORITY] = nghttp2_submit_frame_priority, [NGHTTP2_RST_STREAM] = nghttp2_submit_frame_rst_stream, @@ -1766,58 +1815,11 @@ nghttp2_data_send(nghttp2_session *session, const nghttp2_frame *frame, const ui return (ssize_t)length; } -static int -submit_end_data(struct tfe_session_info_t *session_info, - struct h2_stream_data_t *h2_stream) -{ - int xret = -1; - enum tfe_stream_action stream_action = ACTION_DROP_DATA; - - struct http2_half_private *resp = h2_stream->resp; - - if (resp->body_state == MANAGE_STAGE_INIT){ - nghttp2_end_submit_header2(session_info, h2_stream); - //return 1; - } - - if (resp->body_state != MANAGE_STAGE_INIT){ - if (resp->event_cb) { - resp->event_cb(resp, EV_HTTP_RESP_BODY_END, NULL, 0, - resp->event_cb_user); - } - if (resp->event_cb) { - resp->event_cb(resp, EV_HTTP_RESP_END, NULL, 0, - resp->event_cb_user); - } - } - struct data_t *body = &resp->body; - body->flags |= NGHTTP2_FLAG_END_STREAM; - resp->body_state = MANAGE_STAGE_COMPLETE; - resp->message_state = MANAGE_STAGE_COMPLETE; - - stream_action = server_frame_submit_data(session_info, h2_stream, CONN_DIR_UPSTREAM); - if (stream_action == ACTION_DROP_DATA){ - xret = nghttp2_session_send(session_info->as_server); - if (xret != 0) { - stream_action = ACTION_FORWARD_DATA; - TFE_LOG_ERROR(logger()->handle, "Fatal upstream send error: %s\n",nghttp2_strerror(xret)); - } - } - TFE_LOG_INFO(logger()->handle, "%s, 1, End of stream submit, stream_id:%d, action:%d", session_info->tf_stream->str_stream_info, - h2_stream->stream_id, session_info->stream_action); - - if (stream_action == ACTION_USER_DATA) - stream_action = ACTION_DROP_DATA; - session_info->stream_action = stream_action; - return 1; -} - static int nghttp2_on_stream_close(nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, void *user_data, enum tfe_conn_dir dir) { - int xret = -1; struct h2_stream_data_t *h2_stream = NULL; struct http2_half_private *resp = NULL; @@ -1839,9 +1841,9 @@ nghttp2_on_stream_close(nghttp2_session *session, const nghttp2_frame *frame, co resp = h2_stream->resp; if (error_code == 0 && resp->body_state != MANAGE_STAGE_COMPLETE){ - xret = submit_end_data(session_info, h2_stream); - if (xret == 1) - goto end; + if (resp->body_state == MANAGE_STAGE_INIT) + nghttp2_end_submit_header2(session_info, h2_stream); + goto end; } finish: TAILQ_REMOVE(&session_info->list, h2_stream, next);