forked from quic-go/quic-go
The http.Request.Body can be type-asserted to a http3.Settingser. The Settings method on this interface blocks until the client's SETTINGS frame has been received.
79 lines
2.4 KiB
Go
79 lines
2.4 KiB
Go
package http3
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/quic-go/quic-go"
|
|
mockquic "github.com/quic-go/quic-go/internal/mocks/quic"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
"go.uber.org/mock/gomock"
|
|
)
|
|
|
|
var _ = Describe("Request Body", func() {
|
|
It("makes the SETTINGS available", func() {
|
|
str := mockquic.NewMockStream(mockCtrl)
|
|
rcvdSettings := make(chan struct{})
|
|
close(rcvdSettings)
|
|
settings := &Settings{EnableExtendedConnect: true}
|
|
body := newRequestBody(str, context.Background(), rcvdSettings, func() *Settings { return settings })
|
|
s, err := body.Settings(context.Background())
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(s).To(Equal(settings))
|
|
})
|
|
|
|
It("unblocks Settings() when the connection is closed", func() {
|
|
str := mockquic.NewMockStream(mockCtrl)
|
|
ctx, cancel := context.WithCancelCause(context.Background())
|
|
testErr := errors.New("test error")
|
|
cancel(testErr)
|
|
body := newRequestBody(str, ctx, make(chan struct{}), func() *Settings { return nil })
|
|
_, err := body.Settings(context.Background())
|
|
Expect(err).To(MatchError(testErr))
|
|
})
|
|
})
|
|
|
|
var _ = Describe("Response Body", func() {
|
|
var reqDone chan struct{}
|
|
|
|
BeforeEach(func() { reqDone = make(chan struct{}) })
|
|
|
|
It("closes the reqDone channel when Read errors", func() {
|
|
str := mockquic.NewMockStream(mockCtrl)
|
|
str.EXPECT().Read(gomock.Any()).Return(0, errors.New("test error"))
|
|
rb := newResponseBody(str, nil, reqDone)
|
|
_, err := rb.Read([]byte{0})
|
|
Expect(err).To(MatchError("test error"))
|
|
Expect(reqDone).To(BeClosed())
|
|
})
|
|
|
|
It("allows multiple calls to Read, when Read errors", func() {
|
|
str := mockquic.NewMockStream(mockCtrl)
|
|
str.EXPECT().Read(gomock.Any()).Return(0, errors.New("test error")).Times(2)
|
|
rb := newResponseBody(str, nil, reqDone)
|
|
_, err := rb.Read([]byte{0})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(reqDone).To(BeClosed())
|
|
_, err = rb.Read([]byte{0})
|
|
Expect(err).To(HaveOccurred())
|
|
})
|
|
|
|
It("closes responses", func() {
|
|
str := mockquic.NewMockStream(mockCtrl)
|
|
rb := newResponseBody(str, nil, reqDone)
|
|
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(ErrCodeRequestCanceled)).MaxTimes(2)
|
|
Expect(rb.Close()).To(Succeed())
|
|
Expect(reqDone).To(BeClosed())
|
|
Expect(rb.Close()).To(Succeed())
|
|
})
|
|
})
|