summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/http
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quic/core/http')
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc100
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc38
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h17
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h9
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc32
11 files changed, 175 insertions, 72 deletions
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc
index 29e6377280b..cad9cacb022 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc
@@ -485,8 +485,7 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
}
}
- void AddToCache(absl::string_view path,
- int response_code,
+ void AddToCache(absl::string_view path, int response_code,
absl::string_view body) {
memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
response_code, body);
@@ -553,12 +552,6 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
EXPECT_EQ(0u, server_stats.packets_lost);
}
EXPECT_EQ(0u, server_stats.packets_discarded);
- if (!GetQuicReloadableFlag(
- quic_ignore_user_agent_transport_parameter)) {
- EXPECT_EQ(
- server_session->user_agent_id().value_or("MissingUserAgent"),
- kTestUserAgentId);
- }
} else {
ADD_FAILURE() << "Missing server connection";
}
@@ -657,16 +650,14 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
}
bool SendSynchronousRequestAndCheckResponse(
- QuicTestClient* client,
- const std::string& request,
+ QuicTestClient* client, const std::string& request,
const std::string& expected_response) {
std::string received_response = client->SendSynchronousRequest(request);
return CheckResponse(client, received_response, expected_response);
}
bool SendSynchronousRequestAndCheckResponse(
- const std::string& request,
- const std::string& expected_response) {
+ const std::string& request, const std::string& expected_response) {
return SendSynchronousRequestAndCheckResponse(client_.get(), request,
expected_response);
}
@@ -844,8 +835,7 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
};
// Run all end to end tests with all supported versions.
-INSTANTIATE_TEST_SUITE_P(EndToEndTests,
- EndToEndTest,
+INSTANTIATE_TEST_SUITE_P(EndToEndTests, EndToEndTest,
::testing::ValuesIn(GetTestParams()),
::testing::PrintToStringParamName());
@@ -3210,8 +3200,7 @@ TEST_P(EndToEndTest, ConnectionMigrationNewTokenForNewIp) {
class DuplicatePacketWithSpoofedSelfAddressWriter
: public QuicPacketWriterWrapper {
public:
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
@@ -3246,7 +3235,8 @@ TEST_P(EndToEndTest, ClientAddressSpoofedForSomePeriod) {
ASSERT_TRUE(QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
GetClientConnection()));
- QuicIpAddress real_host = TestLoopback(1);
+ QuicIpAddress real_host =
+ client_->client()->session()->connection()->self_address().host();
ASSERT_TRUE(client_->MigrateSocket(real_host));
SendSynchronousFooRequestAndCheckResponse();
EXPECT_EQ(
@@ -4384,13 +4374,10 @@ TEST_P(EndToEndTest, CanceledStreamDoesNotBecomeZombie) {
class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
public:
ServerStreamWithErrorResponseBody(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend,
std::string response_body)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend),
response_body_(std::move(response_body)) {}
@@ -4419,8 +4406,7 @@ class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
~StreamWithErrorFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamWithErrorResponseBody(
id, session, quic_simple_server_backend, response_body_);
@@ -4433,12 +4419,9 @@ class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
// A test server stream that drops all received body.
class ServerStreamThatDropsBody : public QuicSimpleServerStream {
public:
- ServerStreamThatDropsBody(QuicStreamId id,
- QuicSpdySession* session,
+ ServerStreamThatDropsBody(QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend) {}
~ServerStreamThatDropsBody() override = default;
@@ -4480,8 +4463,7 @@ class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
~ServerStreamThatDropsBodyFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamThatDropsBody(id, session,
quic_simple_server_backend);
@@ -4492,13 +4474,9 @@ class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
public:
ServerStreamThatSendsHugeResponse(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend,
- int64_t body_bytes)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ QuicStreamId id, QuicSpdySession* session,
+ QuicSimpleServerBackend* quic_simple_server_backend, int64_t body_bytes)
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend),
body_bytes_(body_bytes) {}
@@ -4528,8 +4506,7 @@ class ServerStreamThatSendsHugeResponseFactory
~ServerStreamThatSendsHugeResponseFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamThatSendsHugeResponse(
id, session, quic_simple_server_backend, body_bytes_);
@@ -5254,8 +5231,7 @@ TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
// called.
class PacketHoldingWriter : public QuicPacketWriterWrapper {
public:
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
@@ -5533,11 +5509,13 @@ TEST_P(EndToEndPacketReorderingTest, MigrateAgainAfterPathValidationFailure) {
}
TEST_P(EndToEndPacketReorderingTest,
- MigrateAgainAfterPathValidationFailureWithNonZeroClientConnectionId) {
+ MigrateAgainAfterPathValidationFailureWithNonZeroClientCid) {
if (!version_.SupportsClientConnectionIds()) {
ASSERT_TRUE(Initialize());
return;
}
+ SetQuicReloadableFlag(quic_retire_cid_on_reverse_path_validation_failure,
+ true);
override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
ASSERT_TRUE(Initialize());
if (!GetClientConnection()->connection_migration_use_new_cid()) {
@@ -5707,8 +5685,7 @@ class BadShloPacketWriter : public QuicPacketWriterWrapper {
: error_returned_(false), version_(version) {}
~BadShloPacketWriter() override {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
quic::PerPacketOptions* options) override {
@@ -5725,6 +5702,9 @@ class BadShloPacketWriter : public QuicPacketWriterWrapper {
}
bool TypeByteIsServerHello(uint8_t type_byte) {
+ if (version_.UsesV2PacketTypes()) {
+ return ((type_byte & 0x30) >> 4) == 3;
+ }
if (version_.UsesQuicCrypto()) {
// ENCRYPTION_ZERO_RTT packet.
return ((type_byte & 0x30) >> 4) == 1;
@@ -5781,21 +5761,23 @@ TEST_P(EndToEndTest, ConnectionCloseBeforeHandshakeComplete) {
class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
public:
- BadShloPacketWriter2() : error_returned_(false) {}
+ BadShloPacketWriter2(ParsedQuicVersion version)
+ : error_returned_(false), version_(version) {}
~BadShloPacketWriter2() override {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
quic::PerPacketOptions* options) override {
const uint8_t type_byte = buffer[0];
- if ((type_byte & FLAGS_LONG_HEADER) &&
- (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
- QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
- if (!error_returned_ && !(type_byte & FLAGS_LONG_HEADER)) {
+
+ if (type_byte & FLAGS_LONG_HEADER) {
+ if (((type_byte & 0x30 >> 4) == (version_.UsesV2PacketTypes() ? 2 : 1)) ||
+ ((type_byte & 0x7F) == 0x7C)) {
+ QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
+ return WriteResult(WRITE_STATUS_OK, buf_len);
+ }
+ } else if (!error_returned_) {
QUIC_DVLOG(1) << "Return write error for short header packet";
error_returned_ = true;
return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
@@ -5806,6 +5788,7 @@ class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
private:
bool error_returned_;
+ ParsedQuicVersion version_;
};
TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
@@ -5836,7 +5819,7 @@ TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
dispatcher,
// This causes the all server sent ZERO_RTT_PROTECTED packets to be
// dropped, and first short header packet causes write error.
- new BadShloPacketWriter2());
+ new BadShloPacketWriter2(version_));
server_thread_->Resume();
client_.reset(CreateQuicClient(client_writer_));
EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
@@ -5913,10 +5896,6 @@ TEST_P(EndToEndTest, CustomTransportParameters) {
QuicConfig* server_config = nullptr;
if (server_session != nullptr) {
server_config = server_session->config();
- if (!GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter)) {
- EXPECT_EQ(server_session->user_agent_id().value_or("MissingUserAgent"),
- kTestUserAgentId);
- }
} else {
ADD_FAILURE() << "Missing server session";
}
@@ -6025,8 +6004,7 @@ class CopyingPacketWriter : public PacketDroppingTestWriter {
public:
explicit CopyingPacketWriter(int num_packets_to_copy)
: num_packets_to_copy_(num_packets_to_copy) {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc
index 42fef63c978..3a44f79a1d1 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc
@@ -50,7 +50,6 @@ using spdy::SpdyGoAwayIR;
using spdy::SpdyHeaderBlock;
using spdy::SpdyHeadersHandlerInterface;
using spdy::SpdyHeadersIR;
-using spdy::SpdyKnownSettingsId;
using spdy::SpdyPingId;
using spdy::SpdyPingIR;
using spdy::SpdyPriority;
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc
index 30c4178feca..2d144d2465c 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc
@@ -45,7 +45,6 @@ using testing::_;
using testing::StrictMock;
using testing::AtLeast;
-using testing::Return;
namespace quic {
namespace test {
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc
index 5a859271e6e..cfc47296417 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc
@@ -43,7 +43,6 @@ using spdy::SpdyFrameType;
using spdy::SpdyHeaderBlock;
using spdy::SpdyHeadersHandlerInterface;
using spdy::SpdyHeadersIR;
-using spdy::SpdyKnownSettingsId;
using spdy::SpdyPingId;
using spdy::SpdyPriority;
using spdy::SpdyPriorityIR;
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc
index 5db1aab4e91..45506211f9d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc
@@ -153,7 +153,6 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
}
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> /*application_state*/) override {}
- bool KeyUpdateSupportedLocally() const override { return false; }
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override {
return nullptr;
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc
index 8147ce00dcc..5317137d7e0 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc
@@ -185,6 +185,8 @@ QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
headers_payload_length_(0),
trailers_decompressed_(false),
trailers_consumed_(false),
+ qpack_decoded_headers_accumulator_reset_reason_(
+ QpackDecodedHeadersAccumulatorResetReason::kUnSet),
http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
decoder_(http_decoder_visitor_.get(),
HttpDecoderOptionsForBidiStream(spdy_session)),
@@ -225,6 +227,8 @@ QuicSpdyStream::QuicSpdyStream(PendingStream* pending,
headers_payload_length_(0),
trailers_decompressed_(false),
trailers_consumed_(false),
+ qpack_decoded_headers_accumulator_reset_reason_(
+ QpackDecodedHeadersAccumulatorResetReason::kUnSet),
http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
decoder_(http_decoder_visitor_.get()),
sequencer_offset_(sequencer()->NumBytesConsumed()),
@@ -563,6 +567,8 @@ void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
bool header_list_size_limit_exceeded) {
header_list_size_limit_exceeded_ = header_list_size_limit_exceeded;
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeadersDecoded;
QuicSpdySession::LogHeaderCompressionRatioHistogram(
/* using_qpack = */ true,
@@ -592,6 +598,8 @@ void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
void QuicSpdyStream::OnHeaderDecodingError(QuicErrorCode error_code,
absl::string_view error_message) {
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeaderDecodingError;
std::string connection_close_error_message = absl::StrCat(
"Error decoding ", headers_decompressed_ ? "trailers" : "headers",
@@ -756,6 +764,8 @@ void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset1;
}
}
@@ -769,6 +779,8 @@ void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
if (!fin_received() && spdy_session_->qpack_decoder()) {
spdy_session_->qpack_decoder()->OnStreamReset(id());
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset2;
}
QuicStream::OnStreamReset(frame);
@@ -791,6 +803,8 @@ void QuicSpdyStream::ResetWithError(QuicResetStreamError error) {
if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInResetWithError;
}
}
@@ -893,6 +907,8 @@ void QuicSpdyStream::OnClose() {
QuicStream::OnClose();
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnClose;
if (visitor_) {
Visitor* visitor = visitor_;
@@ -1088,7 +1104,14 @@ bool QuicSpdyStream::OnHeadersFrameStart(QuicByteCount header_length,
bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) {
QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QUICHE_DCHECK(qpack_decoded_headers_accumulator_);
+
+ if (!qpack_decoded_headers_accumulator_) {
+ QUIC_BUG(b215142466_OnHeadersFramePayload)
+ << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
+ OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
+ "qpack_decoded_headers_accumulator_ is nullptr");
+ return false;
+ }
qpack_decoded_headers_accumulator_->Decode(payload);
@@ -1103,7 +1126,14 @@ bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) {
bool QuicSpdyStream::OnHeadersFrameEnd() {
QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QUICHE_DCHECK(qpack_decoded_headers_accumulator_);
+
+ if (!qpack_decoded_headers_accumulator_) {
+ QUIC_BUG(b215142466_OnHeadersFrameEnd)
+ << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
+ OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
+ "qpack_decoded_headers_accumulator_ is nullptr");
+ return false;
+ }
qpack_decoded_headers_accumulator_->EndHeaderBlock();
@@ -1244,9 +1274,7 @@ void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
std::string protocol;
absl::optional<QuicDatagramStreamId> flow_id;
bool version_indicated = false;
- for (const auto& header : header_list_) {
- const std::string& header_name = header.first;
- const std::string& header_value = header.second;
+ for (const auto& [header_name, header_value] : header_list_) {
if (header_name == ":method") {
if (!method.empty() || header_value.empty()) {
return;
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h
index 8ec56d58f06..14ac2f2f585 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h
@@ -391,6 +391,20 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream
WebTransportStreamAdapter adapter;
};
+ // Reason codes for `qpack_decoded_headers_accumulator_` being nullptr.
+ enum class QpackDecodedHeadersAccumulatorResetReason {
+ // `qpack_decoded_headers_accumulator_` was default constructed to nullptr.
+ kUnSet = 0,
+ // `qpack_decoded_headers_accumulator_` was reset in the corresponding
+ // method.
+ kResetInOnHeadersDecoded = 1,
+ kResetInOnHeaderDecodingError = 2,
+ kResetInOnStreamReset1 = 3,
+ kResetInOnStreamReset2 = 4,
+ kResetInResetWithError = 5,
+ kResetInOnClose = 6,
+ };
+
// Called by HttpDecoderVisitor.
bool OnDataFrameStart(QuicByteCount header_length,
QuicByteCount payload_length);
@@ -462,6 +476,9 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream
// Headers accumulator for decoding HEADERS frame payload.
std::unique_ptr<QpackDecodedHeadersAccumulator>
qpack_decoded_headers_accumulator_;
+ // Reason for `qpack_decoded_headers_accumulator_` being nullptr.
+ QpackDecodedHeadersAccumulatorResetReason
+ qpack_decoded_headers_accumulator_reset_reason_;
// Visitor of the HttpDecoder.
std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
// HttpDecoder for processing raw incoming stream frames.
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc
index 3bad6efe6ee..c8146e1c5a1 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc
@@ -136,7 +136,6 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
}
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> /*application_state*/) override {}
- bool KeyUpdateSupportedLocally() const override { return true; }
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override {
return nullptr;
@@ -3424,6 +3423,32 @@ TEST_P(QuicSpdyStreamTest, GetMaxDatagramSize) {
EXPECT_EQ(size - 1, size_with_context);
}
+TEST_P(QuicSpdyStreamTest,
+ QUIC_TEST_DISABLED_IN_CHROME(HeadersAccumulatorNullptr)) {
+ if (!UsesHttp3()) {
+ return;
+ }
+
+ Initialize(kShouldProcessData);
+
+ // Creates QpackDecodedHeadersAccumulator in
+ // `qpack_decoded_headers_accumulator_`.
+ std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+ stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+ // Resets `qpack_decoded_headers_accumulator_`.
+ stream_->OnHeadersDecoded({}, false);
+
+ // This private method should never be called when
+ // `qpack_decoded_headers_accumulator_` is nullptr. The number 1 identifies
+ // the site where `qpack_decoded_headers_accumulator_` was last reset.
+ EXPECT_CALL(*connection_, CloseConnection(_, _, _));
+ bool result = true;
+ EXPECT_QUIC_BUG(result = QuicSpdyStreamPeer::OnHeadersFrameEnd(stream_),
+ "b215142466_OnHeadersFrameEnd.: 1$");
+ EXPECT_FALSE(result);
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc
index 74c9c53a72d..5b744077402 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc
@@ -13,6 +13,7 @@
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
+#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_flag_utils.h"
#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_logging.h"
@@ -194,4 +195,23 @@ void SpdyUtils::AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
(*headers)["datagram-flow-id"] = absl::StrCat(flow_id);
}
+// static
+ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ const spdy::SpdyAltSvcWireFormat::AlternativeService&
+ alternative_service_entry,
+ const ParsedQuicVersionVector& supported_versions) {
+ for (const ParsedQuicVersion& version : supported_versions) {
+ if (version.AlpnDeferToRFCv1()) {
+ // Versions with share an ALPN with v1 are currently unable to be
+ // advertised with Alt-Svc.
+ continue;
+ }
+ if (AlpnForVersion(version) == alternative_service_entry.protocol_id) {
+ return version;
+ }
+ }
+
+ return ParsedQuicVersion::Unsupported();
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h
index 01fae4f17a7..85099ab15e7 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h
+++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h
@@ -14,6 +14,7 @@
#include "quic/core/http/quic_header_list.h"
#include "quic/core/quic_packets.h"
#include "quic/platform/api/quic_export.h"
+#include "spdy/core/spdy_alt_svc_wire_format.h"
#include "spdy/core/spdy_header_block.h"
namespace quic {
@@ -61,6 +62,14 @@ class QUIC_EXPORT_PRIVATE SpdyUtils {
// Adds the "datagram-flow-id" header.
static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
QuicDatagramStreamId flow_id);
+
+ // Returns the advertised QUIC version from the specified alternative service
+ // advertisement, or ParsedQuicVersion::Unsupported() if no supported version
+ // is advertised.
+ static ParsedQuicVersion ExtractQuicVersionFromAltSvcEntry(
+ const spdy::SpdyAltSvcWireFormat::AlternativeService&
+ alternative_service_entry,
+ const ParsedQuicVersionVector& supported_versions);
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc
index 918739d6f90..85c5ceccd57 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "quic/core/http/spdy_utils.h"
+
#include <memory>
#include <string>
#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
-#include "quic/core/http/spdy_utils.h"
+#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_test.h"
using spdy::SpdyHeaderBlock;
@@ -408,5 +410,33 @@ TEST_F(DatagramFlowIdTest, DatagramFlowId) {
ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42);
}
+using ExtractQuicVersionFromAltSvcEntry = QuicTest;
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) {
+ ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+ spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+ for (const ParsedQuicVersion& version : supported_versions) {
+ entry.protocol_id = AlpnForVersion(version);
+ ParsedQuicVersion expected_version = version;
+ // Versions with share an ALPN with v1 are currently unable to be
+ // advertised with Alt-Svc.
+ if (entry.protocol_id == AlpnForVersion(ParsedQuicVersion::RFCv1()) &&
+ version != ParsedQuicVersion::RFCv1()) {
+ expected_version = ParsedQuicVersion::RFCv1();
+ }
+ EXPECT_EQ(expected_version, SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ entry, supported_versions))
+ << "version: " << version;
+ }
+}
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, UnsupportedVersion) {
+ spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+ entry.protocol_id = "quic";
+ EXPECT_EQ(ParsedQuicVersion::Unsupported(),
+ SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ entry, AllSupportedVersions()));
+}
+
} // namespace test
} // namespace quic