Add support for HTTP/3 control stream.
Upon initialization, QuicSpdySession will create a write_unidirectional stream
and write stream type and settings when crypto handshake is completed.
The peer will receive the stream type and create a read_unidirectional stream
that reads the settings.
gfe-relnote: version 99 only. Not in prod.
PiperOrigin-RevId: 252650934
Change-Id: I708280eb94dea3d6eb7e54b96ce8ee91e2b8684f
diff --git a/quic/tools/quic_simple_server_session_test.cc b/quic/tools/quic_simple_server_session_test.cc
index aa2defa..9071e05 100644
--- a/quic/tools/quic_simple_server_session_test.cc
+++ b/quic/tools/quic_simple_server_session_test.cc
@@ -502,7 +502,12 @@
QuicSpdyStream* created_stream =
QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
session_.get());
- EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i), created_stream->id());
+ if (VersionHasStreamType(connection_->transport_version())) {
+ EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i + 1),
+ created_stream->id());
+ } else {
+ EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i), created_stream->id());
+ }
EXPECT_EQ(i + 1, session_->GetNumOpenOutgoingStreams());
}
@@ -617,7 +622,12 @@
std::string scheme = "http";
QuicByteCount data_frame_header_length = 0;
for (unsigned int i = 1; i <= num_resources; ++i) {
- QuicStreamId stream_id = GetNthServerInitiatedUnidirectionalId(i - 1);
+ QuicStreamId stream_id;
+ if (VersionHasStreamType(connection_->transport_version())) {
+ stream_id = GetNthServerInitiatedUnidirectionalId(i);
+ } else {
+ stream_id = GetNthServerInitiatedUnidirectionalId(i - 1);
+ }
std::string path =
partial_push_resource_path + QuicTextUtils::Uint64ToString(i);
std::string url = scheme + "://" + resource_host + path;
@@ -714,8 +724,14 @@
MaybeConsumeHeadersStreamData();
size_t num_resources = kMaxStreamsForTest + 1;
QuicByteCount data_frame_header_length = PromisePushResources(num_resources);
- QuicStreamId next_out_going_stream_id =
- GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest);
+ QuicStreamId next_out_going_stream_id;
+ if (VersionHasStreamType(connection_->transport_version())) {
+ next_out_going_stream_id =
+ GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest + 1);
+ } else {
+ next_out_going_stream_id =
+ GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest);
+ }
// After an open stream is marked draining, a new stream is expected to be
// created and a response sent on the stream.
@@ -753,11 +769,17 @@
// a MAX_STREAMS frame is received. This emulates the reception of one.
// For pre-v-99, the node monitors its own stream usage and makes streams
// available as it closes/etc them.
+ // Version 99 also has unidirectional static streams, so we need to send
+ // MaxStreamFrame of the number of resources + number of static streams.
session_->OnMaxStreamsFrame(
- QuicMaxStreamsFrame(0, num_resources, /*unidirectional=*/true));
+ QuicMaxStreamsFrame(0, num_resources + 1, /*unidirectional=*/true));
}
- session_->StreamDraining(GetNthServerInitiatedUnidirectionalId(0));
+ if (VersionHasStreamType(connection_->transport_version())) {
+ session_->StreamDraining(GetNthServerInitiatedUnidirectionalId(1));
+ } else {
+ session_->StreamDraining(GetNthServerInitiatedUnidirectionalId(0));
+ }
// Number of open outgoing streams should still be the same, because a new
// stream is opened. And the queue should be empty.
EXPECT_EQ(kMaxStreamsForTest, session_->GetNumOpenOutgoingStreams());
@@ -783,8 +805,14 @@
QuicByteCount data_frame_header_length = PromisePushResources(num_resources);
// Reset the last stream in the queue. It should be marked cancelled.
- QuicStreamId stream_got_reset =
- GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest + 1);
+ QuicStreamId stream_got_reset;
+ if (VersionHasStreamType(connection_->transport_version())) {
+ stream_got_reset =
+ GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest + 2);
+ } else {
+ stream_got_reset =
+ GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest + 1);
+ }
QuicRstStreamFrame rst(kInvalidControlFrameId, stream_got_reset,
QUIC_STREAM_CANCELLED, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
@@ -798,8 +826,14 @@
// When the first 2 streams becomes draining, the two queued up stream could
// be created. But since one of them was marked cancelled due to RST frame,
// only one queued resource will be sent out.
- QuicStreamId stream_not_reset =
- GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest);
+ QuicStreamId stream_not_reset;
+ if (VersionHasStreamType(connection_->transport_version())) {
+ stream_not_reset =
+ GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest + 1);
+ } else {
+ stream_not_reset =
+ GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest);
+ }
InSequence s;
QuicStreamOffset offset = 0;
if (VersionHasStreamType(connection_->transport_version())) {
@@ -835,10 +869,10 @@
// For pre-v-99, the node monitors its own stream usage and makes streams
// available as it closes/etc them.
session_->OnMaxStreamsFrame(
- QuicMaxStreamsFrame(0, num_resources, /*unidirectional=*/true));
+ QuicMaxStreamsFrame(0, num_resources + 1, /*unidirectional=*/true));
}
- session_->StreamDraining(GetNthServerInitiatedUnidirectionalId(0));
session_->StreamDraining(GetNthServerInitiatedUnidirectionalId(1));
+ session_->StreamDraining(GetNthServerInitiatedUnidirectionalId(2));
}
// Tests that closing a open outgoing stream can trigger a promised resource in
@@ -856,12 +890,17 @@
this, &QuicSimpleServerSessionServerPushTest::ClearControlFrame));
}
QuicByteCount data_frame_header_length = PromisePushResources(num_resources);
- QuicStreamId stream_to_open =
- GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest);
+ QuicStreamId stream_to_open;
+ if (VersionHasStreamType(connection_->transport_version())) {
+ stream_to_open =
+ GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest + 1);
+ } else {
+ stream_to_open = GetNthServerInitiatedUnidirectionalId(kMaxStreamsForTest);
+ }
- // Resetting 1st open stream will close the stream and give space for extra
+ // Resetting an open stream will close the stream and give space for extra
// stream to be opened.
- QuicStreamId stream_got_reset = GetNthServerInitiatedUnidirectionalId(0);
+ QuicStreamId stream_got_reset = GetNthServerInitiatedUnidirectionalId(1);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
EXPECT_CALL(*connection_, SendControlFrame(_));
if (!IsVersion99()) {
@@ -905,7 +944,7 @@
// For pre-v-99, the node monitors its own stream usage and makes streams
// available as it closes/etc them.
session_->OnMaxStreamsFrame(
- QuicMaxStreamsFrame(0, num_resources, /*unidirectional=*/true));
+ QuicMaxStreamsFrame(0, num_resources + 1, /*unidirectional=*/true));
}
visitor_->OnRstStream(rst);
// Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a