aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Craig Tiller <craig.tiller@gmail.com>2015-06-17 08:00:39 -0700
committerGravatar Craig Tiller <craig.tiller@gmail.com>2015-06-17 08:00:39 -0700
commit66abdaad3274b33e99042b5e493e749991201f81 (patch)
treed4797a97f3756a957d8b20726efaeaf7c34e61c4
parentaa642de0b7261642892f81bd1cae04987de9c299 (diff)
Properly deal with streams closing during parsing
-rw-r--r--src/core/transport/chttp2/internal.h2
-rw-r--r--src/core/transport/chttp2/parsing.c7
-rw-r--r--src/core/transport/chttp2_transport.c4
3 files changed, 11 insertions, 2 deletions
diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h
index 078d1501bb..644523e810 100644
--- a/src/core/transport/chttp2/internal.h
+++ b/src/core/transport/chttp2/internal.h
@@ -601,6 +601,8 @@ void grpc_chttp2_for_all_streams(
void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data,
grpc_chttp2_stream_global *stream_global));
+void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport_parsing *transport_parsing);
+
#define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
#define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \
(sizeof(GRPC_CHTTP2_CLIENT_CONNECT_STRING) - 1)
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index cea10b592e..93e8dcc1c8 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -327,6 +327,7 @@ int grpc_chttp2_perform_read(grpc_chttp2_transport_parsing *transport_parsing,
if (!parse_frame_slice(transport_parsing, gpr_empty_slice(), 1)) {
return 0;
}
+ transport_parsing->incoming_stream = NULL;
if (++cur == end) {
transport_parsing->deframe_state = DTS_FH_0;
return 1;
@@ -346,6 +347,7 @@ int grpc_chttp2_perform_read(grpc_chttp2_transport_parsing *transport_parsing,
return 0;
}
transport_parsing->deframe_state = DTS_FH_0;
+ transport_parsing->incoming_stream = NULL;
return 1;
} else if ((gpr_uint32)(end - cur) >
transport_parsing->incoming_frame_size) {
@@ -358,6 +360,7 @@ int grpc_chttp2_perform_read(grpc_chttp2_transport_parsing *transport_parsing,
return 0;
}
cur += transport_parsing->incoming_frame_size;
+ transport_parsing->incoming_stream = NULL;
goto dts_fh_0; /* loop */
} else {
if (!parse_frame_slice(
@@ -447,7 +450,7 @@ static int init_skip_frame_parser(
return 1;
}
-static void become_skip_parser(
+void grpc_chttp2_parsing_become_skip_parser(
grpc_chttp2_transport_parsing *transport_parsing) {
init_skip_frame_parser(
transport_parsing,
@@ -736,7 +739,7 @@ static int parse_frame_slice(grpc_chttp2_transport_parsing *transport_parsing,
}
return 1;
case GRPC_CHTTP2_STREAM_ERROR:
- become_skip_parser(transport_parsing);
+ grpc_chttp2_parsing_become_skip_parser(transport_parsing);
if (stream_parsing) {
stream_parsing->saw_rst_stream = 1;
stream_parsing->rst_stream_reason = GRPC_CHTTP2_PROTOCOL_ERROR;
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 582b7ae42a..3cd6c1f67b 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -702,6 +702,10 @@ static void remove_stream(grpc_chttp2_transport *t, gpr_uint32 id) {
grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->parsing_stream_map, id);
GPR_ASSERT(s);
s->global.in_stream_map = 0;
+ if (t->parsing.incoming_stream == &s->parsing) {
+ t->parsing.incoming_stream = NULL;
+ grpc_chttp2_parsing_become_skip_parser(&t->parsing);
+ }
grpc_chttp2_list_remove_incoming_window_updated(&t->global, &s->global);
}