diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst index ea7dfb8642a..4990e08b5b4 100644 --- a/doc/admin-guide/files/records.config.en.rst +++ b/doc/admin-guide/files/records.config.en.rst @@ -3568,7 +3568,15 @@ HTTP/2 Configuration :reloadable: The maximum size of the header compression table used to decode header - blocks. + blocks. This value will be advertised as SETTINGS_HEADER_TABLE_SIZE. + +.. ts:cv:: CONFIG proxy.config.http2.header_table_size_limit INT 65536 + :reloadable: + + The maximum size of the header compression table ATS actually use when ATS + encodes headers. Setting 0 means ATS doesn't insert headers into HPACK + Dynamic Table, however, headers still can be encoded as indexable + representations. The upper limit is 65536. .. ts:cv:: CONFIG proxy.config.http2.max_header_list_size INT 131072 :reloadable: diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc index fb7a24392b1..794b6acf41f 100644 --- a/mgmt/RecordsConfig.cc +++ b/mgmt/RecordsConfig.cc @@ -1308,6 +1308,8 @@ static const RecordElement RecordsConfig[] = , {RECT_CONFIG, "proxy.config.http2.min_avg_window_update", RECD_FLOAT, "2560.0", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL} , + {RECT_CONFIG, "proxy.config.http2.header_table_size_limit", RECD_INT, "65536", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL} + , //############ //# diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc index 6e427bbd188..0a97482e5a8 100644 --- a/proxy/http2/HTTP2.cc +++ b/proxy/http2/HTTP2.cc @@ -42,8 +42,8 @@ const unsigned HTTP2_LEN_AUTHORITY = countof(":authority") - 1; const unsigned HTTP2_LEN_PATH = countof(":path") - 1; const unsigned HTTP2_LEN_STATUS = countof(":status") - 1; -static size_t HTTP2_LEN_STATUS_VALUE_STR = 3; -static const int HTTP2_MAX_TABLE_SIZE_LIMIT = 64 * 1024; +static size_t HTTP2_LEN_STATUS_VALUE_STR = 3; +static const uint32_t HTTP2_MAX_TABLE_SIZE_LIMIT = 64 * 1024; // Statistics RecRawStatBlock *http2_rsb; @@ -606,8 +606,9 @@ Http2ErrorCode http2_encode_header_blocks(HTTPHdr *in, uint8_t *out, uint32_t out_len, uint32_t *len_written, HpackHandle &handle, int32_t maximum_table_size) { - // Limit the maximum table size to 64kB, which is the size advertised by major clients - maximum_table_size = std::min(maximum_table_size, HTTP2_MAX_TABLE_SIZE_LIMIT); + // Limit the maximum table size to the configured value or 64kB at maximum, which is the size advertised by major clients + maximum_table_size = + std::min(maximum_table_size, static_cast(std::min(Http2::header_table_size_limit, HTTP2_MAX_TABLE_SIZE_LIMIT))); // Set maximum table size only if it is different from current maximum size if (maximum_table_size == hpack_get_maximum_table_size(handle)) { maximum_table_size = -1; @@ -753,6 +754,7 @@ uint32_t Http2::max_priority_frames_per_minute = 120; float Http2::min_avg_window_update = 2560.0; uint32_t Http2::con_slow_log_threshold = 0; uint32_t Http2::stream_slow_log_threshold = 0; +uint32_t Http2::header_table_size_limit = 65536; void Http2::init() @@ -779,6 +781,7 @@ Http2::init() REC_EstablishStaticConfigFloat(min_avg_window_update, "proxy.config.http2.min_avg_window_update"); REC_EstablishStaticConfigInt32U(con_slow_log_threshold, "proxy.config.http2.connection.slow.log.threshold"); REC_EstablishStaticConfigInt32U(stream_slow_log_threshold, "proxy.config.http2.stream.slow.log.threshold"); + REC_EstablishStaticConfigInt32U(header_table_size_limit, "proxy.config.http2.header_table_size_limit"); // If any settings is broken, ATS should not start ink_release_assert(http2_settings_parameter_is_valid({HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, max_concurrent_streams_in})); diff --git a/proxy/http2/HTTP2.h b/proxy/http2/HTTP2.h index 083eda44e88..6d2fad5019a 100644 --- a/proxy/http2/HTTP2.h +++ b/proxy/http2/HTTP2.h @@ -390,6 +390,7 @@ class Http2 static float min_avg_window_update; static uint32_t con_slow_log_threshold; static uint32_t stream_slow_log_threshold; + static uint32_t header_table_size_limit; static void init(); };