mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-01 19:27:35 +03:00
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:
parent
c9ae152956
commit
af517bdef1
8 changed files with 113 additions and 113 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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"))
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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{}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue