forked from quic-go/quic-go
use application-specific CONNECTION_CLOSE for application errors
This commit is contained in:
@@ -39,6 +39,7 @@ func CryptoError(tlsAlert uint8, errorMessage string) *QuicError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApplicationError creates a new QuicError instance for an application error
|
||||||
func ApplicationError(errorCode ErrorCode, errorMessage string) *QuicError {
|
func ApplicationError(errorCode ErrorCode, errorMessage string) *QuicError {
|
||||||
return &QuicError{
|
return &QuicError{
|
||||||
ErrorCode: errorCode,
|
ErrorCode: errorCode,
|
||||||
@@ -65,6 +66,11 @@ func (e *QuicError) IsCryptoError() bool {
|
|||||||
return e.ErrorCode.isCryptoError()
|
return e.ErrorCode.isCryptoError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsApplicationError says if this error is an application error
|
||||||
|
func (e *QuicError) IsApplicationError() bool {
|
||||||
|
return e.isApplicationError
|
||||||
|
}
|
||||||
|
|
||||||
// Temporary says if the error is temporary.
|
// Temporary says if the error is temporary.
|
||||||
func (e *QuicError) Temporary() bool {
|
func (e *QuicError) Temporary() bool {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ var _ = Describe("QUIC Transport Errors", func() {
|
|||||||
It("has a string representation", func() {
|
It("has a string representation", func() {
|
||||||
err := Error(FlowControlError, "foobar")
|
err := Error(FlowControlError, "foobar")
|
||||||
Expect(err.Timeout()).To(BeFalse())
|
Expect(err.Timeout()).To(BeFalse())
|
||||||
|
Expect(err.IsApplicationError()).To(BeFalse())
|
||||||
Expect(err.Error()).To(Equal("FLOW_CONTROL_ERROR: foobar"))
|
Expect(err.Error()).To(Equal("FLOW_CONTROL_ERROR: foobar"))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -38,13 +39,17 @@ var _ = Describe("QUIC Transport Errors", func() {
|
|||||||
|
|
||||||
It("says if an error is a crypto error", func() {
|
It("says if an error is a crypto error", func() {
|
||||||
Expect(Error(FlowControlError, "").IsCryptoError()).To(BeFalse())
|
Expect(Error(FlowControlError, "").IsCryptoError()).To(BeFalse())
|
||||||
Expect(CryptoError(42, "").IsCryptoError()).To(BeTrue())
|
err := CryptoError(42, "")
|
||||||
|
Expect(err.IsCryptoError()).To(BeTrue())
|
||||||
|
Expect(err.IsApplicationError()).To(BeFalse())
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("application errors", func() {
|
Context("application errors", func() {
|
||||||
It("has a string representation for errors with a message", func() {
|
It("has a string representation for errors with a message", func() {
|
||||||
err := ApplicationError(0x42, "foobar")
|
err := ApplicationError(0x42, "foobar")
|
||||||
|
Expect(err.IsApplicationError()).To(BeTrue())
|
||||||
Expect(err.Error()).To(Equal("Application error 0x42: foobar"))
|
Expect(err.Error()).To(Equal("Application error 0x42: foobar"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1023,7 +1023,7 @@ func (s *session) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) CloseWithError(code protocol.ApplicationErrorCode, desc string) error {
|
func (s *session) CloseWithError(code protocol.ApplicationErrorCode, desc string) error {
|
||||||
s.closeLocal(qerr.Error(qerr.ErrorCode(code), desc))
|
s.closeLocal(qerr.ApplicationError(qerr.ErrorCode(code), desc))
|
||||||
<-s.ctx.Done()
|
<-s.ctx.Done()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1250,8 +1250,9 @@ func (s *session) sendConnectionClose(quicErr *qerr.QuicError) ([]byte, error) {
|
|||||||
reason = quicErr.ErrorMessage
|
reason = quicErr.ErrorMessage
|
||||||
}
|
}
|
||||||
packet, err := s.packer.PackConnectionClose(&wire.ConnectionCloseFrame{
|
packet, err := s.packer.PackConnectionClose(&wire.ConnectionCloseFrame{
|
||||||
ErrorCode: quicErr.ErrorCode,
|
IsApplicationError: quicErr.IsApplicationError(),
|
||||||
ReasonPhrase: reason,
|
ErrorCode: quicErr.ErrorCode,
|
||||||
|
ReasonPhrase: reason,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -449,12 +449,17 @@ var _ = Describe("Session", func() {
|
|||||||
Expect(sess.Context().Done()).To(BeClosed())
|
Expect(sess.Context().Done()).To(BeClosed())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("closes streams with proper error", func() {
|
It("closes with an error", func() {
|
||||||
testErr := errors.New("test error")
|
testErr := errors.New("test error")
|
||||||
streamManager.EXPECT().CloseWithError(qerr.Error(0x1337, testErr.Error()))
|
streamManager.EXPECT().CloseWithError(qerr.ApplicationError(0x1337, testErr.Error()))
|
||||||
expectReplaceWithClosed()
|
expectReplaceWithClosed()
|
||||||
cryptoSetup.EXPECT().Close()
|
cryptoSetup.EXPECT().Close()
|
||||||
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&packedPacket{}, nil)
|
packer.EXPECT().PackConnectionClose(gomock.Any()).DoAndReturn(func(f *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
||||||
|
Expect(f.IsApplicationError).To(BeTrue())
|
||||||
|
Expect(f.ErrorCode).To(BeEquivalentTo(0x1337))
|
||||||
|
Expect(f.ReasonPhrase).To(Equal("test error"))
|
||||||
|
return &packedPacket{}, nil
|
||||||
|
})
|
||||||
sess.CloseWithError(0x1337, testErr.Error())
|
sess.CloseWithError(0x1337, testErr.Error())
|
||||||
Eventually(areSessionsRunning).Should(BeFalse())
|
Eventually(areSessionsRunning).Should(BeFalse())
|
||||||
Expect(sess.Context().Done()).To(BeClosed())
|
Expect(sess.Context().Done()).To(BeClosed())
|
||||||
@@ -1203,7 +1208,7 @@ var _ = Describe("Session", func() {
|
|||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
cryptoSetup.EXPECT().RunHandshake().MaxTimes(1)
|
cryptoSetup.EXPECT().RunHandshake().MaxTimes(1)
|
||||||
err := sess.run()
|
err := sess.run()
|
||||||
Expect(err).To(MatchError(qerr.Error(0x1337, testErr.Error())))
|
Expect(err).To(MatchError(qerr.ApplicationError(0x1337, testErr.Error())))
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
|
|||||||
Reference in New Issue
Block a user