Add QpackEncoder::SetMaximumDynamicTableCapacity() and SetMaximumBlockedStreams() and call them when corresponding settings are received.
gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 261579634
Change-Id: Ice97e1d26210c622fbbf6c6894901ed6b44c01ca
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
index 3c00c2b..2a83d24 100644
--- a/quic/core/http/quic_spdy_session.cc
+++ b/quic/core/http/quic_spdy_session.cc
@@ -647,7 +647,7 @@
QUIC_DVLOG(1)
<< "SETTINGS_QPACK_MAX_TABLE_CAPACITY received with value "
<< value;
- // TODO(b/112770235): implement.
+ qpack_encoder_->SetMaximumDynamicTableCapacity(value);
break;
case SETTINGS_MAX_HEADER_LIST_SIZE:
QUIC_DVLOG(1) << "SETTINGS_MAX_HEADER_LIST_SIZE received with value "
@@ -657,7 +657,7 @@
case SETTINGS_QPACK_BLOCKED_STREAMS:
QUIC_DVLOG(1) << "SETTINGS_QPACK_BLOCKED_STREAMS received with value "
<< value;
- // TODO(b/112770235): implement.
+ qpack_encoder_->SetMaximumBlockedStreams(value);
break;
case SETTINGS_NUM_PLACEHOLDERS:
QUIC_DVLOG(1) << "SETTINGS_NUM_PLACEHOLDERS received with value "
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index a2b4846..6a0b96e 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -25,6 +25,8 @@
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/qpack_encoder_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/qpack_header_table_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
@@ -2119,7 +2121,7 @@
if (!VersionHasStreamType(transport_version())) {
return;
}
- // Use a arbitrary stream id.
+ // Use an arbitrary stream id.
QuicStreamId stream_id =
GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
char type[] = {kControlStream};
@@ -2130,14 +2132,27 @@
QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
SettingsFrame settings;
- settings.values[3] = 2;
+ settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 512;
settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
+ settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 42;
std::string data = EncodeSettings(settings);
QuicStreamFrame frame(stream_id, false, 1, QuicStringPiece(data));
+ QpackEncoder* qpack_encoder = session_.qpack_encoder();
+ QpackHeaderTable* header_table =
+ QpackEncoderPeer::header_table(qpack_encoder);
+
+ EXPECT_NE(512u,
+ QpackHeaderTablePeer::maximum_dynamic_table_capacity(header_table));
EXPECT_NE(5u, session_.max_outbound_header_list_size());
+ EXPECT_NE(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+
session_.OnStreamFrame(frame);
+
+ EXPECT_EQ(512u,
+ QpackHeaderTablePeer::maximum_dynamic_table_capacity(header_table));
EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+ EXPECT_EQ(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
}
TEST_P(QuicSpdySessionTestServer, ReceiveControlStreamOutOfOrderDelivery) {
diff --git a/quic/core/qpack/qpack_encoder.cc b/quic/core/qpack/qpack_encoder.cc
index 4759e42..1daa572 100644
--- a/quic/core/qpack/qpack_encoder.cc
+++ b/quic/core/qpack/qpack_encoder.cc
@@ -20,7 +20,8 @@
QpackStreamSenderDelegate* encoder_stream_sender_delegate)
: decoder_stream_error_delegate_(decoder_stream_error_delegate),
decoder_stream_receiver_(this),
- encoder_stream_sender_(encoder_stream_sender_delegate) {
+ encoder_stream_sender_(encoder_stream_sender_delegate),
+ maximum_blocked_streams_(0) {
DCHECK(decoder_stream_error_delegate_);
DCHECK(encoder_stream_sender_delegate);
}
@@ -103,6 +104,15 @@
decoder_stream_receiver_.Decode(data);
}
+void QpackEncoder::SetMaximumDynamicTableCapacity(
+ uint64_t maximum_dynamic_table_capacity) {
+ header_table_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
+}
+
+void QpackEncoder::SetMaximumBlockedStreams(uint64_t maximum_blocked_streams) {
+ maximum_blocked_streams_ = maximum_blocked_streams;
+}
+
void QpackEncoder::OnInsertCountIncrement(uint64_t /*increment*/) {
// TODO(bnc): Implement dynamic table management for encoding.
}
diff --git a/quic/core/qpack/qpack_encoder.h b/quic/core/qpack/qpack_encoder.h
index 39600e8..e0bd8d4 100644
--- a/quic/core/qpack/qpack_encoder.h
+++ b/quic/core/qpack/qpack_encoder.h
@@ -20,10 +20,16 @@
class SpdyHeaderBlock;
-}
+} // namespace spdy
namespace quic {
+namespace test {
+
+class QpackEncoderPeer;
+
+} // namespace test
+
// QPACK encoder class. Exactly one instance should exist per QUIC connection.
class QUIC_EXPORT_PRIVATE QpackEncoder
: public QpackDecoderStreamReceiver::Delegate {
@@ -49,6 +55,14 @@
// Decode data received on the decoder stream.
void DecodeDecoderStreamData(QuicStringPiece data);
+ // Set maximum capacity of dynamic table, measured in bytes.
+ // Called when SETTINGS_QPACK_MAX_TABLE_CAPACITY is received.
+ void SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
+
+ // Set maximum number of blocked streams.
+ // Called when SETTINGS_QPACK_BLOCKED_STREAMS is received.
+ void SetMaximumBlockedStreams(uint64_t maximum_blocked_streams);
+
// QpackDecoderStreamReceiver::Delegate implementation
void OnInsertCountIncrement(uint64_t increment) override;
void OnHeaderAcknowledgement(QuicStreamId stream_id) override;
@@ -56,6 +70,8 @@
void OnErrorDetected(QuicStringPiece error_message) override;
private:
+ friend class test::QpackEncoderPeer;
+
// TODO(bnc): Consider moving this class to QpackInstructionEncoder or
// qpack_constants, adding factory methods, one for each instruction, and
// changing QpackInstructionEncoder::Encoder() to take an
@@ -71,6 +87,7 @@
QpackDecoderStreamReceiver decoder_stream_receiver_;
QpackEncoderStreamSender encoder_stream_sender_;
QpackHeaderTable header_table_;
+ uint64_t maximum_blocked_streams_;
};
} // namespace quic
diff --git a/quic/core/qpack/qpack_header_table.h b/quic/core/qpack/qpack_header_table.h
index 4e3b77c..f251894 100644
--- a/quic/core/qpack/qpack_header_table.h
+++ b/quic/core/qpack/qpack_header_table.h
@@ -17,6 +17,12 @@
namespace quic {
+namespace test {
+
+class QpackHeaderTablePeer;
+
+} // namespace test
+
using QpackEntry = spdy::HpackEntry;
// This class manages the QPACK static and dynamic tables. For dynamic entries,
@@ -114,6 +120,8 @@
uint64_t draining_index(float draining_fraction) const;
private:
+ friend class test::QpackHeaderTablePeer;
+
// Evict entries from the dynamic table until table size is less than or equal
// to current value of |dynamic_table_capacity_|.
void EvictDownToCurrentCapacity();
diff --git a/quic/test_tools/qpack_encoder_peer.cc b/quic/test_tools/qpack_encoder_peer.cc
new file mode 100644
index 0000000..4e4bb52
--- /dev/null
+++ b/quic/test_tools/qpack_encoder_peer.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/test_tools/qpack_encoder_peer.h"
+
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h"
+
+namespace quic {
+namespace test {
+
+// static
+QpackHeaderTable* QpackEncoderPeer::header_table(QpackEncoder* encoder) {
+ return &encoder->header_table_;
+}
+
+// static
+uint64_t QpackEncoderPeer::maximum_blocked_streams(
+ const QpackEncoder* encoder) {
+ return encoder->maximum_blocked_streams_;
+}
+
+} // namespace test
+} // namespace quic
diff --git a/quic/test_tools/qpack_encoder_peer.h b/quic/test_tools/qpack_encoder_peer.h
new file mode 100644
index 0000000..b8a8cc7
--- /dev/null
+++ b/quic/test_tools/qpack_encoder_peer.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_ENCODER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QPACK_ENCODER_PEER_H_
+
+#include <cstdint>
+
+namespace quic {
+
+class QpackEncoder;
+class QpackHeaderTable;
+
+namespace test {
+
+class QpackEncoderPeer {
+ public:
+ QpackEncoderPeer() = delete;
+
+ static QpackHeaderTable* header_table(QpackEncoder* encoder);
+ static uint64_t maximum_blocked_streams(const QpackEncoder* encoder);
+};
+
+} // namespace test
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_ENCODER_PEER_H_
diff --git a/quic/test_tools/qpack_header_table_peer.cc b/quic/test_tools/qpack_header_table_peer.cc
new file mode 100644
index 0000000..37c2961
--- /dev/null
+++ b/quic/test_tools/qpack_header_table_peer.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/test_tools/qpack_header_table_peer.h"
+
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h"
+
+namespace quic {
+namespace test {
+
+// static
+uint64_t QpackHeaderTablePeer::maximum_dynamic_table_capacity(
+ const QpackHeaderTable* header_table) {
+ return header_table->maximum_dynamic_table_capacity_;
+}
+
+} // namespace test
+} // namespace quic
diff --git a/quic/test_tools/qpack_header_table_peer.h b/quic/test_tools/qpack_header_table_peer.h
new file mode 100644
index 0000000..a73859c
--- /dev/null
+++ b/quic/test_tools/qpack_header_table_peer.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_HEADER_TABLE_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QPACK_HEADER_TABLE_PEER_H_
+
+#include <cstdint>
+
+namespace quic {
+
+class QpackHeaderTable;
+
+namespace test {
+
+class QpackHeaderTablePeer {
+ public:
+ QpackHeaderTablePeer() = delete;
+
+ static uint64_t maximum_dynamic_table_capacity(
+ const QpackHeaderTable* header_table);
+};
+
+} // namespace test
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_HEADER_TABLE_PEER_H_