Fix decoder table size update

When applying new header table size acknowledged with SETTINGS ACK by
an encoder, change the header table size on a decoder only when it
strictly lowers the current maximum table size set by Dynamic Table
Size Update from the encoder or the default size 4096 if no Dynamic
Table Size Update is received.

Previously, the header table size on a decoder is always changed.  If
a maximum size in SETTINGS are increased (e.g., 4096 -> 8192), and
then decreased to the previous value, the decoder incorrectly requires
Dynamic Table Size Update from an encoder.
This commit is contained in:
Tatsuhiro Tsujikawa 2022-01-11 19:50:45 +09:00
parent d91ae6987d
commit deb390cf85
3 changed files with 12 additions and 11 deletions

View File

@ -1263,6 +1263,8 @@ int nghttp2_hd_inflate_change_table_size(
return NGHTTP2_ERR_INVALID_STATE; return NGHTTP2_ERR_INVALID_STATE;
} }
inflater->settings_hd_table_bufsize_max = settings_max_dynamic_table_size;
/* It seems that encoder is not required to send dynamic table size /* It seems that encoder is not required to send dynamic table size
update if the table size is not changed after applying update if the table size is not changed after applying
SETTINGS_HEADER_TABLE_SIZE. RFC 7541 is ambiguous here, but this SETTINGS_HEADER_TABLE_SIZE. RFC 7541 is ambiguous here, but this
@ -1275,13 +1277,12 @@ int nghttp2_hd_inflate_change_table_size(
/* Remember minimum value, and validate that encoder sends the /* Remember minimum value, and validate that encoder sends the
value less than or equal to this. */ value less than or equal to this. */
inflater->min_hd_table_bufsize_max = settings_max_dynamic_table_size; inflater->min_hd_table_bufsize_max = settings_max_dynamic_table_size;
}
inflater->settings_hd_table_bufsize_max = settings_max_dynamic_table_size;
inflater->ctx.hd_table_bufsize_max = settings_max_dynamic_table_size; inflater->ctx.hd_table_bufsize_max = settings_max_dynamic_table_size;
hd_context_shrink_table_size(&inflater->ctx, NULL); hd_context_shrink_table_size(&inflater->ctx, NULL);
}
return 0; return 0;
} }

View File

@ -734,7 +734,7 @@ void test_nghttp2_hd_change_table_size(void) {
CU_ASSERT(4096 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(4096 == deflater.ctx.hd_table_bufsize_max);
CU_ASSERT(8000 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(4096 == inflater.ctx.hd_table_bufsize_max);
CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max); CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max);
/* This will emit encoding context update with header table size 4096 */ /* This will emit encoding context update with header table size 4096 */
@ -830,8 +830,8 @@ void test_nghttp2_hd_change_table_size(void) {
CU_ASSERT(8000 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(8000 == deflater.ctx.hd_table_bufsize_max);
CU_ASSERT(8000 == nghttp2_hd_deflate_get_max_dynamic_table_size(&deflater)); CU_ASSERT(8000 == nghttp2_hd_deflate_get_max_dynamic_table_size(&deflater));
CU_ASSERT(8000 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(4096 == inflater.ctx.hd_table_bufsize_max);
CU_ASSERT(8000 == nghttp2_hd_inflate_get_max_dynamic_table_size(&inflater)); CU_ASSERT(4096 == nghttp2_hd_inflate_get_max_dynamic_table_size(&inflater));
CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max); CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max);
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
@ -856,8 +856,8 @@ void test_nghttp2_hd_change_table_size(void) {
CU_ASSERT(8192 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(8192 == deflater.ctx.hd_table_bufsize_max);
CU_ASSERT(8192 == nghttp2_hd_deflate_get_max_dynamic_table_size(&deflater)); CU_ASSERT(8192 == nghttp2_hd_deflate_get_max_dynamic_table_size(&deflater));
CU_ASSERT(16383 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(8000 == inflater.ctx.hd_table_bufsize_max);
CU_ASSERT(16383 == nghttp2_hd_inflate_get_max_dynamic_table_size(&inflater)); CU_ASSERT(8000 == nghttp2_hd_inflate_get_max_dynamic_table_size(&inflater));
CU_ASSERT(16383 == inflater.settings_hd_table_bufsize_max); CU_ASSERT(16383 == inflater.settings_hd_table_bufsize_max);
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);

View File

@ -5720,7 +5720,7 @@ void test_nghttp2_submit_settings(void) {
nghttp2_frame_settings_free(&ack_frame.settings, mem); nghttp2_frame_settings_free(&ack_frame.settings, mem);
CU_ASSERT(16 * 1024 == session->local_settings.initial_window_size); CU_ASSERT(16 * 1024 == session->local_settings.initial_window_size);
CU_ASSERT(1023 == session->hd_inflater.ctx.hd_table_bufsize_max); CU_ASSERT(111 == session->hd_inflater.ctx.hd_table_bufsize_max);
CU_ASSERT(111 == session->hd_inflater.min_hd_table_bufsize_max); CU_ASSERT(111 == session->hd_inflater.min_hd_table_bufsize_max);
CU_ASSERT(50 == session->local_settings.max_concurrent_streams); CU_ASSERT(50 == session->local_settings.max_concurrent_streams);