Include encoder stream bytes in written header size.
Include the total size of dynamic table insertion instructions (including
duplications) sent on the encoder stream triggered by encoding a header list in
the return value of QuicSpdyStream::WriteHeadersImpl().
gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 268203243
Change-Id: I5aacf67592862747670192a598c0aa877cb0c658
diff --git a/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc b/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
index 8527483..996aa70 100644
--- a/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
+++ b/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
@@ -55,7 +55,7 @@
std::string EncodeHeaderList(QuicStreamId stream_id,
const spdy::SpdyHeaderBlock& header_list) {
- return encoder_.EncodeHeaderList(stream_id, header_list);
+ return encoder_.EncodeHeaderList(stream_id, header_list, nullptr);
}
private:
diff --git a/quic/core/qpack/qpack_encoder.cc b/quic/core/qpack/qpack_encoder.cc
index d1736f8..24f12bb 100644
--- a/quic/core/qpack/qpack_encoder.cc
+++ b/quic/core/qpack/qpack_encoder.cc
@@ -87,9 +87,11 @@
QpackEncoder::Instructions QpackEncoder::FirstPassEncode(
const spdy::SpdyHeaderBlock& header_list,
- QpackBlockingManager::IndexSet* referred_indices) {
+ QpackBlockingManager::IndexSet* referred_indices,
+ QuicByteCount* encoder_stream_sent_byte_count) {
Instructions instructions;
instructions.reserve(header_list.size());
+ QuicByteCount sent_byte_count = 0;
// The index of the oldest entry that must not be evicted.
uint64_t smallest_blocking_index =
@@ -144,7 +146,7 @@
header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
std::min(smallest_blocking_index, index))) {
// If allowed, duplicate entry and refer to it.
- encoder_stream_sender_.SendDuplicate(
+ sent_byte_count += encoder_stream_sender_.SendDuplicate(
QpackAbsoluteIndexToEncoderStreamRelativeIndex(
index, header_table_.inserted_entry_count()));
auto entry = header_table_.InsertEntry(name, value);
@@ -174,8 +176,9 @@
header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
smallest_blocking_index)) {
// If allowed, insert entry into dynamic table and refer to it.
- encoder_stream_sender_.SendInsertWithNameReference(is_static, index,
- value);
+ sent_byte_count +=
+ encoder_stream_sender_.SendInsertWithNameReference(
+ is_static, index, value);
auto entry = header_table_.InsertEntry(name, value);
instructions.push_back(EncodeIndexedHeaderField(
/* is_static = */ false, entry->InsertionIndex(),
@@ -198,7 +201,7 @@
header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
std::min(smallest_blocking_index, index))) {
// If allowed, insert entry with name reference and refer to it.
- encoder_stream_sender_.SendInsertWithNameReference(
+ sent_byte_count += encoder_stream_sender_.SendInsertWithNameReference(
is_static,
QpackAbsoluteIndexToEncoderStreamRelativeIndex(
index, header_table_.inserted_entry_count()),
@@ -238,7 +241,9 @@
header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
smallest_blocking_index)) {
// If allowed, insert entry and refer to it.
- encoder_stream_sender_.SendInsertWithoutNameReference(name, value);
+ sent_byte_count +=
+ encoder_stream_sender_.SendInsertWithoutNameReference(name,
+ value);
auto entry = header_table_.InsertEntry(name, value);
instructions.push_back(EncodeIndexedHeaderField(
/* is_static = */ false, entry->InsertionIndex(),
@@ -256,6 +261,12 @@
}
}
+ // Use local |sent_byte_count| variable to avoid branching and dereferencing
+ // each time encoder stream data is sent.
+ if (encoder_stream_sent_byte_count) {
+ *encoder_stream_sent_byte_count = sent_byte_count;
+ }
+
return instructions;
}
@@ -296,13 +307,15 @@
std::string QpackEncoder::EncodeHeaderList(
QuicStreamId stream_id,
- const spdy::SpdyHeaderBlock& header_list) {
+ const spdy::SpdyHeaderBlock& header_list,
+ QuicByteCount* encoder_stream_sent_byte_count) {
// Keep track of all dynamic table indices that this header block refers to so
// that it can be passed to QpackBlockingManager.
QpackBlockingManager::IndexSet referred_indices;
// First pass: encode into |instructions|.
- Instructions instructions = FirstPassEncode(header_list, &referred_indices);
+ Instructions instructions = FirstPassEncode(header_list, &referred_indices,
+ encoder_stream_sent_byte_count);
const uint64_t required_insert_count =
referred_indices.empty()
diff --git a/quic/core/qpack/qpack_encoder.h b/quic/core/qpack/qpack_encoder.h
index 4aa69c1..d64d159 100644
--- a/quic/core/qpack/qpack_encoder.h
+++ b/quic/core/qpack/qpack_encoder.h
@@ -49,9 +49,12 @@
QpackEncoder(DecoderStreamErrorDelegate* decoder_stream_error_delegate);
~QpackEncoder() override;
- // Encode a header list.
+ // Encode a header list. If |encoder_stream_sent_byte_count| is not null,
+ // |*encoder_stream_sent_byte_count| will be set to the number of bytes sent
+ // on the encoder stream to insert dynamic table entries.
std::string EncodeHeaderList(QuicStreamId stream_id,
- const spdy::SpdyHeaderBlock& header_list);
+ const spdy::SpdyHeaderBlock& header_list,
+ QuicByteCount* encoder_stream_sent_byte_count);
// Set maximum dynamic table capacity to |maximum_dynamic_table_capacity|,
// measured in bytes. Called when SETTINGS_QPACK_MAX_TABLE_CAPACITY is
@@ -121,13 +124,16 @@
// |*header_list| as a reference to an existing entry, the name of an existing
// entry with a literal value, or a literal name and value pair. Sends
// necessary instructions on the encoder stream. Records absolute indices of
- // referred dynamic table entries in |*referred_indices|. Returns list of
- // header field representations, with all dynamic table entries referred to
- // with absolute indices. Returned Instructions object may have
- // QuicStringPieces pointing to strings owned by |*header_list|.
- Instructions FirstPassEncode(
- const spdy::SpdyHeaderBlock& header_list,
- QpackBlockingManager::IndexSet* referred_indices);
+ // referred dynamic table entries in |*referred_indices|. If
+ // |encoder_stream_sent_byte_count| is not null, then sets
+ // |*encoder_stream_sent_byte_count| to the number of bytes sent on the
+ // encoder stream to insert dynamic table entries. Returns list of header
+ // field representations, with all dynamic table entries referred to with
+ // absolute indices. Returned Instructions object may have QuicStringPieces
+ // pointing to strings owned by |*header_list|.
+ Instructions FirstPassEncode(const spdy::SpdyHeaderBlock& header_list,
+ QpackBlockingManager::IndexSet* referred_indices,
+ QuicByteCount* encoder_stream_sent_byte_count);
// Performs second pass of two-pass encoding: serializes representations
// generated in first pass, transforming absolute indices of dynamic table
diff --git a/quic/core/qpack/qpack_encoder_stream_sender.cc b/quic/core/qpack/qpack_encoder_stream_sender.cc
index e6209fd..533e3a1 100644
--- a/quic/core/qpack/qpack_encoder_stream_sender.cc
+++ b/quic/core/qpack/qpack_encoder_stream_sender.cc
@@ -15,7 +15,7 @@
QpackEncoderStreamSender::QpackEncoderStreamSender() : delegate_(nullptr) {}
-void QpackEncoderStreamSender::SendInsertWithNameReference(
+QuicByteCount QpackEncoderStreamSender::SendInsertWithNameReference(
bool is_static,
uint64_t name_index,
QuicStringPiece value) {
@@ -27,9 +27,10 @@
instruction_encoder_.Encode(InsertWithNameReferenceInstruction(), values_,
&output);
delegate_->WriteStreamData(output);
+ return output.size();
}
-void QpackEncoderStreamSender::SendInsertWithoutNameReference(
+QuicByteCount QpackEncoderStreamSender::SendInsertWithoutNameReference(
QuicStringPiece name,
QuicStringPiece value) {
values_.name = name;
@@ -39,23 +40,27 @@
instruction_encoder_.Encode(InsertWithoutNameReferenceInstruction(), values_,
&output);
delegate_->WriteStreamData(output);
+ return output.size();
}
-void QpackEncoderStreamSender::SendDuplicate(uint64_t index) {
+QuicByteCount QpackEncoderStreamSender::SendDuplicate(uint64_t index) {
values_.varint = index;
std::string output;
instruction_encoder_.Encode(DuplicateInstruction(), values_, &output);
delegate_->WriteStreamData(output);
+ return output.size();
}
-void QpackEncoderStreamSender::SendSetDynamicTableCapacity(uint64_t capacity) {
+QuicByteCount QpackEncoderStreamSender::SendSetDynamicTableCapacity(
+ uint64_t capacity) {
values_.varint = capacity;
std::string output;
instruction_encoder_.Encode(SetDynamicTableCapacityInstruction(), values_,
&output);
delegate_->WriteStreamData(output);
+ return output.size();
}
} // namespace quic
diff --git a/quic/core/qpack/qpack_encoder_stream_sender.h b/quic/core/qpack/qpack_encoder_stream_sender.h
index 3c410d5..c8c7717 100644
--- a/quic/core/qpack/qpack_encoder_stream_sender.h
+++ b/quic/core/qpack/qpack_encoder_stream_sender.h
@@ -9,6 +9,7 @@
#include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
@@ -25,16 +26,16 @@
// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
// 5.2.1. Insert With Name Reference
- void SendInsertWithNameReference(bool is_static,
- uint64_t name_index,
- QuicStringPiece value);
+ QuicByteCount SendInsertWithNameReference(bool is_static,
+ uint64_t name_index,
+ QuicStringPiece value);
// 5.2.2. Insert Without Name Reference
- void SendInsertWithoutNameReference(QuicStringPiece name,
- QuicStringPiece value);
+ QuicByteCount SendInsertWithoutNameReference(QuicStringPiece name,
+ QuicStringPiece value);
// 5.2.3. Duplicate
- void SendDuplicate(uint64_t index);
+ QuicByteCount SendDuplicate(uint64_t index);
// 5.2.4. Set Dynamic Table Capacity
- void SendSetDynamicTableCapacity(uint64_t capacity);
+ QuicByteCount SendSetDynamicTableCapacity(uint64_t capacity);
// delegate must be set if dynamic table capacity is not zero.
void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
diff --git a/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/quic/core/qpack/qpack_encoder_stream_sender_test.cc
index 4a15d1f..dcfd5bd 100644
--- a/quic/core/qpack/qpack_encoder_stream_sender_test.cc
+++ b/quic/core/qpack/qpack_encoder_stream_sender_test.cc
@@ -28,80 +28,93 @@
TEST_F(QpackEncoderStreamSenderTest, InsertWithNameReference) {
// Static, index fits in prefix, empty value.
- EXPECT_CALL(delegate_, WriteStreamData(Eq(QuicTextUtils::HexDecode("c500"))));
- stream_.SendInsertWithNameReference(true, 5, "");
+ std::string expected_encoded_data = QuicTextUtils::HexDecode("c500");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendInsertWithNameReference(true, 5, ""));
// Static, index fits in prefix, Huffman encoded value.
- EXPECT_CALL(delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode("c28294e7"))));
- stream_.SendInsertWithNameReference(true, 2, "foo");
+ expected_encoded_data = QuicTextUtils::HexDecode("c28294e7");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendInsertWithNameReference(true, 2, "foo"));
// Not static, index does not fit in prefix, not Huffman encoded value.
- EXPECT_CALL(delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode("bf4a03626172"))));
- stream_.SendInsertWithNameReference(false, 137, "bar");
+ expected_encoded_data = QuicTextUtils::HexDecode("bf4a03626172");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendInsertWithNameReference(false, 137, "bar"));
// Value length does not fit in prefix.
// 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
- EXPECT_CALL(
- delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"))));
- stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z'));
+ expected_encoded_data = QuicTextUtils::HexDecode(
+ "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+ "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+ "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+ "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(
+ expected_encoded_data.size(),
+ stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z')));
}
TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) {
// Empty name and value.
- EXPECT_CALL(delegate_, WriteStreamData(Eq(QuicTextUtils::HexDecode("4000"))));
- stream_.SendInsertWithoutNameReference("", "");
+ std::string expected_encoded_data = QuicTextUtils::HexDecode("4000");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendInsertWithoutNameReference("", ""));
// Huffman encoded short strings.
- EXPECT_CALL(delegate_, WriteStreamData(
- Eq(QuicTextUtils::HexDecode("4362617203626172"))));
- stream_.SendInsertWithoutNameReference("bar", "bar");
+ expected_encoded_data = QuicTextUtils::HexDecode("4362617203626172");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendInsertWithoutNameReference("bar", "bar"));
// Not Huffman encoded short strings.
- EXPECT_CALL(delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode("6294e78294e7"))));
- stream_.SendInsertWithoutNameReference("foo", "foo");
+ expected_encoded_data = QuicTextUtils::HexDecode("6294e78294e7");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendInsertWithoutNameReference("foo", "foo"));
// Not Huffman encoded long strings; length does not fit on prefix.
// 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
- EXPECT_CALL(
- delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f"
- "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
- "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"))));
- stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
- std::string(127, 'Z'));
+ expected_encoded_data = QuicTextUtils::HexDecode(
+ "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f"
+ "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+ "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+ "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+ "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
+ std::string(127, 'Z')));
}
TEST_F(QpackEncoderStreamSenderTest, Duplicate) {
// Small index fits in prefix.
- EXPECT_CALL(delegate_, WriteStreamData(Eq(QuicTextUtils::HexDecode("11"))));
- stream_.SendDuplicate(17);
+ std::string expected_encoded_data = QuicTextUtils::HexDecode("11");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(), stream_.SendDuplicate(17));
// Large index requires two extension bytes.
- EXPECT_CALL(delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode("1fd503"))));
- stream_.SendDuplicate(500);
+ expected_encoded_data = QuicTextUtils::HexDecode("1fd503");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(), stream_.SendDuplicate(500));
}
TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) {
// Small capacity fits in prefix.
- EXPECT_CALL(delegate_, WriteStreamData(Eq(QuicTextUtils::HexDecode("31"))));
- stream_.SendSetDynamicTableCapacity(17);
+ std::string expected_encoded_data = QuicTextUtils::HexDecode("31");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendSetDynamicTableCapacity(17));
// Large capacity requires two extension bytes.
- EXPECT_CALL(delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode("3fd503"))));
- stream_.SendSetDynamicTableCapacity(500);
+ expected_encoded_data = QuicTextUtils::HexDecode("3fd503");
+ EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+ EXPECT_EQ(expected_encoded_data.size(),
+ stream_.SendSetDynamicTableCapacity(500));
}
} // namespace
diff --git a/quic/core/qpack/qpack_encoder_test.cc b/quic/core/qpack/qpack_encoder_test.cc
index 0da6f3e..f230942 100644
--- a/quic/core/qpack/qpack_encoder_test.cc
+++ b/quic/core/qpack/qpack_encoder_test.cc
@@ -25,7 +25,9 @@
class QpackEncoderTest : public QuicTest {
protected:
- QpackEncoderTest() : encoder_(&decoder_stream_error_delegate_) {
+ QpackEncoderTest()
+ : encoder_(&decoder_stream_error_delegate_),
+ encoder_stream_sent_byte_count_(0) {
encoder_.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
encoder_.SetMaximumBlockedStreams(1);
}
@@ -33,12 +35,14 @@
~QpackEncoderTest() override = default;
std::string Encode(const spdy::SpdyHeaderBlock& header_list) {
- return encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list);
+ return encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list,
+ &encoder_stream_sent_byte_count_);
}
StrictMock<MockDecoderStreamErrorDelegate> decoder_stream_error_delegate_;
StrictMock<MockQpackStreamSenderDelegate> encoder_stream_sender_delegate_;
QpackEncoder encoder_;
+ QuicByteCount encoder_stream_sent_byte_count_;
};
TEST_F(QpackEncoderTest, Empty) {
@@ -199,24 +203,32 @@
header_list["cookie"] = "baz"; // name matches static entry
// Insert three entries into the dynamic table.
+ std::string insert_entry1 = QuicTextUtils::HexDecode(
+ "62" // insert without name reference
+ "94e7" // Huffman-encoded name "foo"
+ "03626172"); // value "bar"
EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "62" // insert without name reference
- "94e7" // Huffman-encoded name "foo"
- "03626172")))); // value "bar"
+ WriteStreamData(Eq(insert_entry1)));
+
+ std::string insert_entry2 = QuicTextUtils::HexDecode(
+ "80" // insert with name reference, dynamic index 0
+ "0362617a"); // value "baz"
EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "80" // insert with name reference, dynamic index 0
- "0362617a")))); // value "baz"
+ WriteStreamData(Eq(insert_entry2)));
+
+ std::string insert_entry3 = QuicTextUtils::HexDecode(
+ "c5" // insert with name reference, static index 5
+ "0362617a"); // value "baz"
EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "c5" // insert with name reference, static index 5
- "0362617a")))); // value "baz"
+ WriteStreamData(Eq(insert_entry3)));
EXPECT_EQ(QuicTextUtils::HexDecode(
"0400" // prefix
"828180"), // dynamic entries with relative index 0, 1, and 2
Encode(header_list));
+
+ EXPECT_EQ(insert_entry1.size() + insert_entry2.size() + insert_entry3.size(),
+ encoder_stream_sent_byte_count_);
}
// There is no room in the dynamic table after inserting the first entry.
@@ -237,11 +249,12 @@
header_list["bar"] = "baz"; // no match
// Insert one entry into the dynamic table.
+ std::string insert_entry = QuicTextUtils::HexDecode(
+ "62" // insert without name reference
+ "94e7" // Huffman-encoded name "foo"
+ "03626172"); // value "bar"
EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "62" // insert without name reference
- "94e7" // Huffman-encoded name "foo"
- "03626172")))); // value "bar"
+ WriteStreamData(Eq(insert_entry)));
EXPECT_EQ(QuicTextUtils::HexDecode("0200" // prefix
"80" // dynamic entry 0
@@ -252,6 +265,8 @@
"23626172" // literal name "bar"
"0362617a"), // with literal value "baz"
Encode(header_list));
+
+ EXPECT_EQ(insert_entry.size(), encoder_stream_sent_byte_count_);
}
TEST_F(QpackEncoderTest, BlockedStream) {
@@ -267,15 +282,18 @@
header_list1["foo"] = "bar";
// Insert one entry into the dynamic table.
+ std::string insert_entry1 = QuicTextUtils::HexDecode(
+ "62" // insert without name reference
+ "94e7" // Huffman-encoded name "foo"
+ "03626172"); // value "bar"
EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "62" // insert without name reference
- "94e7" // Huffman-encoded name "foo"
- "03626172")))); // value "bar"
+ WriteStreamData(Eq(insert_entry1)));
EXPECT_EQ(QuicTextUtils::HexDecode("0200" // prefix
"80"), // dynamic entry 0
- encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list1));
+ encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list1,
+ &encoder_stream_sent_byte_count_));
+ EXPECT_EQ(insert_entry1.size(), encoder_stream_sent_byte_count_);
// Stream 1 is blocked. Stream 2 is not allowed to block.
spdy::SpdyHeaderBlock header_list2;
@@ -294,29 +312,40 @@
"0362617a" // with literal value "baz"
"23626172" // literal name "bar"
"0362617a"), // with literal value "baz"
- encoder_.EncodeHeaderList(/* stream_id = */ 2, header_list2));
+ encoder_.EncodeHeaderList(/* stream_id = */ 2, header_list2,
+ &encoder_stream_sent_byte_count_));
+ EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
// Peer acknowledges receipt of one dynamic table entry.
// Stream 1 is no longer blocked.
encoder_.OnInsertCountIncrement(1);
// Insert three entries into the dynamic table.
+ std::string insert_entry2 = QuicTextUtils::HexDecode(
+ "80" // insert with name reference, dynamic index 0
+ "0362617a"); // value "baz"
EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "80" // insert with name reference, dynamic index 0
- "0362617a")))); // value "baz"
+ WriteStreamData(Eq(insert_entry2)));
+
+ std::string insert_entry3 = QuicTextUtils::HexDecode(
+ "c5" // insert with name reference, static index 5
+ "0362617a"); // value "baz"
EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "c5" // insert with name reference, static index 5
- "0362617a")))); // value "baz"
+ WriteStreamData(Eq(insert_entry3)));
+
+ std::string insert_entry4 = QuicTextUtils::HexDecode(
+ "43" // insert without name reference
+ "626172" // name "bar"
+ "0362617a"); // value "baz"
EXPECT_CALL(encoder_stream_sender_delegate_,
- WriteStreamData(Eq(QuicTextUtils::HexDecode(
- "43" // insert without name reference
- "626172" // name "bar"
- "0362617a")))); // value "baz"
- EXPECT_EQ(QuicTextUtils::HexDecode("0500" // prefix
+ WriteStreamData(Eq(insert_entry4)));
+
+ EXPECT_EQ(QuicTextUtils::HexDecode("0500" // prefix
"83828180"), // dynamic entries
- encoder_.EncodeHeaderList(/* stream_id = */ 3, header_list2));
+ encoder_.EncodeHeaderList(/* stream_id = */ 3, header_list2,
+ &encoder_stream_sent_byte_count_));
+ EXPECT_EQ(insert_entry2.size() + insert_entry3.size() + insert_entry4.size(),
+ encoder_stream_sent_byte_count_);
// Stream 3 is blocked. Stream 4 is not allowed to block, but it can
// reference already acknowledged dynamic entry 0.
@@ -328,7 +357,9 @@
"0362617a" // with literal value "baz"
"23626172" // literal name "bar"
"0362617a"), // with literal value "baz"
- encoder_.EncodeHeaderList(/* stream_id = */ 4, header_list2));
+ encoder_.EncodeHeaderList(/* stream_id = */ 4, header_list2,
+ &encoder_stream_sent_byte_count_));
+ EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
// Peer acknowledges receipt of two more dynamic table entries.
// Stream 3 is still blocked.
@@ -340,7 +371,9 @@
"828180" // dynamic entries
"23626172" // literal name "bar"
"0362617a"), // with literal value "baz"
- encoder_.EncodeHeaderList(/* stream_id = */ 5, header_list2));
+ encoder_.EncodeHeaderList(/* stream_id = */ 5, header_list2,
+ &encoder_stream_sent_byte_count_));
+ EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
// Peer acknowledges decoding header block on stream 3.
// Stream 3 is not blocked any longer.
@@ -348,7 +381,9 @@
EXPECT_EQ(QuicTextUtils::HexDecode("0500" // prefix
"83828180"), // dynamic entries
- encoder_.EncodeHeaderList(/* stream_id = */ 6, header_list2));
+ encoder_.EncodeHeaderList(/* stream_id = */ 6, header_list2,
+ &encoder_stream_sent_byte_count_));
+ EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
}
TEST_F(QpackEncoderTest, Draining) {
diff --git a/quic/core/qpack/qpack_round_trip_test.cc b/quic/core/qpack/qpack_round_trip_test.cc
index 9441b82..beff68e 100644
--- a/quic/core/qpack/qpack_round_trip_test.cc
+++ b/quic/core/qpack/qpack_round_trip_test.cc
@@ -32,7 +32,7 @@
QpackEncoder encoder(&decoder_stream_error_delegate);
encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate);
std::string encoded_header_block =
- encoder.EncodeHeaderList(/* stream_id = */ 1, header_list);
+ encoder.EncodeHeaderList(/* stream_id = */ 1, header_list, nullptr);
TestHeadersHandler handler;
NoopEncoderStreamErrorDelegate encoder_stream_error_delegate;