diff --git a/source/hpack.c b/source/hpack.c index 83aee6467..8e2f0887b 100644 --- a/source/hpack.c +++ b/source/hpack.c @@ -14,9 +14,6 @@ const size_t s_hpack_dynamic_table_initial_elements = 512; /* TODO: shouldn't be a hardcoded max_size, it should be driven by SETTINGS_HEADER_TABLE_SIZE */ const size_t s_hpack_dynamic_table_max_size = 16 * 1024 * 1024; -/* Used for growing the dynamic table buffer when it fills up */ -const float s_hpack_dynamic_table_buffer_growth_rate = 1.5F; - struct aws_http_header s_static_header_table[] = { #define HEADER(_index, _name) \ [_index] = { \ @@ -421,7 +418,8 @@ int aws_hpack_insert_header(struct aws_hpack_context *context, const struct aws_ /* If the buffer is currently of 0 size, reset it back to its initial size */ const size_t new_size = context->dynamic_table.buffer_capacity - ? (size_t)(context->dynamic_table.buffer_capacity * s_hpack_dynamic_table_buffer_growth_rate) + /* increase buffer by 1.5 rounded up. */ + ? (size_t)(context->dynamic_table.buffer_capacity + ((context->dynamic_table.buffer_capacity + 1) / 2)) : s_hpack_dynamic_table_initial_elements; if (s_dynamic_table_resize_buffer(context, new_size)) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index af57e205d..d9d6fd3af 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -297,6 +297,7 @@ add_test_case(hpack_dynamic_table_get) add_test_case(hpack_decode_indexed_from_dynamic_table) add_test_case(hpack_dynamic_table_empty_value) add_test_case(hpack_dynamic_table_with_empty_header) +add_test_case(hpack_dynamic_table_growth_corner_case) add_test_case(hpack_dynamic_table_size_update_from_setting) if(ENABLE_LOCALHOST_INTEGRATION_TESTS) diff --git a/tests/test_hpack.c b/tests/test_hpack.c index 195413823..cdf8be4d6 100644 --- a/tests/test_hpack.c +++ b/tests/test_hpack.c @@ -815,6 +815,34 @@ static int test_hpack_dynamic_table_with_empty_header(struct aws_allocator *allo return AWS_OP_SUCCESS; } +AWS_TEST_CASE(hpack_dynamic_table_growth_corner_case, test_hpack_dynamic_table_growth_corner_case) +static int test_hpack_dynamic_table_growth_corner_case(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + aws_http_library_init(allocator); + struct aws_hpack_context context; + aws_hpack_context_init(&context, allocator, AWS_LS_HTTP_GENERAL, NULL); + + DEFINE_STATIC_HEADER(h1, "herp", "derp"); + DEFINE_STATIC_HEADER(h2, "fizz", "buzz"); + + const size_t h1_size = aws_hpack_get_header_size(&h1); + const size_t h2_size = aws_hpack_get_header_size(&h2); + + ASSERT_SUCCESS(aws_hpack_insert_header(&context, &h1)); + ASSERT_UINT_EQUALS(1, aws_hpack_get_dynamic_table_num_elements(&context)); + + ASSERT_SUCCESS(aws_hpack_resize_dynamic_table(&context, h1_size + h2_size + 1)); + ASSERT_UINT_EQUALS(1, aws_hpack_get_dynamic_table_num_elements(&context)); + + ASSERT_SUCCESS(aws_hpack_insert_header(&context, &h2)); + ASSERT_UINT_EQUALS(2, aws_hpack_get_dynamic_table_num_elements(&context)); + + aws_hpack_context_clean_up(&context); + aws_http_library_clean_up(); + return AWS_OP_SUCCESS; +} + AWS_TEST_CASE(hpack_dynamic_table_size_update_from_setting, test_hpack_dynamic_table_size_update_from_setting) static int test_hpack_dynamic_table_size_update_from_setting(struct aws_allocator *allocator, void *ctx) { (void)ctx;