修复HTTP2命中应答头规则后,页面无显示
修复HTTP2注册发送数据接口,发送数据时由于数据已经发送,但是注册的发送接口未销毁
This commit is contained in:
fengweihao
2019-06-19 21:46:38 +08:00
parent f976deddd9
commit 07d10d87b6

View File

@@ -171,6 +171,20 @@ headers_init(struct tfe_h2_header *header)
TAILQ_INIT(&header->h2_field_list);
}
const char * method_idx_to_str(int encode)
{
switch (encode)
{
case HTTP2_CONTENT_ENCODING_GZIP: return "gzip";
case HTTP2_CONTENT_ENCODING_X_GZIP: return "x-gzip";
case HTTP2_CONTENT_ENCODING_DEFLATE: return "deflate";
case HTTP2_CONTENT_ENCODING_BZIP2: return "bzip2";
case HTTP2_CONTENT_ENCODING_X_BZIP2: return "x-bzip2";
case HTTP2_CONTENT_ENCODING_BR: return "br";
default: return "";
}
}
static int
method_to_str_idx(const char * method)
{
@@ -712,7 +726,8 @@ upstream_read_callback(nghttp2_session *session, int32_t stream_id,
static enum tfe_stream_action
nghttp2_frame_submit_built_resp(struct tfe_h2_stream *h2_stream_info,
struct tfe_h2_session *h2_session)
struct tfe_h2_session *h2_session,
nghttp2_data_provider *data_prd)
{
int rv = -1;
struct tfe_h2_header *h2_header = NULL;
@@ -725,28 +740,32 @@ nghttp2_frame_submit_built_resp(struct tfe_h2_stream *h2_stream_info,
}
h2_header = &pangu_resp->header;
if (h2_header->nvlen <= 0)
{
return ACTION_FORWARD_DATA;
}
struct tfe_h2_payload *body = &pangu_resp->h2_payload;
body->flags |= NGHTTP2_FLAG_END_STREAM;
char str_sz_evbuf_body[TFE_STRING_MAX];
snprintf(str_sz_evbuf_body, sizeof(str_sz_evbuf_body) - 1, "%lu", evbuffer_get_length(body->evbuf_body));
const static struct http_field_name encoding_field = {TFE_HTTP_CONT_LENGTH, NULL};
tfe_http_field_write(&pangu_resp->half_public, &encoding_field, str_sz_evbuf_body);
const static struct http_field_name cont_field = {TFE_HTTP_CONT_LENGTH, NULL};
tfe_http_field_write(&pangu_resp->half_public, &cont_field, str_sz_evbuf_body);
nghttp2_data_provider data_prd;
data_prd.source.ptr = (void *)body;
data_prd.read_callback = upstream_read_callback;
if (body->gzip != HTTP2_CONTENT_ENCODING_NONE)
{
const static struct http_field_name encoding_field = {TFE_HTTP_CONT_ENCODING, NULL};
const char *content_encoding = method_idx_to_str(body->gzip);
tfe_http_field_write(&pangu_resp->half_public, &encoding_field, content_encoding);
}
data_prd->source.ptr = (void *)body;
data_prd->read_callback = upstream_read_callback;
nghttp2_nv hdrs[h2_header->nvlen];
/*Adapt Http uri Settings**/
tfe_http_field_write(&pangu_resp->half_public, &encoding_field, str_sz_evbuf_body);
rv = nghttp2_submit_response(h2_stream_info->as_server, h2_session->ngh2_stream_id, tfe_h2_header_convert_nv(h2_header, hdrs),
h2_header->nvlen, &data_prd);
h2_header->nvlen, data_prd);
if (rv != 0){
return ACTION_FORWARD_DATA;
}
@@ -757,7 +776,8 @@ nghttp2_frame_submit_built_resp(struct tfe_h2_stream *h2_stream_info,
static enum tfe_stream_action
nghttp2_frame_submit_built_req(struct tfe_h2_stream *h2_stream_info,
struct tfe_h2_session *h2_session)
struct tfe_h2_session *h2_session,
nghttp2_data_provider *data_prd)
{
int32_t stream_id = -1;
struct tfe_h2_header *h2_header = NULL;
@@ -778,15 +798,14 @@ nghttp2_frame_submit_built_req(struct tfe_h2_stream *h2_stream_info,
const static struct http_field_name encoding_field = {TFE_HTTP_CONT_LENGTH, NULL};
tfe_http_field_write(&plugin_built_req->half_public, &encoding_field, str_sz_evbuf_body);
nghttp2_data_provider data_prd;
data_prd.source.ptr = (void *)body;
data_prd.read_callback = upstream_read_callback;
data_prd->source.ptr = (void *)body;
data_prd->read_callback = upstream_read_callback;
nghttp2_nv hdrs[h2_header->nvlen];
/*Adapt Http uri Settings**/
stream_id = nghttp2_submit_request(h2_stream_info->as_client, NULL,
tfe_h2_header_modify_field(h2_header, hdrs, ":path", plugin_built_req->url_storage),
h2_header->nvlen, &data_prd, h2_session);
h2_header->nvlen, data_prd, h2_session);
if (stream_id < 0){
TFE_LOG_ERROR(logger()->handle, "Could not submit request: %s",
@@ -800,8 +819,9 @@ nghttp2_frame_submit_built_req(struct tfe_h2_stream *h2_stream_info,
static enum tfe_stream_action
nghttp2_submit_data_by_h2_half(struct tfe_h2_stream *connection,
struct tfe_h2_session *h2_session,
enum tfe_conn_dir dir)
struct tfe_h2_session *h2_session,
nghttp2_data_provider *data_provider,
enum tfe_conn_dir dir)
{
enum tfe_stream_action stream_action = ACTION_DROP_DATA;
@@ -810,23 +830,21 @@ nghttp2_submit_data_by_h2_half(struct tfe_h2_stream *connection,
if (h2_session->plugin_built_resp)
{
stream_action = nghttp2_frame_submit_built_resp(connection, h2_session);
stream_action = nghttp2_frame_submit_built_resp(connection, h2_session, data_provider);
}
else if (h2_session->plugin_built_req)
{
stream_action = nghttp2_frame_submit_built_req(connection, h2_session);
stream_action = nghttp2_frame_submit_built_req(connection, h2_session, data_provider);
}
else
{
int rv = -1;
struct tfe_h2_payload *body = &h2_half->h2_payload;
nghttp2_data_provider upstream_data_provider;
upstream_data_provider.source.ptr = (void *)body;
upstream_data_provider.read_callback = upstream_read_callback;
data_provider->source.ptr = (void *)body;
data_provider->read_callback = upstream_read_callback;
rv = nghttp2_submit_data(ngh2_session, body->flags,
h2_session->ngh2_stream_id, &upstream_data_provider);
h2_session->ngh2_stream_id, data_provider);
if (rv != 0){
stream_action = ACTION_FORWARD_DATA;
//printf("Fatal server submit data error: %s\n", nghttp2_strerror(rv));
@@ -1178,7 +1196,10 @@ nghttp2_submit_complete_data(struct tfe_h2_stream *h2_stream_info,
h2_half->body_state = H2_READ_STATE_COMPLETE;
h2_half->message_state = H2_READ_STATE_COMPLETE;
stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, CONN_DIR_UPSTREAM);
/*registeredSend data**/
nghttp2_data_provider *data_provider;
data_provider = ALLOC(nghttp2_data_provider, 1);
stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, data_provider, CONN_DIR_UPSTREAM);
if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(ngh2_session);
if (xret != 0) {
@@ -1188,6 +1209,8 @@ nghttp2_submit_complete_data(struct tfe_h2_stream *h2_stream_info,
}
if (stream_action == ACTION_USER_DATA)
stream_action = ACTION_DROP_DATA;
free(data_provider);
data_provider = NULL;
h2_stream_info->stream_action = stream_action;
return 1;
}
@@ -1201,9 +1224,7 @@ nghttp2_submit_frame_data(struct tfe_h2_stream *h2_stream_info,const nghttp2_fra
h2_session = TAILQ_LIST_FIND(h2_stream_info, frame->hd.stream_id);
if (NULL == h2_session)
{
TFE_LOG_ERROR(logger()->handle, "id %d, can't find stream information(addr = %p)",
frame->hd.stream_id, h2_stream_info);
return 0;;
return 0;
}
struct tfe_h2_half_private *h2_half = tfe_h2_stream_get_half(h2_session, dir);
@@ -1410,7 +1431,7 @@ fill_resp_spec_from_handle(struct tfe_h2_half_private *half_private)
}
int
nghttp2_headers_write_log(struct tfe_h2_session *h2_session, const char * str_stream_info,
nghttp2_write_log(struct tfe_h2_session *h2_session, const char * str_stream_info,
int dir)
{
/* Request */
@@ -1451,6 +1472,47 @@ nghttp2_headers_write_log(struct tfe_h2_session *h2_session, const char * str_st
return 0;
}
static enum tfe_stream_action
nghttp2_submit_built_response(struct tfe_h2_stream *h2_stream_info,
struct tfe_h2_session *h2_session)
{
int xret = -1;
char value[128] = {0};
enum tfe_stream_action stream_action = ACTION_FORWARD_DATA;
struct tfe_h2_half_private *resp = h2_session->plugin_built_resp;
struct http_field_name field;
field.field_id = TFE_HTTP_UNKNOWN_FIELD;
field.field_name = "X-TG-Construct-By";
snprintf(value, sizeof(value), "tfe/%s", tfe_version());
tfe_h2_header_add_field(&resp->header, &field, (const char *)value, 0);
field.field_id = TFE_HTTP_UNKNOWN_FIELD;
field.field_name = ":status";
snprintf(value, sizeof(value), "%d", resp->method_or_status);
tfe_h2_header_add_field(&resp->header, &field, (const char *)value, 0);
nghttp2_data_provider *data_prd;
data_prd = ALLOC(nghttp2_data_provider, 1);
stream_action = nghttp2_frame_submit_built_resp(h2_stream_info, h2_session, data_prd);
if (stream_action == ACTION_DROP_DATA)
{
xret = nghttp2_session_send(h2_stream_info->as_server);
if (xret != 0) {
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Fatal downstream send error: %s\n",
nghttp2_strerror(xret));
}
}
if (stream_action == ACTION_DROP_DATA)
{
stream_action = (enum tfe_stream_action)ACTION_USER_DATA;
}
free(data_prd);
data_prd = NULL;
return stream_action;
}
static enum tfe_stream_action
nghttp2_server_frame_submit_header(struct tfe_h2_stream *h2_stream_info,
struct tfe_h2_session *h2_session)
@@ -1461,7 +1523,14 @@ nghttp2_server_frame_submit_header(struct tfe_h2_stream *h2_stream_info,
enum tfe_stream_action stream_action = ACTION_DROP_DATA;
if (h2_session->plugin_built_resp != NULL){
stream_action = (enum tfe_stream_action)ACTION_USER_DATA;
struct tfe_h2_payload *h2_payload = &(h2_session->plugin_built_resp->h2_payload);
if (h2_payload->evbuf_body != NULL && (evbuffer_get_length(h2_payload->evbuf_body) > 0))
{
stream_action = nghttp2_submit_built_response(h2_stream_info, h2_session);
}
else{
stream_action = (enum tfe_stream_action)ACTION_USER_DATA;
}
return stream_action;
}
resp = h2_session->resp;
@@ -1517,7 +1586,7 @@ nghttp2_server_submit_header(struct tfe_h2_stream *h2_stream_info, int32_t strea
stream_action = ACTION_DEFER_DATA;
goto finish;
}
nghttp2_headers_write_log(h2_session,h2_stream_info->tf_stream->str_stream_info, CONN_DIR_UPSTREAM);
nghttp2_write_log(h2_session,h2_stream_info->tf_stream->str_stream_info, CONN_DIR_UPSTREAM);
stream_action = nghttp2_server_frame_submit_header(h2_stream_info, h2_session);
if (stream_action == ACTION_DROP_DATA){
@@ -1558,8 +1627,7 @@ fill_req_spec_from_handle(struct tfe_h2_half_private *half_private)
continue;
}
}
char *urltmp = half_private->url_storage;
urltmp = (char *)malloc(urllen + 1);
char *urltmp = ALLOC(char, urllen + 1);
if(urltmp){
sprintf(urltmp, "%s%s", (char *)req_spec->host, (char *)req_spec->uri);
req_spec->url = urltmp;
@@ -1585,41 +1653,6 @@ suspend_stop(struct tfe_h2_session *h2_session,
}
#endif
static enum tfe_stream_action
nghttp2_submit_built_response(struct tfe_h2_stream *h2_stream_info,
struct tfe_h2_session *h2_session)
{
int xret = -1;
char value[128] = {0};
enum tfe_stream_action stream_action = ACTION_FORWARD_DATA;
struct tfe_h2_half_private *resp = h2_session->plugin_built_resp;
struct http_field_name field;
field.field_id = TFE_HTTP_UNKNOWN_FIELD;
field.field_name = "X-TG-Construct-By";
snprintf(value, sizeof(value), "tfe/%s", tfe_version());
tfe_h2_header_add_field(&resp->header, &field, (const char *)value, 0);
field.field_id = TFE_HTTP_UNKNOWN_FIELD;
field.field_name = ":status";
snprintf(value, sizeof(value), "%d", resp->method_or_status);
tfe_h2_header_add_field(&resp->header, &field, (const char *)value, 0);
stream_action = nghttp2_frame_submit_built_resp(h2_stream_info, h2_session);
if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(h2_stream_info->as_server);
if (xret != 0) {
stream_action = ACTION_FORWARD_DATA;
TFE_LOG_ERROR(logger()->handle, "Fatal downstream send error: %s\n",
nghttp2_strerror(xret));
}
}
if (stream_action == ACTION_DROP_DATA){
stream_action = (enum tfe_stream_action)ACTION_USER_DATA;
}
return stream_action;
}
static void
downstream_create_resp(struct tfe_h2_session *h2_session, nghttp2_session *as_client,
nghttp2_session *as_server, const struct tfe_stream *tf_stream, unsigned int thread_id)
@@ -1663,7 +1696,7 @@ 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);
//nghttp2_session_set_next_stream_id(h2_stream_info->as_client, h2_session->ngh2_stream_id);
if (h2_session->plugin_built_resp)
{
@@ -1726,7 +1759,7 @@ nghttp2_client_submit_header(struct tfe_h2_stream *h2_stream_info, int32_t strea
req->event_cb(req, EV_HTTP_REQ_HDR, NULL, 0, req->event_cb_user);
nghttp2_headers_write_log(h2_session, h2_stream_info->tf_stream->str_stream_info, CONN_DIR_DOWNSTREAM);
nghttp2_write_log(h2_session, h2_stream_info->tf_stream->str_stream_info, CONN_DIR_DOWNSTREAM);
stream_action = nghttp2_client_frame_submit_header(h2_stream_info, h2_session);
if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(h2_stream_info->as_client);
@@ -1963,13 +1996,19 @@ 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_session *h2_session = (struct tfe_h2_session *)nghttp2_session_get_stream_user_data(session, stream_id);
if (!h2_session){
TFE_LOG_ERROR(logger()->handle, "On data callback can't get downstream information, id = %d",
stream_id);
goto finish;
/*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;
return 0;
}
resp = h2_session->resp;
if (resp == NULL){
h2_stream_info->stream_action = ACTION_DROP_DATA;
return 0;
}
evbuffer_add(resp->h2_payload.evbuf_body, input, input_len);
if (resp->h2_payload.gzip != HTTP2_CONTENT_ENCODING_NONE){
@@ -2011,7 +2050,10 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
}
if (uncompr_len) FREE(&uncompr);
stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, CONN_DIR_UPSTREAM);
nghttp2_data_provider *data_provider = NULL;
data_provider = ALLOC(nghttp2_data_provider, 1);
stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, data_provider, CONN_DIR_UPSTREAM);
if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(h2_stream_info->as_server);
if (xret != 0) {
@@ -2019,15 +2061,11 @@ nghttp2_client_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
TFE_LOG_ERROR(logger()->handle, "Fatal upstream(%d) send error: %s\n",stream_id, nghttp2_strerror(xret));
}
}
#ifdef TFE_LOG_HTTP2
TFE_LOG_DEBUG(logger()->handle, "%s, 1, submit data %d, stream_id:%d, action:%d", h2_stream_info->tf_stream->str_stream_info,
(int)input_len, stream_id, stream_action);
#endif
if (stream_action == ACTION_USER_DATA)
stream_action = ACTION_DROP_DATA;
free(data_provider);
data_provider = NULL;
h2_stream_info->stream_action = stream_action;
finish:
return 0;
}
@@ -2330,7 +2368,9 @@ nghttp2_server_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
}
if (uncompr_len) FREE(&uncompr);
stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, CONN_DIR_DOWNSTREAM);
nghttp2_data_provider *data_provider;
data_provider = ALLOC(nghttp2_data_provider, 1);
stream_action = nghttp2_submit_data_by_h2_half(h2_stream_info, h2_session, data_provider, CONN_DIR_DOWNSTREAM);
if (stream_action == ACTION_DROP_DATA){
xret = nghttp2_session_send(h2_stream_info->as_client);
if (xret != 0) {
@@ -2340,6 +2380,8 @@ nghttp2_server_on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
}
if (stream_action == ACTION_USER_DATA)
stream_action = ACTION_DROP_DATA;
free(data_provider);
data_provider = NULL;
h2_stream_info->stream_action = stream_action;
finish:
return 0;
@@ -2402,6 +2444,12 @@ delete_server_session_data(struct tfe_h2_stream *h2_stream_info)
TAILQ_FOREACH_SAFE(h2_session, &h2_stream_info->h2_session_list, next, peer_h2_stream)
{
TAILQ_REMOVE(&h2_stream_info->h2_session_list, h2_session, next);
if (h2_session->frame_ctx){
http_frame_raise_session_end(h2_session->frame_ctx, h2_stream_info->tf_stream, &h2_session->tfe_session,
h2_stream_info->thread_id);
h2_session->frame_ctx = NULL;
}
delete_http2_stream_data(h2_session, h2_stream_info->tf_stream, 1);
free(h2_session);
h2_session = NULL;
}
@@ -2418,6 +2466,12 @@ delete_client_session_data(struct tfe_h2_stream *h2_stream_info)
TAILQ_FOREACH_SAFE(h2_session, &h2_stream_info->h2_session_list, next, peer_h2_stream){
TAILQ_REMOVE(&h2_stream_info->h2_session_list, h2_session, next);
if (h2_session->frame_ctx){
http_frame_raise_session_end(h2_session->frame_ctx, h2_stream_info->tf_stream, &h2_session->tfe_session,
h2_stream_info->thread_id);
h2_session->frame_ctx = NULL;
}
delete_http2_stream_data(h2_session, h2_stream_info->tf_stream, 1);
free(h2_session);
h2_session = NULL;
}