mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +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 {
|
func (r *body) Close() error {
|
||||||
r.str.CancelRead(quic.StreamErrorCode(errorRequestCanceled))
|
r.str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ func (r *body) StreamID() quic.StreamID {
|
||||||
func (r *hijackableBody) Close() error {
|
func (r *hijackableBody) Close() error {
|
||||||
r.requestDone()
|
r.requestDone()
|
||||||
// If the EOF was read, CancelRead() is a no-op.
|
// If the EOF was read, CancelRead() is a no-op.
|
||||||
r.str.CancelRead(quic.StreamErrorCode(errorRequestCanceled))
|
r.str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,14 +39,14 @@ var _ = Describe("Response Body", func() {
|
||||||
It("closes responses", func() {
|
It("closes responses", func() {
|
||||||
str := mockquic.NewMockStream(mockCtrl)
|
str := mockquic.NewMockStream(mockCtrl)
|
||||||
rb := newResponseBody(str, nil, reqDone)
|
rb := newResponseBody(str, nil, reqDone)
|
||||||
str.EXPECT().CancelRead(quic.StreamErrorCode(errorRequestCanceled))
|
str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled))
|
||||||
Expect(rb.Close()).To(Succeed())
|
Expect(rb.Close()).To(Succeed())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("allows multiple calls to Close", func() {
|
It("allows multiple calls to Close", func() {
|
||||||
str := mockquic.NewMockStream(mockCtrl)
|
str := mockquic.NewMockStream(mockCtrl)
|
||||||
rb := newResponseBody(str, nil, reqDone)
|
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(rb.Close()).To(Succeed())
|
||||||
Expect(reqDone).To(BeClosed())
|
Expect(reqDone).To(BeClosed())
|
||||||
Expect(rb.Close()).To(Succeed())
|
Expect(rb.Close()).To(Succeed())
|
||||||
|
|
|
@ -124,7 +124,7 @@ func (c *client) dial(ctx context.Context) error {
|
||||||
go func() {
|
go func() {
|
||||||
if err := c.setupConn(conn); err != nil {
|
if err := c.setupConn(conn); err != nil {
|
||||||
c.logger.Debugf("Setting up connection failed: %s", err)
|
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 {
|
if err != nil {
|
||||||
c.logger.Debugf("error handling stream: %s", err)
|
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)
|
}(str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,23 +197,23 @@ func (c *client) handleUnidirectionalStreams(conn quic.EarlyConnection) {
|
||||||
return
|
return
|
||||||
case streamTypePushStream:
|
case streamTypePushStream:
|
||||||
// We never increased the Push ID, so we don't expect any push streams.
|
// 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
|
return
|
||||||
default:
|
default:
|
||||||
if c.opts.UniStreamHijacker != nil && c.opts.UniStreamHijacker(StreamType(streamType), conn, str, nil) {
|
if c.opts.UniStreamHijacker != nil && c.opts.UniStreamHijacker(StreamType(streamType), conn, str, nil) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
str.CancelRead(quic.StreamErrorCode(errorStreamCreationError))
|
str.CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f, err := parseNextFrame(str, nil)
|
f, err := parseNextFrame(str, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.CloseWithError(quic.ApplicationErrorCode(errorFrameError), "")
|
conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameError), "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sf, ok := f.(*settingsFrame)
|
sf, ok := f.(*settingsFrame)
|
||||||
if !ok {
|
if !ok {
|
||||||
conn.CloseWithError(quic.ApplicationErrorCode(errorMissingSettings), "")
|
conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeMissingSettings), "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !sf.Datagram {
|
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.
|
// 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).
|
// Note: ConnectionState() will block until the handshake is complete (relevant when using 0-RTT).
|
||||||
if c.opts.EnableDatagram && !conn.ConnectionState().SupportsDatagrams {
|
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)
|
}(str)
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ func (c *client) Close() error {
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return (*conn).CloseWithError(quic.ApplicationErrorCode(errorNoError), "")
|
return (*conn).CloseWithError(quic.ApplicationErrorCode(ErrCodeNoError), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) maxHeaderBytes() uint64 {
|
func (c *client) maxHeaderBytes() uint64 {
|
||||||
|
@ -286,8 +286,8 @@ func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Respon
|
||||||
defer close(done)
|
defer close(done)
|
||||||
select {
|
select {
|
||||||
case <-req.Context().Done():
|
case <-req.Context().Done():
|
||||||
str.CancelWrite(quic.StreamErrorCode(errorRequestCanceled))
|
str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled))
|
||||||
str.CancelRead(quic.StreamErrorCode(errorRequestCanceled))
|
str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled))
|
||||||
case <-reqDone:
|
case <-reqDone:
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -339,7 +339,7 @@ func (c *client) sendRequestBody(str Stream, body io.ReadCloser) error {
|
||||||
if rerr == io.EOF {
|
if rerr == io.EOF {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
str.CancelWrite(quic.StreamErrorCode(errorRequestCanceled))
|
str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled))
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,14 +352,14 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui
|
||||||
requestGzip = true
|
requestGzip = true
|
||||||
}
|
}
|
||||||
if err := c.requestWriter.WriteRequestHeader(str, req, requestGzip); err != nil {
|
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 {
|
if req.Body == nil && !opt.DontCloseRequestStream {
|
||||||
str.Close()
|
str.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
hstr := newStream(str, func() { conn.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "") })
|
hstr := newStream(str, func() { conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "") })
|
||||||
if req.Body != nil {
|
if req.Body != nil {
|
||||||
// send the request body asynchronously
|
// send the request body asynchronously
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -374,23 +374,23 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui
|
||||||
|
|
||||||
frame, err := parseNextFrame(str, nil)
|
frame, err := parseNextFrame(str, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newStreamError(errorFrameError, err)
|
return nil, newStreamError(ErrCodeFrameError, err)
|
||||||
}
|
}
|
||||||
hf, ok := frame.(*headersFrame)
|
hf, ok := frame.(*headersFrame)
|
||||||
if !ok {
|
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() {
|
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)
|
headerBlock := make([]byte, hf.Length)
|
||||||
if _, err := io.ReadFull(str, headerBlock); err != nil {
|
if _, err := io.ReadFull(str, headerBlock); err != nil {
|
||||||
return nil, newStreamError(errorRequestIncomplete, err)
|
return nil, newStreamError(ErrCodeRequestIncomplete, err)
|
||||||
}
|
}
|
||||||
hfs, err := c.decoder.DecodeFull(headerBlock)
|
hfs, err := c.decoder.DecodeFull(headerBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: use the right error code
|
// TODO: use the right error code
|
||||||
return nil, newConnError(errorGeneralProtocolError, err)
|
return nil, newConnError(ErrCodeGeneralProtocolError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
connState := qtls.ToTLSConnectionState(conn.ConnectionState().TLS)
|
connState := qtls.ToTLSConnectionState(conn.ConnectionState().TLS)
|
||||||
|
@ -406,7 +406,7 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui
|
||||||
case ":status":
|
case ":status":
|
||||||
status, err := strconv.Atoi(hf.Value)
|
status, err := strconv.Atoi(hf.Value)
|
||||||
if err != nil {
|
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.StatusCode = status
|
||||||
res.Status = hf.Value + " " + http.StatusText(status)
|
res.Status = hf.Value + " " + http.StatusText(status)
|
||||||
|
|
|
@ -256,7 +256,7 @@ var _ = Describe("Client", func() {
|
||||||
<-testDone
|
<-testDone
|
||||||
return nil, errors.New("test done")
|
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{})
|
_, err := cl.RoundTripOpt(request, RoundTripOpt{})
|
||||||
Expect(err).To(MatchError("done"))
|
Expect(err).To(MatchError("done"))
|
||||||
Eventually(frameTypeChan).Should(Receive(BeEquivalentTo(0x41)))
|
Eventually(frameTypeChan).Should(Receive(BeEquivalentTo(0x41)))
|
||||||
|
@ -278,7 +278,7 @@ var _ = Describe("Client", func() {
|
||||||
<-testDone
|
<-testDone
|
||||||
return nil, errors.New("test done")
|
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{})
|
_, err := cl.RoundTripOpt(request, RoundTripOpt{})
|
||||||
Expect(err).To(MatchError("done"))
|
Expect(err).To(MatchError("done"))
|
||||||
Eventually(frameTypeChan).Should(Receive(BeEquivalentTo(0x41)))
|
Eventually(frameTypeChan).Should(Receive(BeEquivalentTo(0x41)))
|
||||||
|
@ -302,7 +302,7 @@ var _ = Describe("Client", func() {
|
||||||
<-testDone
|
<-testDone
|
||||||
return nil, errors.New("test done")
|
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{})
|
_, err := cl.RoundTripOpt(request, RoundTripOpt{})
|
||||||
Expect(err).To(MatchError("done"))
|
Expect(err).To(MatchError("done"))
|
||||||
Eventually(done).Should(BeClosed())
|
Eventually(done).Should(BeClosed())
|
||||||
|
@ -402,7 +402,7 @@ var _ = Describe("Client", func() {
|
||||||
buf := bytes.NewBuffer(quicvarint.Append(nil, 0x54))
|
buf := bytes.NewBuffer(quicvarint.Append(nil, 0x54))
|
||||||
unknownStr := mockquic.NewMockStream(mockCtrl)
|
unknownStr := mockquic.NewMockStream(mockCtrl)
|
||||||
unknownStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
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) {
|
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
|
||||||
return unknownStr, nil
|
return unknownStr, nil
|
||||||
})
|
})
|
||||||
|
@ -497,7 +497,7 @@ var _ = Describe("Client", func() {
|
||||||
str := mockquic.NewMockStream(mockCtrl)
|
str := mockquic.NewMockStream(mockCtrl)
|
||||||
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
||||||
done := make(chan struct{})
|
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)
|
close(done)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ var _ = Describe("Client", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
Expect(code).To(BeEquivalentTo(errorMissingSettings))
|
Expect(code).To(BeEquivalentTo(ErrCodeMissingSettings))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
_, err := cl.RoundTripOpt(req, RoundTripOpt{})
|
_, err := cl.RoundTripOpt(req, RoundTripOpt{})
|
||||||
|
@ -553,7 +553,7 @@ var _ = Describe("Client", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
Expect(code).To(BeEquivalentTo(errorFrameError))
|
Expect(code).To(BeEquivalentTo(ErrCodeFrameError))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
_, err := cl.RoundTripOpt(req, RoundTripOpt{})
|
_, err := cl.RoundTripOpt(req, RoundTripOpt{})
|
||||||
|
@ -575,7 +575,7 @@ var _ = Describe("Client", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
Expect(code).To(BeEquivalentTo(errorIDError))
|
Expect(code).To(BeEquivalentTo(ErrCodeIDError))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
_, err := cl.RoundTripOpt(req, RoundTripOpt{})
|
_, err := cl.RoundTripOpt(req, RoundTripOpt{})
|
||||||
|
@ -601,7 +601,7 @@ var _ = Describe("Client", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, reason string) {
|
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, reason string) {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
Expect(code).To(BeEquivalentTo(errorSettingsError))
|
Expect(code).To(BeEquivalentTo(ErrCodeSettingsError))
|
||||||
Expect(reason).To(Equal("missing QUIC Datagram support"))
|
Expect(reason).To(Equal("missing QUIC Datagram support"))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
|
@ -791,7 +791,7 @@ var _ = Describe("Client", func() {
|
||||||
req.Body.(*mockBody).readErr = errors.New("testErr")
|
req.Body.(*mockBody).readErr = errors.New("testErr")
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
str.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestCanceled)).Do(func(quic.StreamErrorCode) {
|
str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)).Do(func(quic.StreamErrorCode) {
|
||||||
close(done)
|
close(done)
|
||||||
}),
|
}),
|
||||||
str.EXPECT().CancelWrite(gomock.Any()),
|
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() {
|
It("closes the connection when the first frame is not a HEADERS frame", func() {
|
||||||
b := (&dataFrame{Length: 0x42}).Append(nil)
|
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{})
|
closed := make(chan struct{})
|
||||||
r := bytes.NewReader(b)
|
r := bytes.NewReader(b)
|
||||||
str.EXPECT().Close().Do(func() { close(closed) })
|
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() {
|
It("cancels the stream when the HEADERS frame is too large", func() {
|
||||||
b := (&headersFrame{Length: 1338}).Append(nil)
|
b := (&headersFrame{Length: 1338}).Append(nil)
|
||||||
r := bytes.NewReader(b)
|
r := bytes.NewReader(b)
|
||||||
str.EXPECT().CancelWrite(quic.StreamErrorCode(errorFrameError))
|
str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeFrameError))
|
||||||
closed := make(chan struct{})
|
closed := make(chan struct{})
|
||||||
str.EXPECT().Close().Do(func() { close(closed) })
|
str.EXPECT().Close().Do(func() { close(closed) })
|
||||||
str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
|
str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
|
||||||
|
@ -889,8 +889,8 @@ var _ = Describe("Client", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
canceled := make(chan struct{})
|
canceled := make(chan struct{})
|
||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
str.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestCanceled)).Do(func(quic.StreamErrorCode) { close(canceled) }),
|
str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)).Do(func(quic.StreamErrorCode) { close(canceled) }),
|
||||||
str.EXPECT().CancelRead(quic.StreamErrorCode(errorRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) }),
|
str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) }),
|
||||||
)
|
)
|
||||||
str.EXPECT().CancelWrite(gomock.Any()).MaxTimes(1)
|
str.EXPECT().CancelWrite(gomock.Any()).MaxTimes(1)
|
||||||
str.EXPECT().Read(gomock.Any()).DoAndReturn(func([]byte) (int, error) {
|
str.EXPECT().Read(gomock.Any()).DoAndReturn(func([]byte) (int, error) {
|
||||||
|
@ -919,8 +919,8 @@ var _ = Describe("Client", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
str.EXPECT().Write(gomock.Any()).DoAndReturn(buf.Write)
|
str.EXPECT().Write(gomock.Any()).DoAndReturn(buf.Write)
|
||||||
str.EXPECT().Read(gomock.Any()).DoAndReturn(rspBuf.Read).AnyTimes()
|
str.EXPECT().Read(gomock.Any()).DoAndReturn(rspBuf.Read).AnyTimes()
|
||||||
str.EXPECT().CancelWrite(quic.StreamErrorCode(errorRequestCanceled))
|
str.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled))
|
||||||
str.EXPECT().CancelRead(quic.StreamErrorCode(errorRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) })
|
str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)).Do(func(quic.StreamErrorCode) { close(done) })
|
||||||
_, err := cl.RoundTripOpt(req, RoundTripOpt{})
|
_, err := cl.RoundTripOpt(req, RoundTripOpt{})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
cancel()
|
cancel()
|
||||||
|
|
|
@ -6,66 +6,66 @@ import (
|
||||||
"github.com/quic-go/quic-go"
|
"github.com/quic-go/quic-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
type errorCode quic.ApplicationErrorCode
|
type ErrCode quic.ApplicationErrorCode
|
||||||
|
|
||||||
const (
|
const (
|
||||||
errorNoError errorCode = 0x100
|
ErrCodeNoError ErrCode = 0x100
|
||||||
errorGeneralProtocolError errorCode = 0x101
|
ErrCodeGeneralProtocolError ErrCode = 0x101
|
||||||
errorInternalError errorCode = 0x102
|
ErrCodeInternalError ErrCode = 0x102
|
||||||
errorStreamCreationError errorCode = 0x103
|
ErrCodeStreamCreationError ErrCode = 0x103
|
||||||
errorClosedCriticalStream errorCode = 0x104
|
ErrCodeClosedCriticalStream ErrCode = 0x104
|
||||||
errorFrameUnexpected errorCode = 0x105
|
ErrCodeFrameUnexpected ErrCode = 0x105
|
||||||
errorFrameError errorCode = 0x106
|
ErrCodeFrameError ErrCode = 0x106
|
||||||
errorExcessiveLoad errorCode = 0x107
|
ErrCodeExcessiveLoad ErrCode = 0x107
|
||||||
errorIDError errorCode = 0x108
|
ErrCodeIDError ErrCode = 0x108
|
||||||
errorSettingsError errorCode = 0x109
|
ErrCodeSettingsError ErrCode = 0x109
|
||||||
errorMissingSettings errorCode = 0x10a
|
ErrCodeMissingSettings ErrCode = 0x10a
|
||||||
errorRequestRejected errorCode = 0x10b
|
ErrCodeRequestRejected ErrCode = 0x10b
|
||||||
errorRequestCanceled errorCode = 0x10c
|
ErrCodeRequestCanceled ErrCode = 0x10c
|
||||||
errorRequestIncomplete errorCode = 0x10d
|
ErrCodeRequestIncomplete ErrCode = 0x10d
|
||||||
errorMessageError errorCode = 0x10e
|
ErrCodeMessageError ErrCode = 0x10e
|
||||||
errorConnectError errorCode = 0x10f
|
ErrCodeConnectError ErrCode = 0x10f
|
||||||
errorVersionFallback errorCode = 0x110
|
ErrCodeVersionFallback ErrCode = 0x110
|
||||||
errorDatagramError errorCode = 0x4a1268
|
ErrCodeDatagramError ErrCode = 0x4a1268
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e errorCode) String() string {
|
func (e ErrCode) String() string {
|
||||||
switch e {
|
switch e {
|
||||||
case errorNoError:
|
case ErrCodeNoError:
|
||||||
return "H3_NO_ERROR"
|
return "H3_NO_ERROR"
|
||||||
case errorGeneralProtocolError:
|
case ErrCodeGeneralProtocolError:
|
||||||
return "H3_GENERAL_PROTOCOL_ERROR"
|
return "H3_GENERAL_PROTOCOL_ERROR"
|
||||||
case errorInternalError:
|
case ErrCodeInternalError:
|
||||||
return "H3_INTERNAL_ERROR"
|
return "H3_INTERNAL_ERROR"
|
||||||
case errorStreamCreationError:
|
case ErrCodeStreamCreationError:
|
||||||
return "H3_STREAM_CREATION_ERROR"
|
return "H3_STREAM_CREATION_ERROR"
|
||||||
case errorClosedCriticalStream:
|
case ErrCodeClosedCriticalStream:
|
||||||
return "H3_CLOSED_CRITICAL_STREAM"
|
return "H3_CLOSED_CRITICAL_STREAM"
|
||||||
case errorFrameUnexpected:
|
case ErrCodeFrameUnexpected:
|
||||||
return "H3_FRAME_UNEXPECTED"
|
return "H3_FRAME_UNEXPECTED"
|
||||||
case errorFrameError:
|
case ErrCodeFrameError:
|
||||||
return "H3_FRAME_ERROR"
|
return "H3_FRAME_ERROR"
|
||||||
case errorExcessiveLoad:
|
case ErrCodeExcessiveLoad:
|
||||||
return "H3_EXCESSIVE_LOAD"
|
return "H3_EXCESSIVE_LOAD"
|
||||||
case errorIDError:
|
case ErrCodeIDError:
|
||||||
return "H3_ID_ERROR"
|
return "H3_ID_ERROR"
|
||||||
case errorSettingsError:
|
case ErrCodeSettingsError:
|
||||||
return "H3_SETTINGS_ERROR"
|
return "H3_SETTINGS_ERROR"
|
||||||
case errorMissingSettings:
|
case ErrCodeMissingSettings:
|
||||||
return "H3_MISSING_SETTINGS"
|
return "H3_MISSING_SETTINGS"
|
||||||
case errorRequestRejected:
|
case ErrCodeRequestRejected:
|
||||||
return "H3_REQUEST_REJECTED"
|
return "H3_REQUEST_REJECTED"
|
||||||
case errorRequestCanceled:
|
case ErrCodeRequestCanceled:
|
||||||
return "H3_REQUEST_CANCELLED"
|
return "H3_REQUEST_CANCELLED"
|
||||||
case errorRequestIncomplete:
|
case ErrCodeRequestIncomplete:
|
||||||
return "H3_INCOMPLETE_REQUEST"
|
return "H3_INCOMPLETE_REQUEST"
|
||||||
case errorMessageError:
|
case ErrCodeMessageError:
|
||||||
return "H3_MESSAGE_ERROR"
|
return "H3_MESSAGE_ERROR"
|
||||||
case errorConnectError:
|
case ErrCodeConnectError:
|
||||||
return "H3_CONNECT_ERROR"
|
return "H3_CONNECT_ERROR"
|
||||||
case errorVersionFallback:
|
case ErrCodeVersionFallback:
|
||||||
return "H3_VERSION_FALLBACK"
|
return "H3_VERSION_FALLBACK"
|
||||||
case errorDatagramError:
|
case ErrCodeDatagramError:
|
||||||
return "H3_DATAGRAM_ERROR"
|
return "H3_DATAGRAM_ERROR"
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("unknown error code: %#x", uint16(e))
|
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
|
valString := c.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value
|
||||||
val, err := strconv.ParseInt(valString, 0, 64)
|
val, err := strconv.ParseInt(valString, 0, 64)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
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() {
|
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 {
|
type requestError struct {
|
||||||
err error
|
err error
|
||||||
streamErr errorCode
|
streamErr ErrCode
|
||||||
connErr errorCode
|
connErr ErrCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStreamError(code errorCode, err error) requestError {
|
func newStreamError(code ErrCode, err error) requestError {
|
||||||
return requestError{err: err, streamErr: code}
|
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}
|
return requestError{err: err, connErr: code}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,14 +442,14 @@ func (s *Server) handleConn(conn quic.Connection) error {
|
||||||
str, err := conn.AcceptStream(context.Background())
|
str, err := conn.AcceptStream(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var appErr *quic.ApplicationError
|
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 nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("accepting stream failed: %w", err)
|
return fmt.Errorf("accepting stream failed: %w", err)
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
rerr := s.handleRequest(conn, str, decoder, func() {
|
rerr := s.handleRequest(conn, str, decoder, func() {
|
||||||
conn.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "")
|
conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "")
|
||||||
})
|
})
|
||||||
if rerr.err == errHijacked {
|
if rerr.err == errHijacked {
|
||||||
return
|
return
|
||||||
|
@ -498,23 +498,23 @@ func (s *Server) handleUnidirectionalStreams(conn quic.Connection) {
|
||||||
// TODO: check that only one stream of each type is opened.
|
// TODO: check that only one stream of each type is opened.
|
||||||
return
|
return
|
||||||
case streamTypePushStream: // only the server can push
|
case streamTypePushStream: // only the server can push
|
||||||
conn.CloseWithError(quic.ApplicationErrorCode(errorStreamCreationError), "")
|
conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeStreamCreationError), "")
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
if s.UniStreamHijacker != nil && s.UniStreamHijacker(StreamType(streamType), conn, str, nil) {
|
if s.UniStreamHijacker != nil && s.UniStreamHijacker(StreamType(streamType), conn, str, nil) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
str.CancelRead(quic.StreamErrorCode(errorStreamCreationError))
|
str.CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f, err := parseNextFrame(str, nil)
|
f, err := parseNextFrame(str, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.CloseWithError(quic.ApplicationErrorCode(errorFrameError), "")
|
conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameError), "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sf, ok := f.(*settingsFrame)
|
sf, ok := f.(*settingsFrame)
|
||||||
if !ok {
|
if !ok {
|
||||||
conn.CloseWithError(quic.ApplicationErrorCode(errorMissingSettings), "")
|
conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeMissingSettings), "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !sf.Datagram {
|
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.
|
// 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).
|
// Note: ConnectionState() will block until the handshake is complete (relevant when using 0-RTT).
|
||||||
if s.EnableDatagrams && !conn.ConnectionState().SupportsDatagrams {
|
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)
|
}(str)
|
||||||
}
|
}
|
||||||
|
@ -547,28 +547,28 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q
|
||||||
if err == errHijacked {
|
if err == errHijacked {
|
||||||
return requestError{err: errHijacked}
|
return requestError{err: errHijacked}
|
||||||
}
|
}
|
||||||
return newStreamError(errorRequestIncomplete, err)
|
return newStreamError(ErrCodeRequestIncomplete, err)
|
||||||
}
|
}
|
||||||
hf, ok := frame.(*headersFrame)
|
hf, ok := frame.(*headersFrame)
|
||||||
if !ok {
|
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() {
|
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)
|
headerBlock := make([]byte, hf.Length)
|
||||||
if _, err := io.ReadFull(str, headerBlock); err != nil {
|
if _, err := io.ReadFull(str, headerBlock); err != nil {
|
||||||
return newStreamError(errorRequestIncomplete, err)
|
return newStreamError(ErrCodeRequestIncomplete, err)
|
||||||
}
|
}
|
||||||
hfs, err := decoder.DecodeFull(headerBlock)
|
hfs, err := decoder.DecodeFull(headerBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: use the right error code
|
// TODO: use the right error code
|
||||||
return newConnError(errorGeneralProtocolError, err)
|
return newConnError(ErrCodeGeneralProtocolError, err)
|
||||||
}
|
}
|
||||||
req, err := requestFromHeaders(hfs)
|
req, err := requestFromHeaders(hfs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: use the right error code
|
// TODO: use the right error code
|
||||||
return newStreamError(errorGeneralProtocolError, err)
|
return newStreamError(ErrCodeGeneralProtocolError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
connState := conn.ConnectionState().TLS.ConnectionState
|
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)
|
r.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
// If the EOF was read by the handler, CancelRead() is a no-op.
|
// 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{}
|
return requestError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ var _ = Describe("Server", func() {
|
||||||
buf := bytes.NewBuffer(quicvarint.Append(nil, 0x41))
|
buf := bytes.NewBuffer(quicvarint.Append(nil, 0x41))
|
||||||
unknownStr := mockquic.NewMockStream(mockCtrl)
|
unknownStr := mockquic.NewMockStream(mockCtrl)
|
||||||
unknownStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
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(unknownStr, nil)
|
||||||
conn.EXPECT().AcceptStream(gomock.Any()).Return(nil, errors.New("done"))
|
conn.EXPECT().AcceptStream(gomock.Any()).Return(nil, errors.New("done"))
|
||||||
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
|
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))
|
buf := bytes.NewBuffer(quicvarint.Append(nil, 0x41))
|
||||||
unknownStr := mockquic.NewMockStream(mockCtrl)
|
unknownStr := mockquic.NewMockStream(mockCtrl)
|
||||||
unknownStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
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(unknownStr, nil)
|
||||||
conn.EXPECT().AcceptStream(gomock.Any()).Return(nil, errors.New("done"))
|
conn.EXPECT().AcceptStream(gomock.Any()).Return(nil, errors.New("done"))
|
||||||
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
|
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))
|
buf := bytes.NewBuffer(quicvarint.Append(nil, 0x54))
|
||||||
unknownStr := mockquic.NewMockStream(mockCtrl)
|
unknownStr := mockquic.NewMockStream(mockCtrl)
|
||||||
unknownStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
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) {
|
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
|
||||||
return unknownStr, nil
|
return unknownStr, nil
|
||||||
|
@ -483,7 +483,7 @@ var _ = Describe("Server", func() {
|
||||||
str := mockquic.NewMockStream(mockCtrl)
|
str := mockquic.NewMockStream(mockCtrl)
|
||||||
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
||||||
done := make(chan struct{})
|
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)
|
close(done)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ var _ = Describe("Server", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
Expect(code).To(BeEquivalentTo(errorMissingSettings))
|
Expect(code).To(BeEquivalentTo(ErrCodeMissingSettings))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
s.handleConn(conn)
|
s.handleConn(conn)
|
||||||
|
@ -537,7 +537,7 @@ var _ = Describe("Server", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
Expect(code).To(BeEquivalentTo(errorFrameError))
|
Expect(code).To(BeEquivalentTo(ErrCodeFrameError))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
s.handleConn(conn)
|
s.handleConn(conn)
|
||||||
|
@ -560,7 +560,7 @@ var _ = Describe("Server", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
Expect(code).To(BeEquivalentTo(errorStreamCreationError))
|
Expect(code).To(BeEquivalentTo(ErrCodeStreamCreationError))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
s.handleConn(conn)
|
s.handleConn(conn)
|
||||||
|
@ -585,7 +585,7 @@ var _ = Describe("Server", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, reason string) {
|
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, reason string) {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
Expect(code).To(BeEquivalentTo(errorSettingsError))
|
Expect(code).To(BeEquivalentTo(ErrCodeSettingsError))
|
||||||
Expect(reason).To(Equal("missing QUIC Datagram support"))
|
Expect(reason).To(Equal("missing QUIC Datagram support"))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
|
@ -632,7 +632,7 @@ var _ = Describe("Server", func() {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
str.EXPECT().Context().Return(reqContext)
|
str.EXPECT().Context().Return(reqContext)
|
||||||
str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes()
|
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) })
|
str.EXPECT().Close().Do(func() { close(done) })
|
||||||
|
|
||||||
s.handleConn(conn)
|
s.handleConn(conn)
|
||||||
|
@ -674,7 +674,7 @@ var _ = Describe("Server", func() {
|
||||||
setRequest(append(requestData, b...))
|
setRequest(append(requestData, b...))
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes()
|
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)
|
s.handleConn(conn)
|
||||||
Eventually(done).Should(BeClosed())
|
Eventually(done).Should(BeClosed())
|
||||||
|
@ -689,7 +689,7 @@ var _ = Describe("Server", func() {
|
||||||
testErr := errors.New("stream reset")
|
testErr := errors.New("stream reset")
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
str.EXPECT().Read(gomock.Any()).Return(0, testErr)
|
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)
|
s.handleConn(conn)
|
||||||
Consistently(handlerCalled).ShouldNot(BeClosed())
|
Consistently(handlerCalled).ShouldNot(BeClosed())
|
||||||
|
@ -709,7 +709,7 @@ var _ = Describe("Server", func() {
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Do(func(code quic.ApplicationErrorCode, _ string) {
|
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)
|
close(done)
|
||||||
})
|
})
|
||||||
s.handleConn(conn)
|
s.handleConn(conn)
|
||||||
|
@ -733,7 +733,7 @@ var _ = Describe("Server", func() {
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}).AnyTimes()
|
}).AnyTimes()
|
||||||
done := make(chan struct{})
|
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)
|
s.handleConn(conn)
|
||||||
Eventually(done).Should(BeClosed())
|
Eventually(done).Should(BeClosed())
|
||||||
|
@ -755,7 +755,7 @@ var _ = Describe("Server", func() {
|
||||||
str.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) {
|
str.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) {
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}).AnyTimes()
|
}).AnyTimes()
|
||||||
str.EXPECT().CancelRead(quic.StreamErrorCode(errorNoError))
|
str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeNoError))
|
||||||
|
|
||||||
serr := s.handleRequest(conn, str, qpackDecoder, nil)
|
serr := s.handleRequest(conn, str, qpackDecoder, nil)
|
||||||
Expect(serr.err).ToNot(HaveOccurred())
|
Expect(serr.err).ToNot(HaveOccurred())
|
||||||
|
@ -778,7 +778,7 @@ var _ = Describe("Server", func() {
|
||||||
str.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) {
|
str.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) {
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}).AnyTimes()
|
}).AnyTimes()
|
||||||
str.EXPECT().CancelRead(quic.StreamErrorCode(errorNoError))
|
str.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeNoError))
|
||||||
|
|
||||||
serr := s.handleRequest(conn, str, qpackDecoder, nil)
|
serr := s.handleRequest(conn, str, qpackDecoder, nil)
|
||||||
Expect(serr.err).ToNot(HaveOccurred())
|
Expect(serr.err).ToNot(HaveOccurred())
|
||||||
|
@ -1207,7 +1207,7 @@ var _ = Describe("Server", func() {
|
||||||
<-testDone
|
<-testDone
|
||||||
return nil, errors.New("test done")
|
return nil, errors.New("test done")
|
||||||
}).MaxTimes(1)
|
}).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)
|
s.ServeQUICConn(conn)
|
||||||
close(testDone)
|
close(testDone)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue