Move headers stream from 0 to 60 in v99 This CL also fixes a few tests that were incorrectly using the headers stream. gfe-relnote: change header stream number, protected by v99 flag PiperOrigin-RevId: 253691890 Change-Id: I1351cad387871efe39fb4387eac546e9a24efb7c
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc index 6bd587f..01213d9 100644 --- a/quic/core/http/end_to_end_test.cc +++ b/quic/core/http/end_to_end_test.cc
@@ -751,6 +751,19 @@ .length()); } +TEST_P(EndToEndTestWithTls, SimpleRequestResponseWithIetfDraftSupport) { + if (GetParam().negotiated_version.transport_version != QUIC_VERSION_99 || + GetParam().negotiated_version.handshake_protocol != PROTOCOL_TLS1_3) { + ASSERT_TRUE(Initialize()); + return; + } + QuicVersionInitializeSupportForIetfDraft(1); + ASSERT_TRUE(Initialize()); + + EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); + EXPECT_EQ("200", client_->response_headers()->find(":status")->second); +} + TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) { chlo_multiplier_ = 1; ASSERT_TRUE(Initialize()); @@ -1785,6 +1798,7 @@ // TODO(nharper): Needs to get turned back to EndToEndTestWithTls // when we figure out why the test doesn't work on chrome. TEST_P(EndToEndTest, MaxStreamsUberTest) { + SetQuicFlag(FLAGS_quic_headers_stream_id_in_v99, 0); // Connect with lower fake packet loss than we'd like to test. Until // b/10126687 is fixed, losing handshake packets is pretty brutal. SetPacketLossPercentage(1); @@ -2891,6 +2905,7 @@ const size_t kNumMaxStreams = 10; EndToEndTestServerPush() : EndToEndTest() { + SetQuicFlag(FLAGS_quic_headers_stream_id_in_v99, 0); client_config_.SetMaxIncomingBidirectionalStreamsToSend(kNumMaxStreams); server_config_.SetMaxIncomingBidirectionalStreamsToSend(kNumMaxStreams); client_config_.SetMaxIncomingUnidirectionalStreamsToSend(kNumMaxStreams); @@ -3389,7 +3404,7 @@ TEST_P(EndToEndTest, SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) { // Prevent the connection from expiring in the time wait list. - FLAGS_quic_time_wait_list_seconds = 10000; + SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000); connect_to_server_on_initialize_ = false; ASSERT_TRUE(Initialize());
diff --git a/quic/core/http/quic_headers_stream_test.cc b/quic/core/http/quic_headers_stream_test.cc index a41235f..68d32de 100644 --- a/quic/core/http/quic_headers_stream_test.cc +++ b/quic/core/http/quic_headers_stream_test.cc
@@ -144,14 +144,20 @@ struct TestParams { TestParams(const ParsedQuicVersion& version, Perspective perspective) : version(version), perspective(perspective) { - QUIC_LOG(INFO) << "TestParams: version: " - << ParsedQuicVersionToString(version) - << ", perspective: " << perspective; + QUIC_LOG(INFO) << "TestParams: " << *this; } TestParams(const TestParams& other) : version(other.version), perspective(other.perspective) {} + friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) { + os << "{ version: " << ParsedQuicVersionToString(tp.version) + << ", perspective: " + << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server") + << "}"; + return os; + } + ParsedQuicVersion version; Perspective perspective; }; @@ -390,6 +396,9 @@ } TEST_P(QuicHeadersStreamTest, WritePushPromises) { + if (GetParam().version.DoesNotHaveHeadersStream()) { + return; + } for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_; stream_id += next_stream_id_) { QuicStreamId promised_stream_id = NextPromisedStreamId(); @@ -461,6 +470,9 @@ } TEST_P(QuicHeadersStreamTest, ProcessPushPromise) { + if (GetParam().version.DoesNotHaveHeadersStream()) { + return; + } if (perspective() == Perspective::IS_SERVER) { return; } @@ -470,6 +482,7 @@ SpdyPushPromiseIR push_promise(stream_id, promised_stream_id, headers_.Clone()); SpdySerializedFrame frame(framer_->SerializeFrame(push_promise)); + bool connection_closed = false; if (perspective() == Perspective::IS_SERVER) { EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, @@ -477,6 +490,8 @@ .WillRepeatedly(InvokeWithoutArgs( this, &QuicHeadersStreamTest::TearDownLocalConnectionState)); } else { + ON_CALL(*connection_, CloseConnection(_, _, _)) + .WillByDefault(testing::Assign(&connection_closed, true)); EXPECT_CALL(session_, OnPromiseHeaderList(stream_id, promised_stream_id, frame.size(), _)) .WillOnce( @@ -487,12 +502,18 @@ headers_stream_->OnStreamFrame(stream_frame_); if (perspective() == Perspective::IS_CLIENT) { stream_frame_.offset += frame.size(); + // CheckHeaders crashes if the connection is closed so this ensures we + // fail the test instead of crashing. + ASSERT_FALSE(connection_closed); CheckHeaders(); } } } TEST_P(QuicHeadersStreamTest, ProcessPriorityFrame) { + if (GetParam().version.DoesNotHaveHeadersStream()) { + return; + } QuicStreamId parent_stream_id = 0; for (SpdyPriority priority = 0; priority < 7; ++priority) { for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc index 9aff364..bfde618 100644 --- a/quic/core/http/quic_spdy_client_session_test.cc +++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -241,7 +241,10 @@ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber()); EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber()); - const uint32_t kServerMaxIncomingStreams = 1; + uint32_t kServerMaxIncomingStreams = 1; + if (VersionLacksHeadersStream(GetParam().transport_version)) { + kServerMaxIncomingStreams = 0; + } CompleteCryptoHandshake(kServerMaxIncomingStreams); QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream(); @@ -257,15 +260,22 @@ EXPECT_FALSE(stream); if (GetParam().transport_version == QUIC_VERSION_99) { - // Ensure that we have/have had 3 open streams, crypto, header, and the - // 1 test stream. Primary purpose of this is to fail when crypto - // no longer uses a normal stream. Some above constants will then need - // to be changed. - EXPECT_EQ(QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) - ->outgoing_static_stream_count() + - 1, - QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) - ->outgoing_stream_count()); + if (VersionLacksHeadersStream(GetParam().transport_version)) { + EXPECT_EQ(1u, + QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) + ->outgoing_stream_count()); + + } else { + // Ensure that we have/have had 3 open streams, crypto, header, and the + // 1 test stream. Primary purpose of this is to fail when crypto + // no longer uses a normal stream. Some above constants will then need + // to be changed. + EXPECT_EQ(QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) + ->outgoing_static_stream_count() + + 1, + QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) + ->outgoing_stream_count()); + } } } @@ -279,7 +289,10 @@ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber()); EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber()); - const uint32_t kServerMaxIncomingStreams = 1; + uint32_t kServerMaxIncomingStreams = 1; + if (VersionLacksHeadersStream(GetParam().transport_version)) { + kServerMaxIncomingStreams = 0; + } CompleteCryptoHandshake(kServerMaxIncomingStreams); QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream(); @@ -312,7 +325,11 @@ if (GetParam().transport_version == QUIC_VERSION_99) { // Ensure that we have/have had three open streams: two test streams and the // header stream. - EXPECT_EQ(3u, + QuicStreamCount expected_stream_count = 3; + if (VersionLacksHeadersStream(GetParam().transport_version)) { + expected_stream_count = 2; + } + EXPECT_EQ(expected_stream_count, QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) ->outgoing_stream_count()); } @@ -329,7 +346,10 @@ // the server sends trailing headers (trailers). Receipt of the trailers by // the client should result in all outstanding stream state being tidied up // (including flow control, and number of available outgoing streams). - const uint32_t kServerMaxIncomingStreams = 1; + uint32_t kServerMaxIncomingStreams = 1; + if (VersionLacksHeadersStream(GetParam().transport_version)) { + kServerMaxIncomingStreams = 0; + } CompleteCryptoHandshake(kServerMaxIncomingStreams); QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream(); @@ -392,7 +412,11 @@ if (GetParam().transport_version == QUIC_VERSION_99) { // Ensure that we have/have had three open streams: two test streams and the // header stream. - EXPECT_EQ(3u, + QuicStreamCount expected_stream_count = 3; + if (VersionLacksHeadersStream(GetParam().transport_version)) { + expected_stream_count = 2; + } + EXPECT_EQ(expected_stream_count, QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) ->outgoing_stream_count()); }
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc index b9006ca..5004557 100644 --- a/quic/core/http/quic_spdy_session.cc +++ b/quic/core/http/quic_spdy_session.cc
@@ -351,13 +351,15 @@ void QuicSpdySession::Initialize() { QuicSession::Initialize(); - if (perspective() == Perspective::IS_SERVER) { - set_largest_peer_created_stream_id( - QuicUtils::GetHeadersStreamId(connection()->transport_version())); - } else { - QuicStreamId headers_stream_id = GetNextOutgoingBidirectionalStreamId(); - DCHECK_EQ(headers_stream_id, - QuicUtils::GetHeadersStreamId(connection()->transport_version())); + if (!connection()->version().DoesNotHaveHeadersStream()) { + if (perspective() == Perspective::IS_SERVER) { + set_largest_peer_created_stream_id( + QuicUtils::GetHeadersStreamId(connection()->transport_version())); + } else { + QuicStreamId headers_stream_id = GetNextOutgoingBidirectionalStreamId(); + DCHECK_EQ(headers_stream_id, QuicUtils::GetHeadersStreamId( + connection()->transport_version())); + } } if (VersionUsesQpack(connection()->transport_version())) {
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc index fc1ae0a..ce4d5a9 100644 --- a/quic/core/http/quic_spdy_session_test.cc +++ b/quic/core/http/quic_spdy_session_test.cc
@@ -483,9 +483,12 @@ // stream ID, the next ID should fail. Since the actual limit // is not the number of open streams, we allocate the max and the max+2. // Get the max allowed stream ID, this should succeed. + QuicStreamCount headers_stream_offset = + VersionLacksHeadersStream(QUIC_VERSION_99) ? 1 : 0; QuicStreamId stream_id = StreamCountToId( QuicSessionPeer::v99_streamid_manager(&session_) - ->actual_max_allowed_incoming_bidirectional_streams(), + ->actual_max_allowed_incoming_bidirectional_streams() - + headers_stream_offset, Perspective::IS_CLIENT, // Client initates stream, allocs stream id. /*bidirectional=*/true); EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id)); @@ -500,7 +503,7 @@ stream_id = StreamCountToId( QuicSessionPeer::v99_streamid_manager(&session_) ->actual_max_allowed_incoming_bidirectional_streams() + - 1, + 1 - headers_stream_offset, Perspective::IS_CLIENT, /*bidirectional=*/true); EXPECT_EQ(nullptr, session_.GetOrCreateDynamicStream(stream_id)); @@ -1588,10 +1591,12 @@ .Times(1); } else { // On version 99 opening such a stream results in a connection close. - EXPECT_CALL( - *connection_, - CloseConnection(QUIC_INVALID_STREAM_ID, - "Stream id 24 would exceed stream count limit 6", _)); + EXPECT_CALL(*connection_, + CloseConnection( + QUIC_INVALID_STREAM_ID, + testing::MatchesRegex( + "Stream id [0-9]+ would exceed stream count limit 6"), + _)); } // Create one more data streams to exceed limit of open stream. QuicStreamFrame data1(kFinalStreamId, false, 0, QuicStringPiece("HT"));
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc index 9ca1df2..66100bb 100644 --- a/quic/core/http/quic_spdy_stream_test.cc +++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -260,9 +260,12 @@ VersionUsesQpack(GetParam().transport_version); if (version_uses_qpack) { - EXPECT_CALL(*connection_, - CloseConnection(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE, - "Too large headers received on stream 4", _)); + EXPECT_CALL( + *connection_, + CloseConnection(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE, + testing::MatchesRegex( + "Too large headers received on stream [0-9]+"), + _)); } else { EXPECT_CALL(*session_, SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0)); @@ -1817,11 +1820,13 @@ std::string stream_frame_payload = QuicStrCat(headers, data); QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload); - EXPECT_CALL(*connection_, - CloseConnection(QUIC_DECOMPRESSION_FAILURE, - "Error decompressing header block on stream 4: " - "Incomplete header block.", - _)) + EXPECT_CALL( + *connection_, + CloseConnection(QUIC_DECOMPRESSION_FAILURE, + testing::MatchesRegex( + "Error decompressing header block on stream [0-9]+: " + "Incomplete header block."), + _)) .WillOnce( (Invoke([this](QuicErrorCode error, const std::string& error_details, ConnectionCloseBehavior connection_close_behavior) {
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index 7450eb6..243c13a 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -92,7 +92,9 @@ QuicStreamId GetNthClientInitiatedStreamId(int n, QuicTransportVersion version) { - return QuicUtils::GetHeadersStreamId(version) + n * 2; + return QuicUtils::GetFirstBidirectionalStreamId(version, + Perspective::IS_CLIENT) + + n * 2; } QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) { @@ -3166,8 +3168,8 @@ iov.iov_base = data_array.get(); iov.iov_len = len; QuicConsumedData consumed = connection_.SaveAndSendStreamData( - QuicUtils::GetHeadersStreamId(connection_.transport_version()), &iov, 1, - len, 0, FIN); + GetNthClientInitiatedStreamId(0, connection_.transport_version()), &iov, + 1, len, 0, FIN); EXPECT_EQ(len, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -3176,7 +3178,7 @@ // Parse the last packet and ensure it's one stream frame with a fin. EXPECT_EQ(1u, writer_->frame_count()); ASSERT_EQ(1u, writer_->stream_frames().size()); - EXPECT_EQ(QuicUtils::GetHeadersStreamId(connection_.transport_version()), + EXPECT_EQ(GetNthClientInitiatedStreamId(0, connection_.transport_version()), writer_->stream_frames()[0]->stream_id); EXPECT_TRUE(writer_->stream_frames()[0]->fin); // Ensure the ack alarm was cancelled when the ack was sent. @@ -4517,8 +4519,8 @@ // Send and ack new data 3 seconds later to lengthen the idle timeout. SendStreamDataToPeer( - QuicUtils::GetHeadersStreamId(connection_.transport_version()), "GET /", - 0, FIN, nullptr); + GetNthClientInitiatedStreamId(0, connection_.transport_version()), + "GET /", 0, FIN, nullptr); clock_.AdvanceTime(QuicTime::Delta::FromSeconds(3)); QuicAckFrame frame = InitAckFrame(1); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); @@ -4560,8 +4562,8 @@ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); SendStreamDataToPeer( - QuicUtils::GetHeadersStreamId(connection_.transport_version()), "GET /", - 0, FIN, nullptr); + GetNthClientInitiatedStreamId(0, connection_.transport_version()), + "GET /", 0, FIN, nullptr); EXPECT_TRUE(connection_.GetPingAlarm()->IsSet()); EXPECT_EQ(clock_.ApproximateNow() + QuicTime::Delta::FromSeconds(15), connection_.GetPingAlarm()->deadline()); @@ -4614,8 +4616,8 @@ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); SendStreamDataToPeer( - QuicUtils::GetHeadersStreamId(connection_.transport_version()), "GET /", - 0, FIN, nullptr); + GetNthClientInitiatedStreamId(0, connection_.transport_version()), + "GET /", 0, FIN, nullptr); EXPECT_TRUE(connection_.GetPingAlarm()->IsSet()); EXPECT_EQ(clock_.ApproximateNow() + QuicTime::Delta::FromSeconds(10), connection_.GetPingAlarm()->deadline());
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc index a661c24..bc30af9 100644 --- a/quic/core/quic_packet_creator_test.cc +++ b/quic/core/quic_packet_creator_test.cc
@@ -261,7 +261,9 @@ } QuicStreamId GetNthClientInitiatedStreamId(int n) const { - return QuicUtils::GetHeadersStreamId(creator_.transport_version()) + n * 2; + return QuicUtils::GetFirstBidirectionalStreamId( + creator_.transport_version(), Perspective::IS_CLIENT) + + n * 2; } static const QuicStreamOffset kOffset = 0u; @@ -1371,9 +1373,8 @@ EXPECT_FALSE(creator_.HasPendingFrames()); MakeIOVector("test", &iov_); - producer_.SaveStreamData( - QuicUtils::GetHeadersStreamId(client_framer_.transport_version()), &iov_, - 1u, 0u, iov_.iov_len); + producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), &iov_, 1u, 0u, + iov_.iov_len); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); size_t num_bytes_consumed; @@ -1381,8 +1382,8 @@ creator_.set_debug_delegate(&debug); EXPECT_CALL(debug, OnFrameAddedToPacket(_)); creator_.CreateAndSerializeStreamFrame( - QuicUtils::GetHeadersStreamId(client_framer_.transport_version()), - iov_.iov_len, 0, 0, true, NOT_RETRANSMISSION, &num_bytes_consumed); + GetNthClientInitiatedStreamId(0), iov_.iov_len, 0, 0, true, + NOT_RETRANSMISSION, &num_bytes_consumed); EXPECT_EQ(4u, num_bytes_consumed); // Ensure the packet is successfully created. @@ -1407,15 +1408,14 @@ // Send one byte of stream data. MakeIOVector("a", &iov_); - producer_.SaveStreamData( - QuicUtils::GetHeadersStreamId(client_framer_.transport_version()), &iov_, - 1u, 0u, iov_.iov_len); + producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), &iov_, 1u, 0u, + iov_.iov_len); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); size_t num_bytes_consumed; creator_.CreateAndSerializeStreamFrame( - QuicUtils::GetHeadersStreamId(client_framer_.transport_version()), - iov_.iov_len, 0, 0, true, NOT_RETRANSMISSION, &num_bytes_consumed); + GetNthClientInitiatedStreamId(0), iov_.iov_len, 0, 0, true, + NOT_RETRANSMISSION, &num_bytes_consumed); EXPECT_EQ(1u, num_bytes_consumed); // Check that a packet is created. @@ -1445,9 +1445,8 @@ creator_.set_encryption_level(ENCRYPTION_INITIAL); EXPECT_CALL(delegate_, OnUnrecoverableError(_, _)); - QuicStreamFrame stream_frame( - QuicUtils::GetHeadersStreamId(client_framer_.transport_version()), - /*fin=*/false, 0u, QuicStringPiece()); + QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0), + /*fin=*/false, 0u, QuicStringPiece()); EXPECT_QUIC_BUG( creator_.AddSavedFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION), "Cannot send stream data with level: ENCRYPTION_INITIAL"); @@ -1461,9 +1460,8 @@ creator_.set_encryption_level(ENCRYPTION_HANDSHAKE); EXPECT_CALL(delegate_, OnUnrecoverableError(_, _)); - QuicStreamFrame stream_frame( - QuicUtils::GetHeadersStreamId(client_framer_.transport_version()), - /*fin=*/false, 0u, QuicStringPiece()); + QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0), + /*fin=*/false, 0u, QuicStringPiece()); EXPECT_QUIC_BUG( creator_.AddSavedFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION), "Cannot send stream data with level: ENCRYPTION_HANDSHAKE");
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc index c8a0a02..584593a 100644 --- a/quic/core/quic_session_test.cc +++ b/quic/core/quic_session_test.cc
@@ -1295,6 +1295,9 @@ } TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) { + if (connection_->version().DoesNotHaveHeadersStream()) { + return; + } QuicStreamId headers_stream_id = QuicUtils::GetHeadersStreamId(connection_->transport_version()); std::unique_ptr<TestStream> fake_headers_stream = QuicMakeUnique<TestStream>( @@ -1316,6 +1319,9 @@ } TEST_P(QuicSessionTestServer, OnRstStreamStaticStreamId) { + if (connection_->version().DoesNotHaveHeadersStream()) { + return; + } QuicStreamId headers_stream_id = QuicUtils::GetHeadersStreamId(connection_->transport_version()); std::unique_ptr<TestStream> fake_headers_stream = QuicMakeUnique<TestStream>(
diff --git a/quic/core/quic_utils.cc b/quic/core/quic_utils.cc index 996e78f..955e82f 100644 --- a/quic/core/quic_utils.cc +++ b/quic/core/quic_utils.cc
@@ -399,6 +399,11 @@ // static QuicStreamId QuicUtils::GetHeadersStreamId(QuicTransportVersion version) { + if (version == QUIC_VERSION_99) { + // TODO(b/130659182) Turn this into a QUIC_BUG once we've fully removed + // the headers stream in those versions. + return GetQuicFlag(FLAGS_quic_headers_stream_id_in_v99); + } return GetFirstBidirectionalStreamId(version, Perspective::IS_CLIENT); }
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc index f0b5416..33faa3c 100644 --- a/quic/core/quic_versions.cc +++ b/quic/core/quic_versions.cc
@@ -63,6 +63,17 @@ return transport_version >= QUIC_VERSION_99; } +bool ParsedQuicVersion::DoesNotHaveHeadersStream() const { + return VersionLacksHeadersStream(transport_version); +} + +bool VersionLacksHeadersStream(QuicTransportVersion transport_version) { + if (GetQuicFlag(FLAGS_quic_headers_stream_id_in_v99) == 0) { + return false; + } + return transport_version == QUIC_VERSION_99; +} + std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) { os << ParsedQuicVersionToString(version); return os; @@ -418,6 +429,8 @@ // Enable necessary flags. SetQuicFlag(FLAGS_quic_supports_tls_handshake, true); + // 60 is the highest multiple of 4 and one-byte variable length integer. + SetQuicFlag(FLAGS_quic_headers_stream_id_in_v99, 60); SetQuicReloadableFlag(quic_deprecate_ack_bundling_mode, true); SetQuicReloadableFlag(quic_rpm_decides_when_to_send_acks, true); SetQuicReloadableFlag(quic_use_uber_loss_algorithm, true);
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h index dd10d96..59005cd 100644 --- a/quic/core/quic_versions.h +++ b/quic/core/quic_versions.h
@@ -169,6 +169,9 @@ // Returns whether this version supports client connection ID. bool SupportsClientConnectionIds() const; + + // Returns whether this version does not have the Google QUIC headers stream. + bool DoesNotHaveHeadersStream() const; }; QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion(); @@ -408,6 +411,11 @@ return transport_version == QUIC_VERSION_99; } +// Returns whether |transport_version| does not have the +// Google QUIC headers stream. +QUIC_EXPORT_PRIVATE bool VersionLacksHeadersStream( + QuicTransportVersion transport_version); + // Returns the ALPN string to use in TLS for this version of QUIC. QUIC_EXPORT_PRIVATE std::string AlpnForVersion( ParsedQuicVersion parsed_version);
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc index 38873dd..100f4e9 100644 --- a/quic/test_tools/quic_test_utils.cc +++ b/quic/test_tools/quic_test_utils.cc
@@ -1147,10 +1147,13 @@ QuicStreamId GetNthClientInitiatedBidirectionalStreamId( QuicTransportVersion version, int n) { + int num = n; + if (!VersionLacksHeadersStream(version)) { + num++; // + 1 because spdy_session contains headers stream. + } return QuicUtils::GetFirstBidirectionalStreamId(version, Perspective::IS_CLIENT) + - // + 1 because spdy_session contains headers stream. - QuicUtils::StreamIdDelta(version) * (n + 1); + QuicUtils::StreamIdDelta(version) * num; } QuicStreamId GetNthServerInitiatedBidirectionalStreamId(