Introduce the concept of STOP_SENDING in gQUIC.
gQUIC uses to have RST(QUIC_STREAM_NO_ERROR) to achieve STOP_SENDING semantics. This change would unify this behavior with IETF STOP_SENDING.
Protected by quic_reloadable_flag_quic_split_up_send_rst.
PiperOrigin-RevId: 336959906
Change-Id: Ie1daa4a96bcdd627354b1425bd736a91f153beab
diff --git a/quic/tools/quic_simple_server_stream_test.cc b/quic/tools/quic_simple_server_stream_test.cc
index c5d989a..251f02d 100644
--- a/quic/tools/quic_simple_server_stream_test.cc
+++ b/quic/tools/quic_simple_server_stream_test.cc
@@ -12,6 +12,7 @@
#include "absl/types/optional.h"
#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
@@ -158,6 +159,16 @@
QuicStreamOffset bytes_written,
bool send_rst_only),
(override));
+ MOCK_METHOD(void,
+ MaybeSendRstStreamFrame,
+ (QuicStreamId stream_id,
+ QuicRstStreamErrorCode error,
+ QuicStreamOffset bytes_written),
+ (override));
+ MOCK_METHOD(void,
+ MaybeSendStopSendingFrame,
+ (QuicStreamId stream_id, QuicRstStreamErrorCode error),
+ (override));
// Matchers cannot be used on non-copyable types like SpdyHeaderBlock.
void PromisePushResources(
const std::string& request_url,
@@ -341,7 +352,18 @@
QuicStreamPeer::SetFinSent(stream_);
stream_->CloseWriteSide();
- EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)).Times(1);
+ if (!session_.split_up_send_rst()) {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _))
+ .Times(1);
+ } else {
+ if (session_.version().UsesHttp3()) {
+ EXPECT_CALL(session_, MaybeSendStopSendingFrame(_, QUIC_STREAM_NO_ERROR))
+ .Times(1);
+ } else {
+ EXPECT_CALL(session_, MaybeSendRstStreamFrame(_, QUIC_STREAM_NO_ERROR, _))
+ .Times(1);
+ }
+ }
stream_->StopReading();
}
@@ -469,8 +491,16 @@
std::move(response_headers_), body);
InSequence s;
- EXPECT_CALL(session_, SendRstStream(promised_stream->id(),
- QUIC_STREAM_CANCELLED, 0, _));
+ if (!session_.split_up_send_rst()) {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_CANCELLED, 0, _));
+ } else {
+ if (session_.version().UsesHttp3()) {
+ EXPECT_CALL(session_, MaybeSendStopSendingFrame(promised_stream->id(),
+ QUIC_STREAM_CANCELLED));
+ }
+ EXPECT_CALL(session_, MaybeSendRstStreamFrame(promised_stream->id(),
+ QUIC_STREAM_CANCELLED, 0));
+ }
promised_stream->DoSendResponse();
}
@@ -674,7 +704,6 @@
TEST_P(QuicSimpleServerStreamTest,
DoNotSendQuicRstStreamNoErrorWithRstReceived) {
- InSequence s;
EXPECT_FALSE(stream_->reading_stopped());
EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)).Times(0);
@@ -687,16 +716,33 @@
EXPECT_CALL(session_, WritevData(qpack_decoder_stream->id(), _, _, _, _, _))
.Times(AnyNumber());
}
- EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _, _))
- .Times(1);
+
+ if (!session_.split_up_send_rst()) {
+ EXPECT_CALL(session_, SendRstStream(_,
+ session_.version().UsesHttp3()
+ ? QUIC_STREAM_CANCELLED
+ : QUIC_RST_ACKNOWLEDGEMENT,
+ _, _))
+ .Times(1);
+ } else {
+ EXPECT_CALL(session_,
+ MaybeSendRstStreamFrame(_,
+ session_.version().UsesHttp3()
+ ? QUIC_STREAM_CANCELLED
+ : QUIC_RST_ACKNOWLEDGEMENT,
+ _))
+ .Times(1);
+ }
QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
QUIC_STREAM_CANCELLED, 1234);
stream_->OnStreamReset(rst_frame);
if (VersionHasIetfQuicFrames(connection_->transport_version())) {
- // For V99 receiving a RST_STREAM causes a 1-way close; the test requires
- // a full close. A CloseWriteSide closes the other half of the stream.
- // Everything should then work properly.
- stream_->CloseWriteSide();
+ EXPECT_CALL(session_owner_, OnStopSendingReceived(_));
+ // Create and inject a STOP SENDING frame to complete the close
+ // of the stream. This is only needed for version 99/IETF QUIC.
+ QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
+ QUIC_STREAM_CANCELLED);
+ session_.OnStopSendingFrame(stop_sending);
}
EXPECT_TRUE(stream_->reading_stopped());
EXPECT_TRUE(stream_->write_side_closed());