From af517bdef10a483bacd5eb96e67ebca4e4e151b2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Giorgi Date: Sat, 8 Apr 2023 06:53:14 +0200 Subject: [PATCH] http3: make error codes public and consistent with http2 package (#3744) * make http3 error codes public and consistent with http2 package * typo on ErrNoError * renaming of ErrCode values --- http3/body.go | 4 +-- http3/body_test.go | 4 +-- http3/client.go | 38 ++++++++++---------- http3/client_test.go | 32 ++++++++--------- http3/error_codes.go | 76 +++++++++++++++++++-------------------- http3/error_codes_test.go | 4 +-- http3/server.go | 36 +++++++++---------- http3/server_test.go | 32 ++++++++--------- 8 files changed, 113 insertions(+), 113 deletions(-) diff --git a/http3/body.go b/http3/body.go index 15985a1c..63ff4366 100644 --- a/http3/body.go +++ b/http3/body.go @@ -67,7 +67,7 @@ func (r *body) Read(b []byte) (int, error) { } func (r *body) Close() error { - r.str.CancelRead(quic.StreamErrorCode(errorRequestCanceled)) + r.str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)) return nil } @@ -126,7 +126,7 @@ func (r *body) StreamID() quic.StreamID { func (r *hijackableBody) Close() error { r.requestDone() // If the EOF was read, CancelRead() is a no-op. - r.str.CancelRead(quic.StreamErrorCode(errorRequestCanceled)) + r.str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)) return nil } diff --git a/http3/body_test.go b/http3/body_test.go index 5ccb996a..5bcca2e9 100644 --- a/http3/body_test.go +++ b/http3/body_test.go @@ -39,14 +39,14 @@ var _ = Describe("Response Body", func() { It("closes responses", func() { str := mockquic.NewMockStream(mockCtrl) rb := newResponseBody(str, nil, reqDone) - str.EXPECT().CancelRead(quic.StreamErrorCode(errorRequestCanceled)) + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)) Expect(rb.Close()).To(Succeed()) }) It("allows multiple calls to Close", func() { str := mockquic.NewMockStream(mockCtrl) rb := newResponseBody(str, nil, reqDone) - str.EXPECT().CancelRead(quic.StreamErrorCode(errorRequestCanceled)).MaxTimes(2) + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)).MaxTimes(2) Expect(rb.Close()).To(Succeed()) Expect(reqDone).To(BeClosed()) Expect(rb.Close()).To(Succeed()) diff --git a/http3/client.go b/http3/client.go index 63200db8..bada6f04 100644 --- a/http3/client.go +++ b/http3/client.go @@ -124,7 +124,7 @@ func (c *client) dial(ctx context.Context) error { go func() { if err := c.setupConn(conn); err != nil { c.logger.Debugf("Setting up connection failed: %s", err) - conn.CloseWithError(quic.ApplicationErrorCode(errorInternalError), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeInternalError), "") } }() @@ -166,7 +166,7 @@ func (c *client) handleBidirectionalStreams(conn quic.EarlyConnection) { if err != nil { c.logger.Debugf("error handling stream: %s", err) } - conn.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "received HTTP/3 frame on bidirectional stream") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "received HTTP/3 frame on bidirectional stream") }(str) } } @@ -197,23 +197,23 @@ func (c *client) handleUnidirectionalStreams(conn quic.EarlyConnection) { return case streamTypePushStream: // We never increased the Push ID, so we don't expect any push streams. - conn.CloseWithError(quic.ApplicationErrorCode(errorIDError), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeIDError), "") return default: if c.opts.UniStreamHijacker != nil && c.opts.UniStreamHijacker(StreamType(streamType), conn, str, nil) { return } - str.CancelRead(quic.StreamErrorCode(errorStreamCreationError)) + str.CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)) return } f, err := parseNextFrame(str, nil) if err != nil { - conn.CloseWithError(quic.ApplicationErrorCode(errorFrameError), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameError), "") return } sf, ok := f.(*settingsFrame) if !ok { - conn.CloseWithError(quic.ApplicationErrorCode(errorMissingSettings), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeMissingSettings), "") return } if !sf.Datagram { @@ -223,7 +223,7 @@ func (c *client) handleUnidirectionalStreams(conn quic.EarlyConnection) { // we can expect it to have been negotiated both on the transport and on the HTTP/3 layer. // Note: ConnectionState() will block until the handshake is complete (relevant when using 0-RTT). if c.opts.EnableDatagram && !conn.ConnectionState().SupportsDatagrams { - conn.CloseWithError(quic.ApplicationErrorCode(errorSettingsError), "missing QUIC Datagram support") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeSettingsError), "missing QUIC Datagram support") } }(str) } @@ -234,7 +234,7 @@ func (c *client) Close() error { if conn == nil { return nil } - return (*conn).CloseWithError(quic.ApplicationErrorCode(errorNoError), "") + return (*conn).CloseWithError(quic.ApplicationErrorCode(ErrCodeNoError), "") } func (c *client) maxHeaderBytes() uint64 { @@ -286,8 +286,8 @@ func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Respon defer close(done) select { case <-req.Context().Done(): - str.CancelWrite(quic.StreamErrorCode(errorRequestCanceled)) - str.CancelRead(quic.StreamErrorCode(errorRequestCanceled)) + str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)) + str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)) case <-reqDone: } }() @@ -339,7 +339,7 @@ func (c *client) sendRequestBody(str Stream, body io.ReadCloser) error { if rerr == io.EOF { break } - str.CancelWrite(quic.StreamErrorCode(errorRequestCanceled)) + str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)) return rerr } } @@ -352,14 +352,14 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui requestGzip = true } if err := c.requestWriter.WriteRequestHeader(str, req, requestGzip); err != nil { - return nil, newStreamError(errorInternalError, err) + return nil, newStreamError(ErrCodeInternalError, err) } if req.Body == nil && !opt.DontCloseRequestStream { str.Close() } - hstr := newStream(str, func() { conn.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "") }) + hstr := newStream(str, func() { conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "") }) if req.Body != nil { // send the request body asynchronously go func() { @@ -374,23 +374,23 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui frame, err := parseNextFrame(str, nil) if err != nil { - return nil, newStreamError(errorFrameError, err) + return nil, newStreamError(ErrCodeFrameError, err) } hf, ok := frame.(*headersFrame) if !ok { - return nil, newConnError(errorFrameUnexpected, errors.New("expected first frame to be a HEADERS frame")) + return nil, newConnError(ErrCodeFrameUnexpected, errors.New("expected first frame to be a HEADERS frame")) } if hf.Length > c.maxHeaderBytes() { - return nil, newStreamError(errorFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, c.maxHeaderBytes())) + return nil, newStreamError(ErrCodeFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, c.maxHeaderBytes())) } headerBlock := make([]byte, hf.Length) if _, err := io.ReadFull(str, headerBlock); err != nil { - return nil, newStreamError(errorRequestIncomplete, err) + return nil, newStreamError(ErrCodeRequestIncomplete, err) } hfs, err := c.decoder.DecodeFull(headerBlock) if err != nil { // TODO: use the right error code - return nil, newConnError(errorGeneralProtocolError, err) + return nil, newConnError(ErrCodeGeneralProtocolError, err) } connState := qtls.ToTLSConnectionState(conn.ConnectionState().TLS) @@ -406,7 +406,7 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui case ":status": status, err := strconv.Atoi(hf.Value) if err != nil { - return nil, newStreamError(errorGeneralProtocolError, errors.New("malformed non-numeric status pseudo header")) + return nil, newStreamError(ErrCodeGeneralProtocolError, errors.New("malformed non-numeric status pseudo header")) } res.StatusCode = status res.Status = hf.Value + " " + http.StatusText(status) diff --git a/http3/client_test.go b/http3/client_test.go index ebea0047..9f249008 100644 --- a/http3/client_test.go +++ b/http3/client_test.go @@ -256,7 +256,7 @@ var _ = Describe("Client", func() { <-testDone return nil, errors.New("test done") }) - conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), gomock.Any()).Return(nil).AnyTimes() + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), gomock.Any()).Return(nil).AnyTimes() _, err := cl.RoundTripOpt(request, RoundTripOpt{}) Expect(err).To(MatchError("done")) Eventually(frameTypeChan).Should(Receive(BeEquivalentTo(0x41))) @@ -278,7 +278,7 @@ var _ = Describe("Client", func() { <-testDone return nil, errors.New("test done") }) - conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), gomock.Any()).Return(nil).AnyTimes() + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), gomock.Any()).Return(nil).AnyTimes() _, err := cl.RoundTripOpt(request, RoundTripOpt{}) Expect(err).To(MatchError("done")) Eventually(frameTypeChan).Should(Receive(BeEquivalentTo(0x41))) @@ -302,7 +302,7 @@ var _ = Describe("Client", func() { <-testDone return nil, errors.New("test done") }) - conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), gomock.Any()).Return(nil).AnyTimes() + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), gomock.Any()).Return(nil).AnyTimes() _, err := cl.RoundTripOpt(request, RoundTripOpt{}) Expect(err).To(MatchError("done")) Eventually(done).Should(BeClosed()) @@ -402,7 +402,7 @@ var _ = Describe("Client", func() { buf := bytes.NewBuffer(quicvarint.Append(nil, 0x54)) unknownStr := mockquic.NewMockStream(mockCtrl) unknownStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() - unknownStr.EXPECT().CancelRead(quic.StreamErrorCode(errorStreamCreationError)) + unknownStr.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)) conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) { return unknownStr, nil }) @@ -497,7 +497,7 @@ var _ = Describe("Client", func() { str := mockquic.NewMockStream(mockCtrl) str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() done := make(chan struct{}) - str.EXPECT().CancelRead(quic.StreamErrorCode(errorStreamCreationError)).Do(func(code quic.StreamErrorCode) { + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)).Do(func(code quic.StreamErrorCode) { close(done) }) @@ -529,7 +529,7 @@ var _ = Describe("Client", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(errorMissingSettings)) + Expect(code).To(BeEquivalentTo(ErrCodeMissingSettings)) close(done) }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) @@ -553,7 +553,7 @@ var _ = Describe("Client", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(errorFrameError)) + Expect(code).To(BeEquivalentTo(ErrCodeFrameError)) close(done) }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) @@ -575,7 +575,7 @@ var _ = Describe("Client", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(errorIDError)) + Expect(code).To(BeEquivalentTo(ErrCodeIDError)) close(done) }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) @@ -601,7 +601,7 @@ var _ = Describe("Client", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, reason string) { defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(errorSettingsError)) + Expect(code).To(BeEquivalentTo(ErrCodeSettingsError)) Expect(reason).To(Equal("missing QUIC Datagram support")) close(done) }) @@ -791,7 +791,7 @@ var _ = Describe("Client", func() { req.Body.(*mockBody).readErr = errors.New("testErr") done := make(chan struct{}) gomock.InOrder( - str.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestCanceled)).Do(func(quic.StreamErrorCode) { + str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) }), str.EXPECT().CancelWrite(gomock.Any()), @@ -831,7 +831,7 @@ var _ = Describe("Client", func() { It("closes the connection when the first frame is not a HEADERS frame", func() { b := (&dataFrame{Length: 0x42}).Append(nil) - conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), gomock.Any()) + conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), gomock.Any()) closed := make(chan struct{}) r := bytes.NewReader(b) str.EXPECT().Close().Do(func() { close(closed) }) @@ -844,7 +844,7 @@ var _ = Describe("Client", func() { It("cancels the stream when the HEADERS frame is too large", func() { b := (&headersFrame{Length: 1338}).Append(nil) r := bytes.NewReader(b) - str.EXPECT().CancelWrite(quic.StreamErrorCode(errorFrameError)) + str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeFrameError)) closed := make(chan struct{}) str.EXPECT().Close().Do(func() { close(closed) }) str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes() @@ -889,8 +889,8 @@ var _ = Describe("Client", func() { done := make(chan struct{}) canceled := make(chan struct{}) gomock.InOrder( - str.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestCanceled)).Do(func(quic.StreamErrorCode) { close(canceled) }), - str.EXPECT().CancelRead(quic.StreamErrorCode(errorRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) }), + str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)).Do(func(quic.StreamErrorCode) { close(canceled) }), + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) }), ) str.EXPECT().CancelWrite(gomock.Any()).MaxTimes(1) str.EXPECT().Read(gomock.Any()).DoAndReturn(func([]byte) (int, error) { @@ -919,8 +919,8 @@ var _ = Describe("Client", func() { done := make(chan struct{}) str.EXPECT().Write(gomock.Any()).DoAndReturn(buf.Write) str.EXPECT().Read(gomock.Any()).DoAndReturn(rspBuf.Read).AnyTimes() - str.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestCanceled)) - str.EXPECT().CancelRead(quic.StreamErrorCode(errorRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) }) + str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)) + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) }) _, err := cl.RoundTripOpt(req, RoundTripOpt{}) Expect(err).ToNot(HaveOccurred()) cancel() diff --git a/http3/error_codes.go b/http3/error_codes.go index 5df9b5df..67b215d8 100644 --- a/http3/error_codes.go +++ b/http3/error_codes.go @@ -6,66 +6,66 @@ import ( "github.com/quic-go/quic-go" ) -type errorCode quic.ApplicationErrorCode +type ErrCode quic.ApplicationErrorCode const ( - errorNoError errorCode = 0x100 - errorGeneralProtocolError errorCode = 0x101 - errorInternalError errorCode = 0x102 - errorStreamCreationError errorCode = 0x103 - errorClosedCriticalStream errorCode = 0x104 - errorFrameUnexpected errorCode = 0x105 - errorFrameError errorCode = 0x106 - errorExcessiveLoad errorCode = 0x107 - errorIDError errorCode = 0x108 - errorSettingsError errorCode = 0x109 - errorMissingSettings errorCode = 0x10a - errorRequestRejected errorCode = 0x10b - errorRequestCanceled errorCode = 0x10c - errorRequestIncomplete errorCode = 0x10d - errorMessageError errorCode = 0x10e - errorConnectError errorCode = 0x10f - errorVersionFallback errorCode = 0x110 - errorDatagramError errorCode = 0x4a1268 + ErrCodeNoError ErrCode = 0x100 + ErrCodeGeneralProtocolError ErrCode = 0x101 + ErrCodeInternalError ErrCode = 0x102 + ErrCodeStreamCreationError ErrCode = 0x103 + ErrCodeClosedCriticalStream ErrCode = 0x104 + ErrCodeFrameUnexpected ErrCode = 0x105 + ErrCodeFrameError ErrCode = 0x106 + ErrCodeExcessiveLoad ErrCode = 0x107 + ErrCodeIDError ErrCode = 0x108 + ErrCodeSettingsError ErrCode = 0x109 + ErrCodeMissingSettings ErrCode = 0x10a + ErrCodeRequestRejected ErrCode = 0x10b + ErrCodeRequestCanceled ErrCode = 0x10c + ErrCodeRequestIncomplete ErrCode = 0x10d + ErrCodeMessageError ErrCode = 0x10e + ErrCodeConnectError ErrCode = 0x10f + ErrCodeVersionFallback ErrCode = 0x110 + ErrCodeDatagramError ErrCode = 0x4a1268 ) -func (e errorCode) String() string { +func (e ErrCode) String() string { switch e { - case errorNoError: + case ErrCodeNoError: return "H3_NO_ERROR" - case errorGeneralProtocolError: + case ErrCodeGeneralProtocolError: return "H3_GENERAL_PROTOCOL_ERROR" - case errorInternalError: + case ErrCodeInternalError: return "H3_INTERNAL_ERROR" - case errorStreamCreationError: + case ErrCodeStreamCreationError: return "H3_STREAM_CREATION_ERROR" - case errorClosedCriticalStream: + case ErrCodeClosedCriticalStream: return "H3_CLOSED_CRITICAL_STREAM" - case errorFrameUnexpected: + case ErrCodeFrameUnexpected: return "H3_FRAME_UNEXPECTED" - case errorFrameError: + case ErrCodeFrameError: return "H3_FRAME_ERROR" - case errorExcessiveLoad: + case ErrCodeExcessiveLoad: return "H3_EXCESSIVE_LOAD" - case errorIDError: + case ErrCodeIDError: return "H3_ID_ERROR" - case errorSettingsError: + case ErrCodeSettingsError: return "H3_SETTINGS_ERROR" - case errorMissingSettings: + case ErrCodeMissingSettings: return "H3_MISSING_SETTINGS" - case errorRequestRejected: + case ErrCodeRequestRejected: return "H3_REQUEST_REJECTED" - case errorRequestCanceled: + case ErrCodeRequestCanceled: return "H3_REQUEST_CANCELLED" - case errorRequestIncomplete: + case ErrCodeRequestIncomplete: return "H3_INCOMPLETE_REQUEST" - case errorMessageError: + case ErrCodeMessageError: return "H3_MESSAGE_ERROR" - case errorConnectError: + case ErrCodeConnectError: return "H3_CONNECT_ERROR" - case errorVersionFallback: + case ErrCodeVersionFallback: return "H3_VERSION_FALLBACK" - case errorDatagramError: + case ErrCodeDatagramError: return "H3_DATAGRAM_ERROR" default: return fmt.Sprintf("unknown error code: %#x", uint16(e)) diff --git a/http3/error_codes_test.go b/http3/error_codes_test.go index 62b4716b..a50afc60 100644 --- a/http3/error_codes_test.go +++ b/http3/error_codes_test.go @@ -29,11 +29,11 @@ var _ = Describe("error codes", func() { valString := c.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value val, err := strconv.ParseInt(valString, 0, 64) Expect(err).NotTo(HaveOccurred()) - Expect(errorCode(val).String()).ToNot(Equal("unknown error code")) + Expect(ErrCode(val).String()).ToNot(Equal("unknown error code")) } }) It("has a string representation for unknown error codes", func() { - Expect(errorCode(0x1337).String()).To(Equal("unknown error code: 0x1337")) + Expect(ErrCode(0x1337).String()).To(Equal("unknown error code: 0x1337")) }) }) diff --git a/http3/server.go b/http3/server.go index 69a186d7..bdc5a43c 100644 --- a/http3/server.go +++ b/http3/server.go @@ -107,15 +107,15 @@ var ServerContextKey = &contextKey{"http3-server"} type requestError struct { err error - streamErr errorCode - connErr errorCode + streamErr ErrCode + connErr ErrCode } -func newStreamError(code errorCode, err error) requestError { +func newStreamError(code ErrCode, err error) requestError { return requestError{err: err, streamErr: code} } -func newConnError(code errorCode, err error) requestError { +func newConnError(code ErrCode, err error) requestError { return requestError{err: err, connErr: code} } @@ -442,14 +442,14 @@ func (s *Server) handleConn(conn quic.Connection) error { str, err := conn.AcceptStream(context.Background()) if err != nil { var appErr *quic.ApplicationError - if errors.As(err, &appErr) && appErr.ErrorCode == quic.ApplicationErrorCode(errorNoError) { + if errors.As(err, &appErr) && appErr.ErrorCode == quic.ApplicationErrorCode(ErrCodeNoError) { return nil } return fmt.Errorf("accepting stream failed: %w", err) } go func() { rerr := s.handleRequest(conn, str, decoder, func() { - conn.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "") }) if rerr.err == errHijacked { return @@ -498,23 +498,23 @@ func (s *Server) handleUnidirectionalStreams(conn quic.Connection) { // TODO: check that only one stream of each type is opened. return case streamTypePushStream: // only the server can push - conn.CloseWithError(quic.ApplicationErrorCode(errorStreamCreationError), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeStreamCreationError), "") return default: if s.UniStreamHijacker != nil && s.UniStreamHijacker(StreamType(streamType), conn, str, nil) { return } - str.CancelRead(quic.StreamErrorCode(errorStreamCreationError)) + str.CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)) return } f, err := parseNextFrame(str, nil) if err != nil { - conn.CloseWithError(quic.ApplicationErrorCode(errorFrameError), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameError), "") return } sf, ok := f.(*settingsFrame) if !ok { - conn.CloseWithError(quic.ApplicationErrorCode(errorMissingSettings), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeMissingSettings), "") return } if !sf.Datagram { @@ -524,7 +524,7 @@ func (s *Server) handleUnidirectionalStreams(conn quic.Connection) { // we can expect it to have been negotiated both on the transport and on the HTTP/3 layer. // Note: ConnectionState() will block until the handshake is complete (relevant when using 0-RTT). if s.EnableDatagrams && !conn.ConnectionState().SupportsDatagrams { - conn.CloseWithError(quic.ApplicationErrorCode(errorSettingsError), "missing QUIC Datagram support") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeSettingsError), "missing QUIC Datagram support") } }(str) } @@ -547,28 +547,28 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q if err == errHijacked { return requestError{err: errHijacked} } - return newStreamError(errorRequestIncomplete, err) + return newStreamError(ErrCodeRequestIncomplete, err) } hf, ok := frame.(*headersFrame) if !ok { - return newConnError(errorFrameUnexpected, errors.New("expected first frame to be a HEADERS frame")) + return newConnError(ErrCodeFrameUnexpected, errors.New("expected first frame to be a HEADERS frame")) } if hf.Length > s.maxHeaderBytes() { - return newStreamError(errorFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, s.maxHeaderBytes())) + return newStreamError(ErrCodeFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, s.maxHeaderBytes())) } headerBlock := make([]byte, hf.Length) if _, err := io.ReadFull(str, headerBlock); err != nil { - return newStreamError(errorRequestIncomplete, err) + return newStreamError(ErrCodeRequestIncomplete, err) } hfs, err := decoder.DecodeFull(headerBlock) if err != nil { // TODO: use the right error code - return newConnError(errorGeneralProtocolError, err) + return newConnError(ErrCodeGeneralProtocolError, err) } req, err := requestFromHeaders(hfs) if err != nil { // TODO: use the right error code - return newStreamError(errorGeneralProtocolError, err) + return newStreamError(ErrCodeGeneralProtocolError, err) } connState := conn.ConnectionState().TLS.ConnectionState @@ -622,7 +622,7 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q r.WriteHeader(http.StatusOK) } // If the EOF was read by the handler, CancelRead() is a no-op. - str.CancelRead(quic.StreamErrorCode(errorNoError)) + str.CancelRead(quic.StreamErrorCode(ErrCodeNoError)) return requestError{} } diff --git a/http3/server_test.go b/http3/server_test.go index be1dac3a..3f288f9f 100644 --- a/http3/server_test.go +++ b/http3/server_test.go @@ -272,7 +272,7 @@ var _ = Describe("Server", func() { buf := bytes.NewBuffer(quicvarint.Append(nil, 0x41)) unknownStr := mockquic.NewMockStream(mockCtrl) unknownStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() - unknownStr.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestIncomplete)) + unknownStr.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestIncomplete)) conn.EXPECT().AcceptStream(gomock.Any()).Return(unknownStr, nil) conn.EXPECT().AcceptStream(gomock.Any()).Return(nil, errors.New("done")) conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) { @@ -295,7 +295,7 @@ var _ = Describe("Server", func() { buf := bytes.NewBuffer(quicvarint.Append(nil, 0x41)) unknownStr := mockquic.NewMockStream(mockCtrl) unknownStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() - unknownStr.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestIncomplete)) + unknownStr.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestIncomplete)) conn.EXPECT().AcceptStream(gomock.Any()).Return(unknownStr, nil) conn.EXPECT().AcceptStream(gomock.Any()).Return(nil, errors.New("done")) conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) { @@ -406,7 +406,7 @@ var _ = Describe("Server", func() { buf := bytes.NewBuffer(quicvarint.Append(nil, 0x54)) unknownStr := mockquic.NewMockStream(mockCtrl) unknownStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() - unknownStr.EXPECT().CancelRead(quic.StreamErrorCode(errorStreamCreationError)) + unknownStr.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)) conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) { return unknownStr, nil @@ -483,7 +483,7 @@ var _ = Describe("Server", func() { str := mockquic.NewMockStream(mockCtrl) str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() done := make(chan struct{}) - str.EXPECT().CancelRead(quic.StreamErrorCode(errorStreamCreationError)).Do(func(code quic.StreamErrorCode) { + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)).Do(func(code quic.StreamErrorCode) { close(done) }) @@ -514,7 +514,7 @@ var _ = Describe("Server", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(errorMissingSettings)) + Expect(code).To(BeEquivalentTo(ErrCodeMissingSettings)) close(done) }) s.handleConn(conn) @@ -537,7 +537,7 @@ var _ = Describe("Server", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(errorFrameError)) + Expect(code).To(BeEquivalentTo(ErrCodeFrameError)) close(done) }) s.handleConn(conn) @@ -560,7 +560,7 @@ var _ = Describe("Server", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(errorStreamCreationError)) + Expect(code).To(BeEquivalentTo(ErrCodeStreamCreationError)) close(done) }) s.handleConn(conn) @@ -585,7 +585,7 @@ var _ = Describe("Server", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, reason string) { defer GinkgoRecover() - Expect(code).To(BeEquivalentTo(errorSettingsError)) + Expect(code).To(BeEquivalentTo(ErrCodeSettingsError)) Expect(reason).To(Equal("missing QUIC Datagram support")) close(done) }) @@ -632,7 +632,7 @@ var _ = Describe("Server", func() { done := make(chan struct{}) str.EXPECT().Context().Return(reqContext) str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes() - str.EXPECT().CancelRead(quic.StreamErrorCode(errorNoError)) + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeNoError)) str.EXPECT().Close().Do(func() { close(done) }) s.handleConn(conn) @@ -674,7 +674,7 @@ var _ = Describe("Server", func() { setRequest(append(requestData, b...)) done := make(chan struct{}) str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes() - str.EXPECT().CancelWrite(quic.StreamErrorCode(errorFrameError)).Do(func(quic.StreamErrorCode) { close(done) }) + str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeFrameError)).Do(func(quic.StreamErrorCode) { close(done) }) s.handleConn(conn) Eventually(done).Should(BeClosed()) @@ -689,7 +689,7 @@ var _ = Describe("Server", func() { testErr := errors.New("stream reset") done := make(chan struct{}) str.EXPECT().Read(gomock.Any()).Return(0, testErr) - str.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestIncomplete)).Do(func(quic.StreamErrorCode) { close(done) }) + str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestIncomplete)).Do(func(quic.StreamErrorCode) { close(done) }) s.handleConn(conn) Consistently(handlerCalled).ShouldNot(BeClosed()) @@ -709,7 +709,7 @@ var _ = Describe("Server", func() { done := make(chan struct{}) conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) { - Expect(code).To(Equal(quic.ApplicationErrorCode(errorFrameUnexpected))) + Expect(code).To(Equal(quic.ApplicationErrorCode(ErrCodeFrameUnexpected))) close(done) }) s.handleConn(conn) @@ -733,7 +733,7 @@ var _ = Describe("Server", func() { return len(p), nil }).AnyTimes() done := make(chan struct{}) - str.EXPECT().CancelWrite(quic.StreamErrorCode(errorFrameError)).Do(func(quic.StreamErrorCode) { close(done) }) + str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeFrameError)).Do(func(quic.StreamErrorCode) { close(done) }) s.handleConn(conn) Eventually(done).Should(BeClosed()) @@ -755,7 +755,7 @@ var _ = Describe("Server", func() { str.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) { return len(p), nil }).AnyTimes() - str.EXPECT().CancelRead(quic.StreamErrorCode(errorNoError)) + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeNoError)) serr := s.handleRequest(conn, str, qpackDecoder, nil) Expect(serr.err).ToNot(HaveOccurred()) @@ -778,7 +778,7 @@ var _ = Describe("Server", func() { str.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) { return len(p), nil }).AnyTimes() - str.EXPECT().CancelRead(quic.StreamErrorCode(errorNoError)) + str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeNoError)) serr := s.handleRequest(conn, str, qpackDecoder, nil) Expect(serr.err).ToNot(HaveOccurred()) @@ -1207,7 +1207,7 @@ var _ = Describe("Server", func() { <-testDone return nil, errors.New("test done") }).MaxTimes(1) - conn.EXPECT().AcceptStream(gomock.Any()).Return(nil, &quic.ApplicationError{ErrorCode: quic.ApplicationErrorCode(errorNoError)}) + conn.EXPECT().AcceptStream(gomock.Any()).Return(nil, &quic.ApplicationError{ErrorCode: quic.ApplicationErrorCode(ErrCodeNoError)}) s.ServeQUICConn(conn) close(testDone) })