mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
release connection-level flow control credit when a stream is reset
This commit is contained in:
parent
1864e301ef
commit
1d7d532035
5 changed files with 99 additions and 26 deletions
|
@ -458,26 +458,22 @@ var _ = Describe("Receive Stream", func() {
|
|||
close(done)
|
||||
}()
|
||||
Consistently(done).ShouldNot(BeClosed())
|
||||
err := str.CancelRead(1234)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.CancelRead(1234)).To(Succeed())
|
||||
Eventually(done).Should(BeClosed())
|
||||
})
|
||||
|
||||
It("doesn't allow further calls to Read", func() {
|
||||
mockSender.EXPECT().queueControlFrame(gomock.Any())
|
||||
err := str.CancelRead(1234)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = strWithTimeout.Read([]byte{0})
|
||||
Expect(str.CancelRead(1234)).To(Succeed())
|
||||
_, err := strWithTimeout.Read([]byte{0})
|
||||
Expect(err).To(MatchError("Read on stream 1337 canceled with error code 1234"))
|
||||
})
|
||||
|
||||
It("does nothing when CancelRead is called twice", func() {
|
||||
mockSender.EXPECT().queueControlFrame(gomock.Any())
|
||||
err := str.CancelRead(1234)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
err = str.CancelRead(2345)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = strWithTimeout.Read([]byte{0})
|
||||
Expect(str.CancelRead(1234)).To(Succeed())
|
||||
Expect(str.CancelRead(1234)).To(Succeed())
|
||||
_, err := strWithTimeout.Read([]byte{0})
|
||||
Expect(err).To(MatchError("Read on stream 1337 canceled with error code 1234"))
|
||||
})
|
||||
|
||||
|
@ -505,7 +501,10 @@ var _ = Describe("Receive Stream", func() {
|
|||
})
|
||||
|
||||
It("doesn't send a STOP_SENDING frame, if the stream was already reset", func() {
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true)
|
||||
gomock.InOrder(
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true),
|
||||
mockFC.EXPECT().Abandon(),
|
||||
)
|
||||
mockSender.EXPECT().onStreamCompleted(streamID)
|
||||
Expect(str.handleResetStreamFrame(&wire.ResetStreamFrame{
|
||||
StreamID: streamID,
|
||||
|
@ -513,6 +512,32 @@ var _ = Describe("Receive Stream", func() {
|
|||
})).To(Succeed())
|
||||
Expect(str.CancelRead(1234)).To(Succeed())
|
||||
})
|
||||
|
||||
It("sends a STOP_SENDING and completes the stream after receiving the final offset", func() {
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(1000), true)
|
||||
Expect(str.handleStreamFrame(&wire.StreamFrame{
|
||||
Offset: 1000,
|
||||
FinBit: true,
|
||||
})).To(Succeed())
|
||||
mockFC.EXPECT().Abandon()
|
||||
mockSender.EXPECT().queueControlFrame(gomock.Any())
|
||||
mockSender.EXPECT().onStreamCompleted(streamID)
|
||||
Expect(str.CancelRead(1234)).To(Succeed())
|
||||
})
|
||||
|
||||
It("completes the stream when receiving the FinBit after the stream was canceled", func() {
|
||||
mockSender.EXPECT().queueControlFrame(gomock.Any())
|
||||
Expect(str.CancelRead(1234)).To(Succeed())
|
||||
gomock.InOrder(
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(1000), true),
|
||||
mockFC.EXPECT().Abandon(),
|
||||
)
|
||||
mockSender.EXPECT().onStreamCompleted(streamID)
|
||||
Expect(str.handleStreamFrame(&wire.StreamFrame{
|
||||
Offset: 1000,
|
||||
FinBit: true,
|
||||
})).To(Succeed())
|
||||
})
|
||||
})
|
||||
|
||||
Context("receiving RESET_STREAM frames", func() {
|
||||
|
@ -523,7 +548,6 @@ var _ = Describe("Receive Stream", func() {
|
|||
}
|
||||
|
||||
It("unblocks Read", func() {
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true)
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
|
@ -536,16 +560,22 @@ var _ = Describe("Receive Stream", func() {
|
|||
}()
|
||||
Consistently(done).ShouldNot(BeClosed())
|
||||
mockSender.EXPECT().onStreamCompleted(streamID)
|
||||
gomock.InOrder(
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true),
|
||||
mockFC.EXPECT().Abandon(),
|
||||
)
|
||||
str.handleResetStreamFrame(rst)
|
||||
Eventually(done).Should(BeClosed())
|
||||
})
|
||||
|
||||
It("doesn't allow further calls to Read", func() {
|
||||
mockSender.EXPECT().onStreamCompleted(streamID)
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true)
|
||||
err := str.handleResetStreamFrame(rst)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = strWithTimeout.Read([]byte{0})
|
||||
gomock.InOrder(
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true),
|
||||
mockFC.EXPECT().Abandon(),
|
||||
)
|
||||
Expect(str.handleResetStreamFrame(rst)).To(Succeed())
|
||||
_, err := strWithTimeout.Read([]byte{0})
|
||||
Expect(err).To(MatchError("Stream 1337 was reset with error code 1234"))
|
||||
Expect(err).To(BeAssignableToTypeOf(streamCanceledError{}))
|
||||
Expect(err.(streamCanceledError).Canceled()).To(BeTrue())
|
||||
|
@ -561,11 +591,10 @@ var _ = Describe("Receive Stream", func() {
|
|||
|
||||
It("ignores duplicate RESET_STREAM frames", func() {
|
||||
mockSender.EXPECT().onStreamCompleted(streamID)
|
||||
mockFC.EXPECT().Abandon()
|
||||
mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true).Times(2)
|
||||
err := str.handleResetStreamFrame(rst)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
err = str.handleResetStreamFrame(rst)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.handleResetStreamFrame(rst)).To(Succeed())
|
||||
Expect(str.handleResetStreamFrame(rst)).To(Succeed())
|
||||
})
|
||||
|
||||
It("doesn't do anyting when it was closed for shutdown", func() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue