Set max_outbound_header_list_size_ when receiving SETTINGS_MAX_HEADER_LIST_SIZE. Also change max_outbound_header_list_size_ default value to numeric_limits::max, because the default value of this setting is unlimited both in Google QUIC [1] and in IETF QUIC [2]. [1] https://httpwg.org/specs/rfc7540.html#SettingValues [2] https://quicwg.org/base-drafts/draft-ietf-quic-http.html#name-defined-settings-parameters gfe-relnote: n/a (max_outbound_header_list_size_ is never used in production) PiperOrigin-RevId: 293124322 Change-Id: I12f4bceef90030905b7c294724936ec9e7c6dd1e
diff --git a/quic/core/http/quic_headers_stream_test.cc b/quic/core/http/quic_headers_stream_test.cc index 35c74fc..aef31b1 100644 --- a/quic/core/http/quic_headers_stream_test.cc +++ b/quic/core/http/quic_headers_stream_test.cc
@@ -646,7 +646,7 @@ stream_frame_.data_length = frame.size(); headers_stream_->OnStreamFrame(stream_frame_); EXPECT_EQ(kTestHeaderTableSize, QuicSpdySessionPeer::GetSpdyFramer(&session_) - .header_encoder_table_size()); + ->header_encoder_table_size()); } TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
diff --git a/quic/core/http/quic_receive_control_stream_test.cc b/quic/core/http/quic_receive_control_stream_test.cc index 489d983..84cc8ed 100644 --- a/quic/core/http/quic_receive_control_stream_test.cc +++ b/quic/core/http/quic_receive_control_stream_test.cc
@@ -5,9 +5,11 @@ #include "net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" +#include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" +#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" @@ -15,6 +17,9 @@ #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { + +class QpackEncoder; + namespace test { namespace { @@ -150,11 +155,24 @@ SettingsFrame settings; settings.values[3] = 2; settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5; + settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 12; + settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 37; std::string data = EncodeSettings(settings); QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data); - EXPECT_NE(5u, session_.max_outbound_header_list_size()); + + QpackEncoder* qpack_encoder = session_.qpack_encoder(); + QpackHeaderTable* header_table = + QpackEncoderPeer::header_table(qpack_encoder); + EXPECT_EQ(std::numeric_limits<size_t>::max(), + session_.max_outbound_header_list_size()); + EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder)); + EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity()); + receive_control_stream_->OnStreamFrame(frame); + EXPECT_EQ(5u, session_.max_outbound_header_list_size()); + EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder)); + EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity()); } // Regression test for https://crbug.com/982648.
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc index 25b1b0a..8215078 100644 --- a/quic/core/http/quic_spdy_session.cc +++ b/quic/core/http/quic_spdy_session.cc
@@ -6,6 +6,7 @@ #include <algorithm> #include <cstdint> +#include <limits> #include <string> #include <utility> @@ -338,7 +339,7 @@ kDefaultQpackMaxDynamicTableCapacity), qpack_maximum_blocked_streams_(kDefaultMaximumBlockedStreams), max_inbound_header_list_size_(kDefaultMaxUncompressedHeaderSize), - max_outbound_header_list_size_(kDefaultMaxUncompressedHeaderSize), + max_outbound_header_list_size_(std::numeric_limits<size_t>::max()), server_push_enabled_(true), stream_id_( QuicUtils::GetInvalidStreamId(connection->transport_version())), @@ -854,12 +855,11 @@ } } break; - // TODO(fayang): Need to support SETTINGS_MAX_HEADER_LIST_SIZE when - // clients are actually sending it. case spdy::SETTINGS_MAX_HEADER_LIST_SIZE: QUIC_DVLOG(1) << ENDPOINT << "SETTINGS_MAX_HEADER_LIST_SIZE received with value " << value; + max_outbound_header_list_size_ = value; break; default: QUIC_DLOG(ERROR) << ENDPOINT << "Unknown setting identifier " << id
diff --git a/quic/core/http/quic_spdy_session.h b/quic/core/http/quic_spdy_session.h index c9bfb27..95f90c9 100644 --- a/quic/core/http/quic_spdy_session.h +++ b/quic/core/http/quic_spdy_session.h
@@ -417,7 +417,7 @@ // The maximum size of a header block that can be sent to the peer. This field // is informed and set by the peer via SETTINGS frame. - // TODO(renjietang): Honor this field when sending headers. + // TODO(b/148616439): Honor this field when sending headers. size_t max_outbound_header_list_size_; // Set during handshake. If true, resources in x-associated-content and link
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc index 6ce22a9..82ac0d1 100644 --- a/quic/core/http/quic_spdy_session_test.cc +++ b/quic/core/http/quic_spdy_session_test.cc
@@ -5,6 +5,7 @@ #include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h" #include <cstdint> +#include <limits> #include <set> #include <string> #include <utility> @@ -14,6 +15,7 @@ #include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/core/http/http_encoder.h" +#include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" #include "net/third_party/quiche/src/quic/core/quic_config.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" @@ -2706,6 +2708,43 @@ session_.OnHttp3GoAway(stream_id); } +TEST_P(QuicSpdySessionTestServer, OnSetting) { + if (VersionUsesHttp3(transport_version())) { + EXPECT_EQ(std::numeric_limits<size_t>::max(), + session_.max_outbound_header_list_size()); + session_.OnSetting(SETTINGS_MAX_HEADER_LIST_SIZE, 5); + EXPECT_EQ(5u, session_.max_outbound_header_list_size()); + + QpackEncoder* qpack_encoder = session_.qpack_encoder(); + EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder)); + session_.OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 12); + EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder)); + + QpackHeaderTable* header_table = + QpackEncoderPeer::header_table(qpack_encoder); + EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity()); + session_.OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 37); + EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity()); + + return; + } + + EXPECT_EQ(std::numeric_limits<size_t>::max(), + session_.max_outbound_header_list_size()); + session_.OnSetting(SETTINGS_MAX_HEADER_LIST_SIZE, 5); + EXPECT_EQ(5u, session_.max_outbound_header_list_size()); + + EXPECT_TRUE(session_.server_push_enabled()); + session_.OnSetting(spdy::SETTINGS_ENABLE_PUSH, 0); + EXPECT_FALSE(session_.server_push_enabled()); + + spdy::HpackEncoder* hpack_encoder = + QuicSpdySessionPeer::GetSpdyFramer(&session_)->GetHpackEncoder(); + EXPECT_EQ(4096u, hpack_encoder->CurrentHeaderTableSizeSetting()); + session_.OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 59); + EXPECT_EQ(59u, hpack_encoder->CurrentHeaderTableSizeSetting()); +} + } // namespace } // namespace test } // namespace quic
diff --git a/quic/test_tools/quic_spdy_session_peer.cc b/quic/test_tools/quic_spdy_session_peer.cc index cad9599..4730ef9 100644 --- a/quic/test_tools/quic_spdy_session_peer.cc +++ b/quic/test_tools/quic_spdy_session_peer.cc
@@ -32,9 +32,8 @@ } // static -const spdy::SpdyFramer& QuicSpdySessionPeer::GetSpdyFramer( - QuicSpdySession* session) { - return session->spdy_framer_; +spdy::SpdyFramer* QuicSpdySessionPeer::GetSpdyFramer(QuicSpdySession* session) { + return &session->spdy_framer_; } void QuicSpdySessionPeer::SetHpackEncoderDebugVisitor(
diff --git a/quic/test_tools/quic_spdy_session_peer.h b/quic/test_tools/quic_spdy_session_peer.h index 1cfd45f..87eda44 100644 --- a/quic/test_tools/quic_spdy_session_peer.h +++ b/quic/test_tools/quic_spdy_session_peer.h
@@ -28,7 +28,7 @@ static QuicHeadersStream* GetHeadersStream(QuicSpdySession* session); static void SetHeadersStream(QuicSpdySession* session, QuicHeadersStream* headers_stream); - static const spdy::SpdyFramer& GetSpdyFramer(QuicSpdySession* session); + static spdy::SpdyFramer* GetSpdyFramer(QuicSpdySession* session); static void SetHpackEncoderDebugVisitor( QuicSpdySession* session, std::unique_ptr<QuicHpackDebugVisitor> visitor);