Make QuicSendControlStream send actual value for SETTINGS_QPACK_MAX_TABLE_CAPACITY.
gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 266454276
Change-Id: If56657c5955985ce55aee2bd9d2bc70e9dcb175d
diff --git a/quic/core/http/quic_send_control_stream.cc b/quic/core/http/quic_send_control_stream.cc
index 2924eda..507380d 100644
--- a/quic/core/http/quic_send_control_stream.cc
+++ b/quic/core/http/quic_send_control_stream.cc
@@ -13,9 +13,12 @@
QuicSendControlStream::QuicSendControlStream(
QuicStreamId id,
QuicSession* session,
+ uint64_t qpack_maximum_dynamic_table_capacity,
uint64_t max_inbound_header_list_size)
: QuicStream(id, session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
settings_sent_(false),
+ qpack_maximum_dynamic_table_capacity_(
+ qpack_maximum_dynamic_table_capacity),
max_inbound_header_list_size_(max_inbound_header_list_size) {}
void QuicSendControlStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
@@ -43,7 +46,8 @@
settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] =
max_inbound_header_list_size_;
settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
- kDefaultQpackMaxDynamicTableCapacity;
+ qpack_maximum_dynamic_table_capacity_;
+
std::unique_ptr<char[]> buffer;
QuicByteCount frame_length =
encoder_.SerializeSettingsFrame(settings, &buffer);
diff --git a/quic/core/http/quic_send_control_stream.h b/quic/core/http/quic_send_control_stream.h
index e18fd27..2e8959b 100644
--- a/quic/core/http/quic_send_control_stream.h
+++ b/quic/core/http/quic_send_control_stream.h
@@ -19,9 +19,10 @@
public:
// |session| can't be nullptr, and the ownership is not passed. The stream can
// only be accessed through the session.
- explicit QuicSendControlStream(QuicStreamId id,
- QuicSession* session,
- uint64_t max_inbound_header_list_size);
+ QuicSendControlStream(QuicStreamId id,
+ QuicSession* session,
+ uint64_t qpack_maximum_dynamic_table_capacity,
+ uint64_t max_inbound_header_list_size);
QuicSendControlStream(const QuicSendControlStream&) = delete;
QuicSendControlStream& operator=(const QuicSendControlStream&) = delete;
~QuicSendControlStream() override = default;
@@ -49,7 +50,9 @@
// Track if a settings frame is already sent.
bool settings_sent_;
- // Max inbound header list size that will send as setting.
+ // SETTINGS_QPACK_MAX_TABLE_CAPACITY value to send.
+ const uint64_t qpack_maximum_dynamic_table_capacity_;
+ // SETTINGS_MAX_HEADER_LIST_SIZE value to send.
const uint64_t max_inbound_header_list_size_;
};
diff --git a/quic/core/http/quic_send_control_stream_test.cc b/quic/core/http/quic_send_control_stream_test.cc
index fc64574..49cc0ed 100644
--- a/quic/core/http/quic_send_control_stream_test.cc
+++ b/quic/core/http/quic_send_control_stream_test.cc
@@ -4,6 +4,7 @@
#include "net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.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_test_utils.h"
@@ -11,6 +12,7 @@
namespace test {
namespace {
+
using ::testing::_;
using ::testing::Invoke;
using ::testing::StrictMock;
@@ -53,12 +55,15 @@
perspective(),
SupportedVersions(GetParam().version))),
session_(connection_) {
- session_.Initialize();
- send_control_stream_ = QuicSpdySessionPeer::GetSendControlStream(&session_);
ON_CALL(session_, WritevData(_, _, _, _, _))
.WillByDefault(Invoke(MockQuicSession::ConsumeData));
}
+ void Initialize() {
+ session_.Initialize();
+ send_control_stream_ = QuicSpdySessionPeer::GetSendControlStream(&session_);
+ }
+
Perspective perspective() const { return GetParam().perspective; }
MockQuicConnectionHelper helper_;
@@ -73,19 +78,68 @@
QuicSendControlStreamTest,
::testing::ValuesIn(GetTestParams()));
-TEST_P(QuicSendControlStreamTest, WriteSettingsOnlyForOnce) {
+TEST_P(QuicSendControlStreamTest, WriteSettings) {
if (GetParam().version.handshake_protocol == PROTOCOL_TLS1_3) {
// TODO(nharper, b/112643533): Figure out why this test fails when TLS is
// enabled and fix it.
return;
}
+
+ session_.set_qpack_maximum_dynamic_table_capacity(255);
+ session_.set_max_inbound_header_list_size(1024);
+
+ Initialize();
testing::InSequence s;
- EXPECT_CALL(session_, WritevData(_, _, 1, _, _));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _));
+ std::string expected_write_data = QuicTextUtils::HexDecode(
+ "00" // stream type: control stream
+ "04" // frame type: SETTINGS frame
+ "06" // frame length
+ "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+ "40ff" // 255
+ "06" // SETTINGS_MAX_HEADER_LIST_SIZE
+ "4400"); // 1024
+
+ auto buffer = QuicMakeUnique<char[]>(expected_write_data.size());
+ QuicDataWriter writer(expected_write_data.size(), buffer.get());
+
+ // A lambda to save and consume stream data when QuicSession::WritevData() is
+ // called.
+ auto save_write_data = [&writer](QuicStream* stream, QuicStreamId /*id*/,
+ size_t write_length, QuicStreamOffset offset,
+ StreamSendingState /*state*/) {
+ stream->WriteStreamData(offset, write_length, &writer);
+ return QuicConsumedData(/* bytes_consumed = */ write_length,
+ /* fin_consumed = */ false);
+ };
+
+ EXPECT_CALL(session_, WritevData(send_control_stream_, _, 1, _, _))
+ .WillOnce(Invoke(save_write_data));
+ EXPECT_CALL(session_, WritevData(send_control_stream_, _,
+ expected_write_data.size() - 1, _, _))
+ .WillOnce(Invoke(save_write_data));
+
+ send_control_stream_->MaybeSendSettingsFrame();
+ EXPECT_EQ(expected_write_data,
+ QuicStringPiece(writer.data(), writer.length()));
+}
+
+TEST_P(QuicSendControlStreamTest, WriteSettingsOnlyOnce) {
+ if (GetParam().version.handshake_protocol == PROTOCOL_TLS1_3) {
+ // TODO(nharper, b/112643533): Figure out why this test fails when TLS is
+ // enabled and fix it.
+ return;
+ }
+
+ Initialize();
+ testing::InSequence s;
+
+ EXPECT_CALL(session_, WritevData(send_control_stream_, _, 1, _, _));
+ EXPECT_CALL(session_, WritevData(send_control_stream_, _, _, _, _));
send_control_stream_->MaybeSendSettingsFrame();
- // No data should be written the sencond time SendSettingsFrame() is called.
+ // No data should be written the sencond time MaybeSendSettingsFrame() is
+ // called.
send_control_stream_->MaybeSendSettingsFrame();
}
@@ -96,20 +150,21 @@
return;
}
+ Initialize();
testing::InSequence s;
// The first write will trigger the control stream to write stream type and a
// Settings frame before the Priority frame.
- EXPECT_CALL(session_, WritevData(_, send_control_stream_->id(), _, _, _))
- .Times(3);
+ EXPECT_CALL(session_, WritevData(send_control_stream_, _, _, _, _)).Times(3);
PriorityFrame frame;
send_control_stream_->WritePriority(frame);
- EXPECT_CALL(session_, WritevData(_, send_control_stream_->id(), _, _, _));
+ EXPECT_CALL(session_, WritevData(send_control_stream_, _, _, _, _));
send_control_stream_->WritePriority(frame);
}
TEST_P(QuicSendControlStreamTest, ResetControlStream) {
+ Initialize();
QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
send_control_stream_->id(),
QUIC_STREAM_CANCELLED, 1234);
@@ -118,6 +173,7 @@
}
TEST_P(QuicSendControlStreamTest, ReceiveDataOnSendControlStream) {
+ Initialize();
QuicStreamFrame frame(send_control_stream_->id(), false, 0, "test");
EXPECT_CALL(
*connection_,
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
index 73f63bb..719b3dc 100644
--- a/quic/core/http/quic_spdy_session.cc
+++ b/quic/core/http/quic_spdy_session.cc
@@ -391,9 +391,8 @@
QuicMakeUnique<QpackDecoder>(qpack_maximum_dynamic_table_capacity_,
qpack_maximum_blocked_streams_, this);
MaybeInitializeHttp3UnidirectionalStreams();
- // TODO(b/112770235): Send SETTINGS_QPACK_MAX_TABLE_CAPACITY with value
- // qpack_maximum_dynamic_table_capacity_, and SETTINGS_QPACK_BLOCKED_STREAMS
- // with value qpack_maximum_blocked_streams_.
+ // TODO(b/112770235): Send SETTINGS_QPACK_BLOCKED_STREAMS with value
+ // qpack_maximum_blocked_streams_.
}
spdy_framer_visitor_->set_max_header_list_size(max_inbound_header_list_size_);
@@ -973,7 +972,7 @@
if (!send_control_stream_ && CanOpenNextOutgoingUnidirectionalStream()) {
auto send_control = QuicMakeUnique<QuicSendControlStream>(
GetNextOutgoingUnidirectionalStreamId(), this,
- max_inbound_header_list_size_);
+ qpack_maximum_dynamic_table_capacity_, max_inbound_header_list_size_);
send_control_stream_ = send_control.get();
RegisterStaticStream(std::move(send_control));
}