diff options
author | 2016-03-30 14:58:53 -0700 | |
---|---|---|
committer | 2016-03-30 14:58:53 -0700 | |
commit | cb7a80266b4fb867481807dc439d3c002f74d466 (patch) | |
tree | 33f11445bae0bb5a46e1b34fcd7d8779cd16a002 /src/core/lib/transport/metadata.c | |
parent | 503c3caf0804c7b9e2619f7c58de6b2b415a8fb0 (diff) |
Use base64 encoded length for decoder table size
Diffstat (limited to 'src/core/lib/transport/metadata.c')
-rw-r--r-- | src/core/lib/transport/metadata.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c index 451c8d1cd3..b1005f317a 100644 --- a/src/core/lib/transport/metadata.c +++ b/src/core/lib/transport/metadata.c @@ -38,6 +38,7 @@ #include <string.h> #include <grpc/compression.h> +#include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/atm.h> #include <grpc/support/log.h> @@ -93,6 +94,9 @@ typedef struct internal_string { gpr_slice base64_and_huffman; + uint8_t has_size_in_decoder_table; + size_t size_in_decoder_table; + struct internal_string *bucket_next; } internal_string; @@ -407,6 +411,8 @@ grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) { } s->has_base64_and_huffman_encoded = 0; s->hash = hash; + s->has_size_in_decoder_table = 0; + s->size_in_decoder_table = 0; s->bucket_next = shard->strs[idx]; shard->strs[idx] = s; @@ -576,6 +582,29 @@ grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key, grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length)); } +size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem) { + size_t overhead_and_key = 32 + GPR_SLICE_LENGTH(elem->key->slice); + if (is_mdstr_static(elem->value)) { + return overhead_and_key + GPR_SLICE_LENGTH(elem->value->slice); + } else { + internal_string *is = (internal_string *)elem->value; + size_t value_len = GPR_SLICE_LENGTH(is->slice); + static const uint8_t tail_xtra[3] = {0, 2, 3}; + if (is->has_size_in_decoder_table == 0) { + is->has_size_in_decoder_table = 1; + if (grpc_is_binary_header( + (const char *)GPR_SLICE_START_PTR(elem->key->slice), + GPR_SLICE_LENGTH(elem->key->slice))) { + is->size_in_decoder_table = + value_len / 3 * 4 + tail_xtra[value_len % 3]; + } else { + is->size_in_decoder_table = value_len; + } + } + return overhead_and_key + is->size_in_decoder_table; + } +} + grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) { internal_metadata *md = (internal_metadata *)gmd; if (is_mdelem_static(gmd)) return gmd; |