Return false in QuicTransportStream::CanWrite() if the write side of the stream has been closed. gfe-relnote: n/a (not used in production GFE code) PiperOrigin-RevId: 288535167 Change-Id: I2ea667733f234937af671b5740c77944e5eef879
diff --git a/quic/quic_transport/quic_transport_stream.cc b/quic/quic_transport/quic_transport_stream.cc index db90597..2852442 100644 --- a/quic/quic_transport/quic_transport_stream.cc +++ b/quic/quic_transport/quic_transport_stream.cc
@@ -97,7 +97,8 @@ } bool QuicTransportStream::CanWrite() const { - return session_interface_->IsSessionReady() && CanWriteNewData(); + return session_interface_->IsSessionReady() && CanWriteNewData() && + !write_side_closed(); } size_t QuicTransportStream::ReadableBytes() const {
diff --git a/quic/quic_transport/quic_transport_stream_test.cc b/quic/quic_transport/quic_transport_stream_test.cc index f4311ce..69d40f4 100644 --- a/quic/quic_transport/quic_transport_stream_test.cc +++ b/quic/quic_transport/quic_transport_stream_test.cc
@@ -20,6 +20,7 @@ namespace test { namespace { +using testing::_; using testing::Return; ParsedQuicVersionVector GetVersions() { @@ -136,6 +137,16 @@ EXPECT_FALSE(stream_->Write(a_lot_of_data)); } +TEST_F(QuicTransportStreamTest, CannotSendFinTwice) { + EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true)); + ASSERT_TRUE(stream_->CanWrite()); + + EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _)) + .WillOnce(Return(QuicConsumedData(0, /*fin_consumed=*/true))); + EXPECT_TRUE(stream_->SendFin()); + EXPECT_FALSE(stream_->CanWrite()); +} + } // namespace } // namespace test } // namespace quic