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
This commit is contained in:
Jean-Francois Giorgi 2023-04-08 06:53:14 +02:00 committed by GitHub
parent c9ae152956
commit af517bdef1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 113 additions and 113 deletions

View file

@ -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
}

View file

@ -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())

View file

@ -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)

View file

@ -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()

View file

@ -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))

View file

@ -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"))
})
})

View file

@ -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{}
}

View file

@ -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)
})