Close #76 修正HTTP Upgrade后没有正确Detach该连接的问题
* 原实现没有正确处理Upgrade标志位,导致连接再次进入HTTP解析流程从而无法解析,报#76所列之问题。 * 现修正,亦增加#76所示日志之五元组信息。
This commit is contained in:
@@ -208,11 +208,11 @@ struct tfe_stream_write_ctx * tfe_stream_write_frag_start(const struct tfe_strea
|
|||||||
|
|
||||||
int tfe_stream_write_frag(struct tfe_stream_write_ctx * w_ctx, const unsigned char * data, size_t size)
|
int tfe_stream_write_frag(struct tfe_stream_write_ctx * w_ctx, const unsigned char * data, size_t size)
|
||||||
{
|
{
|
||||||
if(w_ctx->_stream == NULL)
|
if (w_ctx->_stream == NULL)
|
||||||
{
|
{
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tfe_conn_private * this_conn = __this_conn(w_ctx->_stream, w_ctx->dir);
|
struct tfe_conn_private * this_conn = __this_conn(w_ctx->_stream, w_ctx->dir);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if (this_conn != NULL)
|
if (this_conn != NULL)
|
||||||
@@ -254,7 +254,7 @@ void tfe_stream_write_frag_end(struct tfe_stream_write_ctx * w_ctx)
|
|||||||
w_ctx->_stream->w_ctx_upstream = NULL;
|
w_ctx->_stream->w_ctx_upstream = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
__out:
|
__out:
|
||||||
free(w_ctx);
|
free(w_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,6 +503,11 @@ static void __stream_bev_readcb(struct bufferevent * bev, void * arg)
|
|||||||
plug_ctx->is_plugin_opened = 1;
|
plug_ctx->is_plugin_opened = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (plug_ctx->state == PLUG_STATE_DETACHED)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (p_info_iter->on_data != NULL)
|
if (p_info_iter->on_data != NULL)
|
||||||
{
|
{
|
||||||
action_tmp = p_info_iter->on_data(&_stream->head, _stream->thread_ref->thread_id,
|
action_tmp = p_info_iter->on_data(&_stream->head, _stream->thread_ref->thread_id,
|
||||||
@@ -677,11 +682,11 @@ __close_connection:
|
|||||||
if (*ref_this_conn != NULL)
|
if (*ref_this_conn != NULL)
|
||||||
{
|
{
|
||||||
/* There is a frag writter setted, need to clear the reference of stream in the writter to indicate the connection is closed */
|
/* There is a frag writter setted, need to clear the reference of stream in the writter to indicate the connection is closed */
|
||||||
if(*ref_this_write_ctx != NULL)
|
if (*ref_this_write_ctx != NULL)
|
||||||
{
|
{
|
||||||
(*ref_this_write_ctx)->_stream = NULL;
|
(*ref_this_write_ctx)->_stream = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
__conn_private_destory_with_ssl(ev_base, *ref_this_conn, *ref_this_ssl_stream);
|
__conn_private_destory_with_ssl(ev_base, *ref_this_conn, *ref_this_ssl_stream);
|
||||||
*ref_this_conn = NULL;
|
*ref_this_conn = NULL;
|
||||||
*ref_this_ssl_stream = NULL;
|
*ref_this_ssl_stream = NULL;
|
||||||
@@ -972,15 +977,15 @@ int __fd_ttl_option_setup(struct tfe_stream_private * _stream, evutil_socket_t f
|
|||||||
struct sockaddr_storage sk_storage;
|
struct sockaddr_storage sk_storage;
|
||||||
socklen_t sk_storage_len = sizeof(sk_storage);
|
socklen_t sk_storage_len = sizeof(sk_storage);
|
||||||
|
|
||||||
if (getsockname(fd, (struct sockaddr *)&sk_storage, &sk_storage_len) < 0)
|
if (getsockname(fd, (struct sockaddr *) &sk_storage, &sk_storage_len) < 0)
|
||||||
{
|
{
|
||||||
TFE_STREAM_LOG_ERROR(_stream, "getsockname(fd = %d) failed: %s", fd, strerror(errno));
|
TFE_STREAM_LOG_ERROR(_stream, "getsockname(fd = %d) failed: %s", fd, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For IPv4, set TTL */
|
/* For IPv4, set TTL */
|
||||||
unsigned int __ttl = (unsigned int)ttl;
|
unsigned int __ttl = (unsigned int) ttl;
|
||||||
const char * __str_family = NULL;
|
const char * __str_family = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (sk_storage.ss_family == AF_INET)
|
if (sk_storage.ss_family == AF_INET)
|
||||||
@@ -995,10 +1000,11 @@ int __fd_ttl_option_setup(struct tfe_stream_private * _stream, evutil_socket_t f
|
|||||||
}
|
}
|
||||||
else { assert(0); }
|
else { assert(0); }
|
||||||
|
|
||||||
if(ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
TFE_STREAM_LOG_ERROR(_stream, "setsockopt(ttl = %u, fd = %d, family = %s) failed: %s",
|
TFE_STREAM_LOG_ERROR(_stream, "setsockopt(ttl = %u, fd = %d, family = %s) failed: %s",
|
||||||
__ttl, fd, __str_family, strerror(errno)); return -2;
|
__ttl, fd, __str_family, strerror(errno));
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1080,7 +1086,7 @@ void __stream_fd_option_setup(struct tfe_stream_private * _stream, evutil_socket
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __ttl = (dir == CONN_DIR_UPSTREAM) ? tcp_options->tcp_ttl_upstream : tcp_options->tcp_ttl_downstream;
|
int __ttl = (dir == CONN_DIR_UPSTREAM) ? tcp_options->tcp_ttl_upstream : tcp_options->tcp_ttl_downstream;
|
||||||
if(__ttl > 0 && __fd_ttl_option_setup(_stream, fd, __ttl) < 0)
|
if (__ttl > 0 && __fd_ttl_option_setup(_stream, fd, __ttl) < 0)
|
||||||
{
|
{
|
||||||
TFE_STREAM_LOG_ERROR(stream, "Failed at setup FD's ttl option, ttl = %d, fd = %d", __ttl, fd);
|
TFE_STREAM_LOG_ERROR(stream, "Failed at setup FD's ttl option, ttl = %d, fd = %d", __ttl, fd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ int http_plugin_init(struct tfe_proxy * proxy)
|
|||||||
plugin_ctx->gc_event_hs_private[thread_id] = gc_event;
|
plugin_ctx->gc_event_hs_private[thread_id] = gc_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin_ctx->access_logger = MESA_create_runtime_log_handle("log/http-access.log", RLOG_LV_INFO);
|
plugin_ctx->access_logger = MESA_create_runtime_log_handle("log/http.log", RLOG_LV_INFO);
|
||||||
assert(plugin_ctx->access_logger != NULL);
|
assert(plugin_ctx->access_logger != NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -419,6 +419,11 @@ enum tfe_stream_action http_connection_entry(const struct tfe_stream * stream, e
|
|||||||
return ACTION_DEFER_DATA;
|
return ACTION_DEFER_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hf_private_in->is_upgrade || hf_private_in->is_passthrough)
|
||||||
|
{
|
||||||
|
goto __passthrough;
|
||||||
|
}
|
||||||
|
|
||||||
/* Need more data, no boundary touched */
|
/* Need more data, no boundary touched */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
@@ -431,18 +436,14 @@ enum tfe_stream_action http_connection_entry(const struct tfe_stream * stream, e
|
|||||||
return hf_private_in->stream_action;
|
return hf_private_in->stream_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == -1 && hf_private_in->is_passthrough)
|
|
||||||
{
|
|
||||||
goto __passthrough;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some kind of error happened, write log and detach the stream */
|
/* Some kind of error happened, write log and detach the stream */
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
TFE_STREAM_LOG_ERROR(stream, "Failed at parsing stream as HTTP: %u, %s, %s",
|
TFE_LOG_ERROR(g_http_plugin->access_logger, "%s: Failed at parsing stream as HTTP, %u, %s, %s",
|
||||||
hf_private_in->parse_errno, http_errno_name(hf_private_in->parse_errno),
|
stream->str_stream_info, hf_private_in->parse_errno, http_errno_name(hf_private_in->parse_errno),
|
||||||
http_errno_description(hf_private_in->parse_errno));
|
http_errno_description(hf_private_in->parse_errno));
|
||||||
|
|
||||||
|
tfe_hexdump2file(stderr, "Failed at parsing stream as HTTP", data, (unsigned int)len);
|
||||||
goto __passthrough;
|
goto __passthrough;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user