diff options
author | Craig Tiller <ctiller@google.com> | 2016-11-18 16:10:24 -0800 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2016-11-18 16:10:24 -0800 |
commit | 03cdd3e2de886659761878ea877f6ad5d51f6319 (patch) | |
tree | 138a626389f4e0cd9525febd81a361a381f69af3 | |
parent | 5ae3ffb3676de640598e675f2670ef8695559fbf (diff) |
Fix timeout decoding
-rw-r--r-- | src/core/ext/transport/chttp2/transport/parsing.c | 15 | ||||
-rw-r--r-- | src/core/lib/transport/metadata.c | 1 | ||||
-rw-r--r-- | src/core/lib/transport/timeout_encoding.c | 15 | ||||
-rw-r--r-- | src/core/lib/transport/timeout_encoding.h | 3 | ||||
-rw-r--r-- | test/core/transport/timeout_encoding_test.c | 7 |
5 files changed, 21 insertions, 20 deletions
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 670ce51b72..12f850791d 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -470,23 +470,24 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp, if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT) == 0) { gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout); - if (!cached_timeout) { + gpr_timespec timeout; + if (cached_timeout == NULL) { /* not already parsed: parse it now, and store the result away */ cached_timeout = gpr_malloc(sizeof(gpr_timespec)); - if (!grpc_http2_decode_timeout(GRPC_SLICE_START_PTR(GRPC_MDVALUE(md)), - GRPC_SLICE_LENGTH(GRPC_MDVALUE(md)), - cached_timeout)) { + if (!grpc_http2_decode_timeout(GRPC_MDVALUE(md), cached_timeout)) { char *val = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val); gpr_free(val); *cached_timeout = gpr_inf_future(GPR_TIMESPAN); } - cached_timeout = - grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); + timeout = *cached_timeout; + grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); + } else { + timeout = *cached_timeout; } grpc_chttp2_incoming_metadata_buffer_set_deadline( &s->metadata_buffer[0], - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout)); + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), timeout)); GRPC_MDELEM_UNREF(exec_ctx, md); } else { const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c index f3f6b1311f..2082d1bac2 100644 --- a/src/core/lib/transport/metadata.c +++ b/src/core/lib/transport/metadata.c @@ -496,6 +496,7 @@ void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *), bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b) { if (a.payload == b.payload) return true; + if (GRPC_MDISNULL(a) || GRPC_MDISNULL(b)) return false; return 0 == grpc_slice_cmp(GRPC_MDKEY(a), GRPC_MDKEY(b)) && 0 == grpc_slice_cmp(GRPC_MDVALUE(a), GRPC_MDVALUE(b)); } diff --git a/src/core/lib/transport/timeout_encoding.c b/src/core/lib/transport/timeout_encoding.c index b2060be59e..0d4d7e5a7e 100644 --- a/src/core/lib/transport/timeout_encoding.c +++ b/src/core/lib/transport/timeout_encoding.c @@ -131,16 +131,15 @@ void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer) { } } -static int is_all_whitespace(const char *p) { - while (*p == ' ') p++; - return *p == 0; +static int is_all_whitespace(const char *p, const char *end) { + while (p != end && *p == ' ') p++; + return p == end; } -int grpc_http2_decode_timeout(const uint8_t *buffer, size_t length, - gpr_timespec *timeout) { +int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout) { int32_t x = 0; - const uint8_t *p = buffer; - const uint8_t *end = p + length; + const uint8_t *p = GRPC_SLICE_START_PTR(text); + const uint8_t *end = GRPC_SLICE_END_PTR(text); int have_digit = 0; /* skip whitespace */ for (; p != end && *p == ' '; p++) @@ -187,5 +186,5 @@ int grpc_http2_decode_timeout(const uint8_t *buffer, size_t length, return 0; } p++; - return is_all_whitespace((const char *)p); + return is_all_whitespace((const char *)p, (const char *)end); } diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h index 838892595f..9b34cec373 100644 --- a/src/core/lib/transport/timeout_encoding.h +++ b/src/core/lib/transport/timeout_encoding.h @@ -42,7 +42,6 @@ /* Encode/decode timeouts to the GRPC over HTTP/2 format; encoding may round up arbitrarily */ void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer); -int grpc_http2_decode_timeout(const uint8_t *buffer, size_t length, - gpr_timespec *timeout); +int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout); #endif /* GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H */ diff --git a/test/core/transport/timeout_encoding_test.c b/test/core/transport/timeout_encoding_test.c index 23b1eb577b..10e1804995 100644 --- a/test/core/transport/timeout_encoding_test.c +++ b/test/core/transport/timeout_encoding_test.c @@ -88,8 +88,8 @@ void test_encoding(void) { static void assert_decodes_as(const char *buffer, gpr_timespec expected) { gpr_timespec got; gpr_log(GPR_INFO, "check decoding '%s'", buffer); - GPR_ASSERT(1 == grpc_http2_decode_timeout((const uint8_t *)buffer, - strlen(buffer), &got)); + GPR_ASSERT(1 == grpc_http2_decode_timeout( + grpc_slice_from_static_string(buffer), &got)); GPR_ASSERT(0 == gpr_time_cmp(got, expected)); } @@ -137,7 +137,8 @@ void test_decoding(void) { static void assert_decoding_fails(const char *s) { gpr_timespec x; - GPR_ASSERT(0 == grpc_http2_decode_timeout((const uint8_t *)s, strlen(s), &x)); + GPR_ASSERT(0 == + grpc_http2_decode_timeout(grpc_slice_from_static_string(s), &x)); } void test_decoding_fails(void) { |