summaryrefslogtreecommitdiff
path: root/plugin/protocol/http2/src/http2_stream.cpp
diff options
context:
space:
mode:
authorfengweihao <[email protected]>2019-06-19 21:46:38 +0800
committerfengweihao <[email protected]>2019-06-19 21:46:38 +0800
commit07d10d87b63773bdafca6d7cdb8d233e9a89b304 (patch)
treec63ea45636a3c85585e016438c66b87a7dc6779e /plugin/protocol/http2/src/http2_stream.cpp
parentf976deddd9d5b33b287ce0796e5da2bb4ee8e998 (diff)
#146
修复HTTP2命中应答头规则后,页面无显示 修复HTTP2注册发送数据接口,发送数据时由于数据已经发送,但是注册的发送接口未销毁
Diffstat (limited to 'plugin/protocol/http2/src/http2_stream.cpp')
-rw-r--r--plugin/protocol/http2/src/http2_stream.cpp222
1 files changed, 138 insertions, 84 deletions
diff --git a/plugin/protocol/http2/src/http2_stream.cpp b/plugin/protocol/http2/src/http2_stream.cpp
index 93ed2da..2f70b61 100644
--- a/plugin/protocol/http2/src/http2_stream.cpp
+++ b/plugin/protocol/http2/src/http2_stream.cpp
@@ -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);
+
+ 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);
+ }
- 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**/
- 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 */
@@ -1452,6 +1473,47 @@ nghttp2_headers_write_log(struct tfe_h2_session *h2_session, const char * str_st
}
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;
}