correclty detected the closed state of a stream

fixes #380
This commit is contained in:
Marten Seemann
2017-01-07 10:53:54 +07:00
parent 7a91794292
commit d6a0a145a4
3 changed files with 64 additions and 2 deletions

View File

@@ -347,6 +347,7 @@ var _ = Describe("Session", func() {
StreamID: 5,
ByteOffset: 0x1337,
}))
Expect(str.(*stream).finished()).To(BeTrue())
})
It("doesn't queue a RST_STREAM for a stream that it already sent a FIN on", func() {
@@ -358,6 +359,7 @@ var _ = Describe("Session", func() {
})
Expect(err).ToNot(HaveOccurred())
Expect(session.packer.controlFrames).To(BeEmpty())
Expect(str.(*stream).finished()).To(BeTrue())
})
It("passes the byte offset to the flow controller", func() {
@@ -403,6 +405,7 @@ var _ = Describe("Session", func() {
StreamID: 5,
ByteOffset: 0x1337,
}))
Expect(str.finished()).To(BeFalse())
})
It("doesn't queue another RST_STREAM, when it receives an RST_STREAM as a response for the first", func() {
@@ -418,7 +421,6 @@ var _ = Describe("Session", func() {
Expect(err).ToNot(HaveOccurred())
Expect(session.packer.controlFrames).To(HaveLen(1))
})
})
Context("handling WINDOW_UPDATE frames", func() {

View File

@@ -310,7 +310,11 @@ func (s *stream) finishedWriteAndSentFin() bool {
}
func (s *stream) finished() bool {
return s.cancelled.Get() || (s.finishedReading.Get() && s.finishedWriteAndSentFin())
return s.cancelled.Get() ||
(s.finishedReading.Get() && s.finishedWriteAndSentFin()) ||
(s.resetRemotely.Get() && s.rstSent.Get()) ||
(s.finishedReading.Get() && s.rstSent.Get()) ||
(s.finishedWriteAndSentFin() && s.resetRemotely.Get())
}
func (s *stream) StreamID() protocol.StreamID {

View File

@@ -732,4 +732,60 @@ var _ = Describe("Stream", func() {
})
})
Context("closing", func() {
testErr := errors.New("testErr")
finishReading := func() {
err := str.AddStreamFrame(&frames.StreamFrame{FinBit: true})
Expect(err).ToNot(HaveOccurred())
b := make([]byte, 100)
_, err = str.Read(b)
Expect(err).To(MatchError(io.EOF))
}
It("is finished after it is canceled", func() {
str.Cancel(testErr)
Expect(str.finished()).To(BeTrue())
})
It("is not finished if it is only closed for writing", func() {
str.Close()
str.sentFin()
Expect(str.finished()).To(BeFalse())
})
It("is not finished if it is only closed for reading", func() {
finishReading()
Expect(str.finished()).To(BeFalse())
})
It("is finished after receiving a RST and sending one", func() {
// this directly sends a rst
str.RegisterRemoteError(testErr)
Expect(str.rstSent.Get()).To(BeTrue())
Expect(str.finished()).To(BeTrue())
})
It("is finished after being locally reset and receiving a RST in response", func() {
str.Reset(testErr)
Expect(str.finished()).To(BeFalse())
str.RegisterRemoteError(testErr)
Expect(str.finished()).To(BeTrue())
})
It("is finished after finishing writing and receiving a RST", func() {
str.Close()
str.sentFin()
str.RegisterRemoteError(testErr)
Expect(str.finished()).To(BeTrue())
})
It("is finished after finishing reading and being locally reset", func() {
finishReading()
Expect(str.finished()).To(BeFalse())
str.Reset(testErr)
Expect(str.finished()).To(BeTrue())
})
})
})