diff --git a/plugin/protocol/http/src/http_entry.cpp b/plugin/protocol/http/src/http_entry.cpp index 4a1bf31..ccdcee4 100644 --- a/plugin/protocol/http/src/http_entry.cpp +++ b/plugin/protocol/http/src/http_entry.cpp @@ -198,6 +198,12 @@ int __on_request_handle_user_req_or_resp(const tfe_stream * stream, struct http_ /* Cannot setup user request and user response simultaneously */ assert(!(hs_private->hf_private_req_user != NULL && hs_private->hf_private_resp_user != NULL)); + /* Only construct HTTP request or early answer response when incoming request is complete */ + if (hf_private_req_in->message_status != STATUS_COMPLETE) + { + return 0; + } + /* User's construct request */ if (hs_private->hf_private_req_user != NULL) { @@ -215,17 +221,23 @@ int __on_request_handle_user_req_or_resp(const tfe_stream * stream, struct http_ hs_private->hf_private_req_user = NULL; } - assert(hf_private_req_in->stream_action == ACTION_DEFER_DATA - || hf_private_req_in->stream_action == ACTION_DROP_DATA); - - hf_private_req_in->stream_action = ACTION_DROP_DATA; + if (hf_private_req_in->stream_action == ACTION_DROP_DATA || + hf_private_req_in->stream_action == ACTION_DEFER_DATA) + { + hf_private_req_in->stream_action = ACTION_DROP_DATA; + } } - /* User's construct response, send before real response arrived. */ - else if (hs_private->hf_private_resp_user != NULL) + /* User's construct response, send before real response arrive. + * Only early answer while the incoming request is send. + * Otherwise, we will construct user's response when real response arrived. */ + + if (hs_private->hf_private_resp_user != NULL /* User response setup */ + && hf_private_req_in->stream_action == ACTION_DROP_DATA /* Incoming request does not sent */) { struct http_half_private * hf_private_resp_user = hs_private->hf_private_resp_user; ret = __write_http_half_to_line(stream, CONN_DIR_DOWNSTREAM, hf_private_resp_user); + if (unlikely(ret < 0)) { TFE_STREAM_LOG_ERROR(stream, "Failed to write HTTP request setup by user".); @@ -243,10 +255,6 @@ int __on_request_handle_user_req_or_resp(const tfe_stream * stream, struct http_ TAILQ_REMOVE(&hc_private->hs_private_list, hs_private, next); TAILQ_INSERT_TAIL(&hc_private->hs_private_orphan_list, hs_private, next); } - - assert(hf_private_req_in->stream_action == ACTION_DEFER_DATA - || hf_private_req_in->stream_action == ACTION_DROP_DATA); - hf_private_req_in->stream_action = ACTION_DROP_DATA; } return 0; diff --git a/plugin/protocol/http/src/http_half.cpp b/plugin/protocol/http/src/http_half.cpp index beed689..e2499af 100644 --- a/plugin/protocol/http/src/http_half.cpp +++ b/plugin/protocol/http/src/http_half.cpp @@ -871,7 +871,6 @@ void hs_ops_response_set(struct tfe_http_session * session, struct tfe_http_half hf_in_req_private->user_stream_action = ACTION_DROP_DATA; hf_in_req_private->is_user_stream_action_set = true; } - else assert(0); } /* Call at response's callback, replace incoming response */ @@ -882,7 +881,6 @@ void hs_ops_response_set(struct tfe_http_session * session, struct tfe_http_half hf_in_resp_private->user_stream_action = ACTION_DROP_DATA; hf_in_resp_private->is_user_stream_action_set = true; } - else assert(0); } assert(hs_private->hf_private_resp_user == NULL);