Files
quic-go/http3/body_test.go
Marten Seemann 4f6d0e651a implement HTTP/3
2019-04-11 09:06:10 +09:00

151 lines
3.5 KiB
Go

package http3
import (
"bytes"
"io"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
type closingBuffer struct {
*bytes.Buffer
closed bool
}
func (b *closingBuffer) Close() error { b.closed = true; return nil }
type bodyType uint8
const (
bodyTypeRequest bodyType = iota
bodyTypeResponse
)
var _ = Describe("Body", func() {
var rb *body
var buf *bytes.Buffer
getDataFrame := func(data []byte) []byte {
b := &bytes.Buffer{}
(&dataFrame{Length: uint64(len(data))}).Write(b)
b.Write(data)
return b.Bytes()
}
BeforeEach(func() {
buf = &bytes.Buffer{}
})
for _, bt := range []bodyType{bodyTypeRequest, bodyTypeResponse} {
bodyType := bt
BeforeEach(func() {
cb := &closingBuffer{Buffer: buf}
switch bodyType {
case bodyTypeRequest:
rb = newRequestBody(cb)
case bodyTypeResponse:
rb = newResponseBody(cb)
}
})
It("reads DATA frames in a single run", func() {
buf.Write(getDataFrame([]byte("foobar")))
b := make([]byte, 6)
n, err := rb.Read(b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(6))
Expect(b).To(Equal([]byte("foobar")))
})
It("reads DATA frames in multiple runs", func() {
buf.Write(getDataFrame([]byte("foobar")))
b := make([]byte, 3)
n, err := rb.Read(b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(3))
Expect(b).To(Equal([]byte("foo")))
n, err = rb.Read(b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(3))
Expect(b).To(Equal([]byte("bar")))
})
It("reads DATA frames into too large buffers", func() {
buf.Write(getDataFrame([]byte("foobar")))
b := make([]byte, 10)
n, err := rb.Read(b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(6))
Expect(b[:n]).To(Equal([]byte("foobar")))
})
It("reads DATA frames into too large buffers, in multiple runs", func() {
buf.Write(getDataFrame([]byte("foobar")))
b := make([]byte, 4)
n, err := rb.Read(b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(4))
Expect(b).To(Equal([]byte("foob")))
n, err = rb.Read(b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(2))
Expect(b[:n]).To(Equal([]byte("ar")))
})
It("reads multiple DATA frames", func() {
buf.Write(getDataFrame([]byte("foo")))
buf.Write(getDataFrame([]byte("bar")))
b := make([]byte, 6)
n, err := rb.Read(b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(3))
Expect(b[:n]).To(Equal([]byte("foo")))
n, err = rb.Read(b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(3))
Expect(b[:n]).To(Equal([]byte("bar")))
})
It("skips HEADERS frames", func() {
buf.Write(getDataFrame([]byte("foo")))
(&headersFrame{Length: 10}).Write(buf)
buf.Write(make([]byte, 10))
buf.Write(getDataFrame([]byte("bar")))
b := make([]byte, 6)
n, err := io.ReadFull(rb, b)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(6))
Expect(b).To(Equal([]byte("foobar")))
})
It("errors when it can't parse the frame", func() {
buf.Write([]byte("invalid"))
_, err := rb.Read([]byte{0})
Expect(err).To(HaveOccurred())
})
It("errors on unexpected frames", func() {
(&settingsFrame{}).Write(buf)
_, err := rb.Read([]byte{0})
Expect(err).To(MatchError("unexpected frame"))
})
}
It("closes requests", func() {
cb := &closingBuffer{Buffer: buf}
rb := newRequestBody(cb)
Expect(rb.Close()).To(Succeed())
Expect(cb.closed).To(BeFalse())
})
It("closes responses", func() {
cb := &closingBuffer{Buffer: buf}
rb := newResponseBody(cb)
Expect(rb.Close()).To(Succeed())
Expect(cb.closed).To(BeTrue())
})
})