修复Bug0000452重定向+RespKeyword,业务层无处理

修复blcok+RespKeyword,kill连接后未发生那个日志,造成内存泄漏
修复0000477Firefox浏览器http2未同步s-c~-s~-c流id信息,造成页面无法访问
添加异常处理,当流信息未同步时,只有请求端数据时,未对stream进行初始化当data+flags为end_stream时,注册数据接口,使模拟发送端进行数据清除操作
This commit is contained in:
fengweihao
2019-06-22 17:44:52 +08:00
parent 74365f53d5
commit aa276e99cf
2 changed files with 79 additions and 15 deletions

View File

@@ -1512,6 +1512,13 @@ static void http_redirect(const struct tfe_http_session * session, enum tfe_http
ctx->enforce_rules[0].config_id); ctx->enforce_rules[0].config_id);
goto error_out; 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); to_write = tfe_http_session_allow_write(session);
if (to_write == NULL) if (to_write == NULL)
{ {

View File

@@ -699,6 +699,24 @@ struct tfe_http_session_ops nghttp2_session_ops =
.ops_response_create = h2_ops_response_create .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 static ssize_t
upstream_read_callback(nghttp2_session *session, int32_t stream_id, upstream_read_callback(nghttp2_session *session, int32_t stream_id,
uint8_t *buf, size_t length, 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; 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 static enum tfe_stream_action
nghttp2_submit_data_by_h2_half(struct tfe_h2_stream *connection, nghttp2_submit_data_by_h2_half(struct tfe_h2_stream *connection,
struct tfe_h2_session *h2_session, 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; struct tfe_h2_session *h2_session = NULL;
nghttp2_session *ngh2_session = tfe_h2_stream_get_nghttp2_peer_session(h2_stream_info, dir); 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, h2_session = (struct tfe_h2_session *)nghttp2_session_get_stream_user_data(ngh2_session, frame->hd.stream_id);
frame->hd.stream_id);
if (!h2_session) if (!h2_session)
{ {
h2_stream_info->stream_action = ACTION_DROP_DATA;
return 0; return 0;
} }
struct tfe_h2_half_private *h2_half = tfe_h2_stream_get_half(h2_session, dir); struct tfe_h2_half_private *h2_half = tfe_h2_stream_get_half(h2_session, dir);
/*HEAD STREMA_END + DATA(9)**/ /*HEAD STREMA_END + DATA(9)**/
if (h2_half == NULL) 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; return 0;
} }
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)
{ {
if (dir == CONN_DIR_UPSTREAM) 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){ if (direction == TFE_HTTP_RESPONSE){
struct tfe_h2_half_private *resp = h2_session->resp; struct tfe_h2_half_private *resp = h2_session->resp;
tfe_session->resp = &resp->half_public; tfe_session->resp = &resp->half_public;
tfe_session->session_id = stream_id;
} }
return 0; 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; struct tfe_h2_half_private *half_private = NULL;
h2_session->ngh2_stream_id = stream_id; h2_session->ngh2_stream_id = stream_id;
h2_session->session = as_server;
h2_session->req = tfe_half_private_init(TFE_HTTP_REQUEST, 0, NULL); h2_session->req = tfe_half_private_init(TFE_HTTP_REQUEST, 0, NULL);
tfe_half_session_init(h2_session, stream_id, TFE_HTTP_REQUEST); 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; h2_stream_info->stream_action = stream_action;
finish: finish:
#ifdef TFE_LOG_HTTP2 #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, 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); 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**/ /*Create C' half_private_resp**/
downstream_create_resp(h2_session, h2_stream_info->as_client, h2_stream_info->as_server, 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); 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) 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; struct tfe_h2_stream *h2_stream_info = (struct tfe_h2_stream *)user_data;
/*proc build resp*/ /*proc build resp*/
struct tfe_h2_session *h2_session = TAILQ_LIST_FIND(h2_stream_info, stream_id); struct tfe_h2_session *h2_session = (struct tfe_h2_session *)nghttp2_session_get_stream_user_data(session, stream_id);
if (NULL == h2_session) if (h2_session == NULL){
{
h2_stream_info->stream_action = ACTION_DROP_DATA;
return 0; return 0;
} }
resp = h2_session->resp; 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 tfe_h2_session *h2_session = NULL;
struct user_event_dispatch *event = 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); h2_session = TAILQ_LIST_FIND(h2_stream_info, stream_id);
if (h2_session == NULL){ if (h2_session == NULL){
goto resp;
}
if (h2_session->resp){
/** todo:When the data of the reply is pushed as promised, /** todo:When the data of the reply is pushed as promised,
there is no stream id at the reply end. to create it*/ there is no stream id at the reply end. to create it*/
goto finish; goto finish;
} }
if (h2_session->resp){ resp:
goto finish; 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); 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); 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; event->tfe_session = &h2_session->tfe_session;
half_set_callback(h2_session->resp, event, free); 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; h2_session->resp->frame_ctx = h2_session->frame_ctx;
nghttp2_session_set_stream_user_data(session, stream_id, h2_session); nghttp2_session_set_stream_user_data(session, stream_id, h2_session);
finish: 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) if (h2_stream_info->kill_signal)
{ {
nghttp2_disect_goaway(h2_stream_info);
tfe_stream_kill(tfe_stream); tfe_stream_kill(tfe_stream);
} }