diff options
Diffstat (limited to 'src/core/transport/chttp2')
-rw-r--r-- | src/core/transport/chttp2/frame.h | 2 | ||||
-rw-r--r-- | src/core/transport/chttp2/frame_rst_stream.c | 40 | ||||
-rw-r--r-- | src/core/transport/chttp2/frame_rst_stream.h | 11 | ||||
-rw-r--r-- | src/core/transport/chttp2/hpack_parser.c | 4 | ||||
-rw-r--r-- | src/core/transport/chttp2/hpack_parser.h | 2 |
5 files changed, 57 insertions, 2 deletions
diff --git a/src/core/transport/chttp2/frame.h b/src/core/transport/chttp2/frame.h index ac76c4cc9c..c9e3e13042 100644 --- a/src/core/transport/chttp2/frame.h +++ b/src/core/transport/chttp2/frame.h @@ -53,12 +53,14 @@ typedef struct { gpr_uint8 send_ping_ack; gpr_uint8 process_ping_reply; gpr_uint8 goaway; + gpr_uint8 rst_stream; gpr_int64 initial_window_update; gpr_uint32 window_update; gpr_uint32 goaway_last_stream_index; gpr_uint32 goaway_error; gpr_slice goaway_text; + gpr_uint32 rst_stream_reason; } grpc_chttp2_parse_state; #define GRPC_CHTTP2_FRAME_DATA 0 diff --git a/src/core/transport/chttp2/frame_rst_stream.c b/src/core/transport/chttp2/frame_rst_stream.c index 368ca86481..3016aac7a2 100644 --- a/src/core/transport/chttp2/frame_rst_stream.c +++ b/src/core/transport/chttp2/frame_rst_stream.c @@ -32,6 +32,9 @@ */ #include "src/core/transport/chttp2/frame_rst_stream.h" + +#include <grpc/support/log.h> + #include "src/core/transport/chttp2/frame.h" gpr_slice grpc_chttp2_rst_stream_create(gpr_uint32 id, gpr_uint32 code) { @@ -54,3 +57,40 @@ gpr_slice grpc_chttp2_rst_stream_create(gpr_uint32 id, gpr_uint32 code) { return slice; } + +grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_begin_frame( + grpc_chttp2_rst_stream_parser *parser, gpr_uint32 length, gpr_uint8 flags) { + if (length != 4) { + gpr_log(GPR_ERROR, "invalid rst_stream: length=%d, flags=%02x", length, flags); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + parser->byte = 0; + return GRPC_CHTTP2_PARSE_OK; +} + +grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse( + void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, + int is_last) { + gpr_uint8 *const beg = GPR_SLICE_START_PTR(slice); + gpr_uint8 *const end = GPR_SLICE_END_PTR(slice); + gpr_uint8 *cur = beg; + grpc_chttp2_rst_stream_parser *p = parser; + + while (p->byte != 4 && cur != end) { + p->reason_bytes[p->byte] = *cur; + cur++; + p->byte++; + } + + if (p->byte == 4) { + GPR_ASSERT(is_last); + state->rst_stream = 1; + state->rst_stream_reason = + (((gpr_uint32)p->reason_bytes[0]) << 24) | + (((gpr_uint32)p->reason_bytes[1]) << 16) | + (((gpr_uint32)p->reason_bytes[2]) << 8) | + (((gpr_uint32)p->reason_bytes[3])); + } + + return GRPC_CHTTP2_PARSE_OK; +} diff --git a/src/core/transport/chttp2/frame_rst_stream.h b/src/core/transport/chttp2/frame_rst_stream.h index 2d3ee18637..07a3c98d03 100644 --- a/src/core/transport/chttp2/frame_rst_stream.h +++ b/src/core/transport/chttp2/frame_rst_stream.h @@ -35,7 +35,18 @@ #define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H #include <grpc/support/slice.h> +#include "src/core/transport/chttp2/frame.h" + +typedef struct { + gpr_uint8 byte; + gpr_uint8 reason_bytes[4]; +} grpc_chttp2_rst_stream_parser; gpr_slice grpc_chttp2_rst_stream_create(gpr_uint32 stream_id, gpr_uint32 code); +grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_begin_frame( + grpc_chttp2_rst_stream_parser *parser, gpr_uint32 length, gpr_uint8 flags); +grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse( + void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last); + #endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H */ diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c index 3fd8f67226..a489543868 100644 --- a/src/core/transport/chttp2/hpack_parser.c +++ b/src/core/transport/chttp2/hpack_parser.c @@ -654,7 +654,7 @@ static int parse_stream_weight(grpc_chttp2_hpack_parser *p, return 1; } - return parse_begin(p, cur + 1, end); + return p->after_prioritization(p, cur + 1, end); } static int parse_stream_dep3(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur, @@ -1349,7 +1349,7 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p, } void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) { - GPR_ASSERT(p->state == parse_begin); + p->after_prioritization = p->state; p->state = parse_stream_dep0; } diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h index bb4c1a1f49..bfc06b3980 100644 --- a/src/core/transport/chttp2/hpack_parser.h +++ b/src/core/transport/chttp2/hpack_parser.h @@ -62,6 +62,8 @@ struct grpc_chttp2_hpack_parser { grpc_chttp2_hpack_parser_state state; /* future states dependent on the opening op code */ const grpc_chttp2_hpack_parser_state *next_state; + /* what to do after skipping prioritization data */ + grpc_chttp2_hpack_parser_state after_prioritization; /* the value we're currently parsing */ union { gpr_uint32 *value; |