http3: reduce usage of bytes.Buffer (#3539)

This commit is contained in:
Marten Seemann 2022-09-01 16:39:21 +03:00 committed by GitHub
parent dfd35cb071
commit 62b82789c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 136 additions and 149 deletions

View file

@ -1,7 +1,6 @@
package http3
import (
"bytes"
"context"
"crypto/tls"
"errors"
@ -136,11 +135,11 @@ func (c *client) setupConn() error {
if err != nil {
return err
}
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
b := make([]byte, 0, 64)
b = quicvarint.Append(b, streamTypeControlStream)
// send the SETTINGS frame
(&settingsFrame{Datagram: c.opts.EnableDatagram, Other: c.opts.AdditionalSettings}).Write(buf)
_, err = str.Write(buf.Bytes())
b = (&settingsFrame{Datagram: c.opts.EnableDatagram, Other: c.opts.AdditionalSettings}).Append(b)
_, err = str.Write(b)
return err
}

View file

@ -455,11 +455,11 @@ var _ = Describe("Client", func() {
})
It("parses the SETTINGS frame", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
(&settingsFrame{}).Write(buf)
b := quicvarint.Append(nil, streamTypeControlStream)
b = (&settingsFrame{}).Append(b)
r := bytes.NewReader(b)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -521,11 +521,11 @@ var _ = Describe("Client", func() {
})
It("errors when the first frame on the control stream is not a SETTINGS frame", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
(&dataFrame{}).Write(buf)
b := quicvarint.Append(nil, streamTypeControlStream)
b = (&dataFrame{}).Append(b)
r := bytes.NewReader(b)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -545,13 +545,11 @@ var _ = Describe("Client", func() {
})
It("errors when parsing the frame on the control stream fails", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
b := &bytes.Buffer{}
(&settingsFrame{}).Write(b)
buf.Write(b.Bytes()[:b.Len()-1])
b := quicvarint.Append(nil, streamTypeControlStream)
b = (&settingsFrame{}).Append(b)
r := bytes.NewReader(b[:len(b)-1])
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -595,11 +593,11 @@ var _ = Describe("Client", func() {
It("errors when the server advertises datagram support (and we enabled support for it)", func() {
client.opts.EnableDatagram = true
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
(&settingsFrame{Datagram: true}).Write(buf)
b := quicvarint.Append(nil, streamTypeControlStream)
b = (&settingsFrame{Datagram: true}).Append(b)
r := bytes.NewReader(b)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -631,16 +629,15 @@ var _ = Describe("Client", func() {
testDone := make(chan struct{})
getHeadersFrame := func(headers map[string]string) []byte {
buf := &bytes.Buffer{}
headerBuf := &bytes.Buffer{}
enc := qpack.NewEncoder(headerBuf)
for name, value := range headers {
Expect(enc.WriteField(qpack.HeaderField{Name: name, Value: value})).To(Succeed())
}
Expect(enc.Close()).To(Succeed())
(&headersFrame{Length: uint64(headerBuf.Len())}).Write(buf)
buf.Write(headerBuf.Bytes())
return buf.Bytes()
b := (&headersFrame{Length: uint64(headerBuf.Len())}).Append(nil)
b = append(b, headerBuf.Bytes()...)
return b
}
decodeHeader := func(str io.Reader) map[string]string {
@ -805,18 +802,18 @@ var _ = Describe("Client", func() {
It("sets the Content-Length", func() {
done := make(chan struct{})
buf := &bytes.Buffer{}
buf.Write(getHeadersFrame(map[string]string{
b := getHeadersFrame(map[string]string{
":status": "200",
"Content-Length": "1337",
}))
(&dataFrame{Length: 0x6}).Write(buf)
buf.Write([]byte("foobar"))
})
b = (&dataFrame{Length: 0x6}).Append(b)
b = append(b, []byte("foobar")...)
r := bytes.NewReader(b)
str.EXPECT().Close().Do(func() { close(done) })
conn.EXPECT().ConnectionState().Return(quic.ConnectionState{})
str.EXPECT().CancelWrite(gomock.Any()).MaxTimes(1) // when reading the response errors
// the response body is sent asynchronously, while already reading the response
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
req, err := client.RoundTripOpt(req, RoundTripOpt{})
Expect(err).ToNot(HaveOccurred())
Expect(req.ContentLength).To(BeEquivalentTo(1337))
@ -824,24 +821,24 @@ var _ = Describe("Client", func() {
})
It("closes the connection when the first frame is not a HEADERS frame", func() {
buf := &bytes.Buffer{}
(&dataFrame{Length: 0x42}).Write(buf)
b := (&dataFrame{Length: 0x42}).Append(nil)
conn.EXPECT().CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), gomock.Any())
closed := make(chan struct{})
r := bytes.NewReader(b)
str.EXPECT().Close().Do(func() { close(closed) })
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
_, err := client.RoundTripOpt(req, RoundTripOpt{})
Expect(err).To(MatchError("expected first frame to be a HEADERS frame"))
Eventually(closed).Should(BeClosed())
})
It("cancels the stream when the HEADERS frame is too large", func() {
buf := &bytes.Buffer{}
(&headersFrame{Length: 1338}).Write(buf)
b := (&headersFrame{Length: 1338}).Append(nil)
r := bytes.NewReader(b)
str.EXPECT().CancelWrite(quic.StreamErrorCode(errorFrameError))
closed := make(chan struct{})
str.EXPECT().Close().Do(func() { close(closed) })
str.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
str.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
_, err := client.RoundTripOpt(req, RoundTripOpt{})
Expect(err).To(MatchError("HEADERS frame too large: 1338 bytes (max: 1337)"))
Eventually(closed).Should(BeClosed())

View file

@ -74,18 +74,18 @@ type dataFrame struct {
Length uint64
}
func (f *dataFrame) Write(b *bytes.Buffer) {
quicvarint.Write(b, 0x0)
quicvarint.Write(b, f.Length)
func (f *dataFrame) Append(b []byte) []byte {
b = quicvarint.Append(b, 0x0)
return quicvarint.Append(b, f.Length)
}
type headersFrame struct {
Length uint64
}
func (f *headersFrame) Write(b *bytes.Buffer) {
quicvarint.Write(b, 0x1)
quicvarint.Write(b, f.Length)
func (f *headersFrame) Append(b []byte) []byte {
b = quicvarint.Append(b, 0x1)
return quicvarint.Append(b, f.Length)
}
const settingDatagram = 0xffd277
@ -142,8 +142,8 @@ func parseSettingsFrame(r io.Reader, l uint64) (*settingsFrame, error) {
return frame, nil
}
func (f *settingsFrame) Write(b *bytes.Buffer) {
quicvarint.Write(b, 0x4)
func (f *settingsFrame) Append(b []byte) []byte {
b = quicvarint.Append(b, 0x4)
var l protocol.ByteCount
for id, val := range f.Other {
l += quicvarint.Len(id) + quicvarint.Len(val)
@ -151,13 +151,14 @@ func (f *settingsFrame) Write(b *bytes.Buffer) {
if f.Datagram {
l += quicvarint.Len(settingDatagram) + quicvarint.Len(1)
}
quicvarint.Write(b, uint64(l))
b = quicvarint.Append(b, uint64(l))
if f.Datagram {
quicvarint.Write(b, settingDatagram)
quicvarint.Write(b, 1)
b = quicvarint.Append(b, settingDatagram)
b = quicvarint.Append(b, 1)
}
for id, val := range f.Other {
quicvarint.Write(b, id)
quicvarint.Write(b, val)
b = quicvarint.Append(b, id)
b = quicvarint.Append(b, val)
}
return b
}

View file

@ -24,12 +24,12 @@ var _ = Describe("Frames", func() {
}
It("skips unknown frames", func() {
data := appendVarInt(nil, 0xdeadbeef) // type byte
data = appendVarInt(data, 0x42)
data = append(data, make([]byte, 0x42)...)
buf := bytes.NewBuffer(data)
(&dataFrame{Length: 0x1234}).Write(buf)
frame, err := parseNextFrame(buf, nil)
b := appendVarInt(nil, 0xdeadbeef) // type byte
b = appendVarInt(b, 0x42)
b = append(b, make([]byte, 0x42)...)
b = (&dataFrame{Length: 0x1234}).Append(b)
r := bytes.NewReader(b)
frame, err := parseNextFrame(r, nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&dataFrame{}))
Expect(frame.(*dataFrame).Length).To(Equal(uint64(0x1234)))
@ -46,9 +46,8 @@ var _ = Describe("Frames", func() {
})
It("writes", func() {
buf := &bytes.Buffer{}
(&dataFrame{Length: 0xdeadbeef}).Write(buf)
frame, err := parseNextFrame(buf, nil)
b := (&dataFrame{Length: 0xdeadbeef}).Append(nil)
frame, err := parseNextFrame(bytes.NewReader(b), nil)
Expect(err).ToNot(HaveOccurred())
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&dataFrame{}))
@ -67,9 +66,8 @@ var _ = Describe("Frames", func() {
})
It("writes", func() {
buf := &bytes.Buffer{}
(&headersFrame{Length: 0xdeadbeef}).Write(buf)
frame, err := parseNextFrame(buf, nil)
b := (&headersFrame{Length: 0xdeadbeef}).Append(nil)
frame, err := parseNextFrame(bytes.NewReader(b), nil)
Expect(err).ToNot(HaveOccurred())
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&headersFrame{}))
@ -112,9 +110,7 @@ var _ = Describe("Frames", func() {
99: 999,
13: 37,
}}
buf := &bytes.Buffer{}
sf.Write(buf)
frame, err := parseNextFrame(buf, nil)
frame, err := parseNextFrame(bytes.NewReader(sf.Append(nil)), nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(Equal(sf))
})
@ -124,10 +120,8 @@ var _ = Describe("Frames", func() {
13: 37,
0xdeadbeef: 0xdecafbad,
}}
buf := &bytes.Buffer{}
sf.Write(buf)
data := sf.Append(nil)
data := buf.Bytes()
_, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).ToNot(HaveOccurred())
@ -177,9 +171,7 @@ var _ = Describe("Frames", func() {
It("writes the H3_DATAGRAM setting", func() {
sf := &settingsFrame{Datagram: true}
buf := &bytes.Buffer{}
sf.Write(buf)
frame, err := parseNextFrame(buf, nil)
frame, err := parseNextFrame(bytes.NewReader(sf.Append(nil)), nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(Equal(sf))
})
@ -222,16 +214,15 @@ var _ = Describe("Frames", func() {
})
It("reads a frame without hijacking the stream", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, 1337)
b := quicvarint.Append(nil, 1337)
customFrameContents := []byte("custom frame")
quicvarint.Write(buf, uint64(len(customFrameContents)))
buf.Write(customFrameContents)
(&dataFrame{Length: 6}).Write(buf)
buf.WriteString("foobar")
b = quicvarint.Append(b, uint64(len(customFrameContents)))
b = append(b, customFrameContents...)
b = (&dataFrame{Length: 6}).Append(b)
b = append(b, []byte("foobar")...)
var called bool
frame, err := parseNextFrame(buf, func(ft FrameType, e error) (hijacked bool, err error) {
frame, err := parseNextFrame(bytes.NewReader(b), func(ft FrameType, e error) (hijacked bool, err error) {
Expect(e).ToNot(HaveOccurred())
Expect(ft).To(BeEquivalentTo(1337))
called = true

View file

@ -1,7 +1,6 @@
package http3
import (
"bytes"
"fmt"
"github.com/lucas-clemente/quic-go"
@ -16,6 +15,8 @@ type Stream quic.Stream
type stream struct {
quic.Stream
buf []byte
onFrameError func()
bytesRemainingInFrame uint64
}
@ -23,7 +24,11 @@ type stream struct {
var _ Stream = &stream{}
func newStream(str quic.Stream, onFrameError func()) *stream {
return &stream{Stream: str, onFrameError: onFrameError}
return &stream{
Stream: str,
onFrameError: onFrameError,
buf: make([]byte, 0, 16),
}
}
func (s *stream) Read(b []byte) (int, error) {
@ -62,9 +67,9 @@ func (s *stream) Read(b []byte) (int, error) {
}
func (s *stream) Write(b []byte) (int, error) {
buf := &bytes.Buffer{}
(&dataFrame{Length: uint64(len(b))}).Write(buf)
if _, err := s.Stream.Write(buf.Bytes()); err != nil {
s.buf = s.buf[:0]
s.buf = (&dataFrame{Length: uint64(len(b))}).Append(s.buf)
if _, err := s.Stream.Write(s.buf); err != nil {
return 0, err
}
return s.Stream.Write(b)

View file

@ -22,10 +22,8 @@ var _ = Describe("Stream", func() {
errorCb := func() { errorCbCalled = true }
getDataFrame := func(data []byte) []byte {
b := &bytes.Buffer{}
(&dataFrame{Length: uint64(len(data))}).Write(b)
b.Write(data)
return b.Bytes()
b := (&dataFrame{Length: uint64(len(data))}).Append(nil)
return append(b, data...)
}
BeforeEach(func() {
@ -96,15 +94,16 @@ var _ = Describe("Stream", func() {
})
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(str, b)
b := getDataFrame([]byte("foo"))
b = (&headersFrame{Length: 10}).Append(b)
b = append(b, make([]byte, 10)...)
b = append(b, getDataFrame([]byte("bar"))...)
buf.Write(b)
r := make([]byte, 6)
n, err := io.ReadFull(str, r)
Expect(err).ToNot(HaveOccurred())
Expect(n).To(Equal(6))
Expect(b).To(Equal([]byte("foobar")))
Expect(r).To(Equal([]byte("foobar")))
})
It("errors when it can't parse the frame", func() {
@ -114,7 +113,8 @@ var _ = Describe("Stream", func() {
})
It("errors on unexpected frames, and calls the error callback", func() {
(&settingsFrame{}).Write(buf)
b := (&settingsFrame{}).Append(nil)
buf.Write(b)
_, err := str.Read([]byte{0})
Expect(err).To(MatchError("peer sent an unexpected frame: *http3.settingsFrame"))
Expect(errorCbCalled).To(BeTrue())

View file

@ -58,10 +58,9 @@ func (w *requestWriter) writeHeaders(wr io.Writer, req *http.Request, gzip bool)
return err
}
buf := &bytes.Buffer{}
hf := headersFrame{Length: uint64(w.headerBuf.Len())}
hf.Write(buf)
if _, err := wr.Write(buf.Bytes()); err != nil {
b := make([]byte, 0, 128)
b = (&headersFrame{Length: uint64(w.headerBuf.Len())}).Append(b)
if _, err := wr.Write(b); err != nil {
return err
}
_, err := wr.Write(w.headerBuf.Bytes())

View file

@ -15,6 +15,7 @@ import (
type responseWriter struct {
conn quic.Connection
bufferedStr *bufio.Writer
buf []byte
header http.Header
status int // status code passed to WriteHeader
@ -32,6 +33,7 @@ var (
func newResponseWriter(str quic.Stream, conn quic.Connection, logger utils.Logger) *responseWriter {
return &responseWriter{
header: http.Header{},
buf: make([]byte, 16),
conn: conn,
bufferedStr: bufio.NewWriter(str),
logger: logger,
@ -62,10 +64,10 @@ func (w *responseWriter) WriteHeader(status int) {
}
}
buf := &bytes.Buffer{}
(&headersFrame{Length: uint64(headers.Len())}).Write(buf)
w.buf = w.buf[:0]
w.buf = (&headersFrame{Length: uint64(headers.Len())}).Append(w.buf)
w.logger.Infof("Responding with %d", status)
if _, err := w.bufferedStr.Write(buf.Bytes()); err != nil {
if _, err := w.bufferedStr.Write(w.buf); err != nil {
w.logger.Errorf("could not write headers frame: %s", err.Error())
}
if _, err := w.bufferedStr.Write(headers.Bytes()); err != nil {
@ -84,9 +86,9 @@ func (w *responseWriter) Write(p []byte) (int, error) {
return 0, http.ErrBodyNotAllowed
}
df := &dataFrame{Length: uint64(len(p))}
buf := &bytes.Buffer{}
df.Write(buf)
if _, err := w.bufferedStr.Write(buf.Bytes()); err != nil {
w.buf = w.buf[:0]
w.buf = df.Append(w.buf)
if _, err := w.bufferedStr.Write(w.buf); err != nil {
return 0, err
}
return w.bufferedStr.Write(p)

View file

@ -1,7 +1,6 @@
package http3
import (
"bytes"
"context"
"crypto/tls"
"errors"
@ -413,10 +412,10 @@ func (s *Server) handleConn(conn quic.EarlyConnection) {
s.logger.Debugf("Opening the control stream failed.")
return
}
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream) // stream type
(&settingsFrame{Datagram: s.EnableDatagrams, Other: s.AdditionalSettings}).Write(buf)
str.Write(buf.Bytes())
b := make([]byte, 0, 64)
b = quicvarint.Append(b, streamTypeControlStream) // stream type
b = (&settingsFrame{Datagram: s.EnableDatagrams, Other: s.AdditionalSettings}).Append(b)
str.Write(b)
go s.handleUnidirectionalStreams(conn)

View file

@ -438,11 +438,11 @@ var _ = Describe("Server", func() {
AfterEach(func() { testDone <- struct{}{} })
It("parses the SETTINGS frame", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
(&settingsFrame{}).Write(buf)
b := quicvarint.Append(nil, streamTypeControlStream)
b = (&settingsFrame{}).Append(b)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
r := bytes.NewReader(b)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -501,11 +501,11 @@ var _ = Describe("Server", func() {
})
It("errors when the first frame on the control stream is not a SETTINGS frame", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
(&dataFrame{}).Write(buf)
b := quicvarint.Append(nil, streamTypeControlStream)
b = (&dataFrame{}).Append(b)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
r := bytes.NewReader(b)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -524,13 +524,11 @@ var _ = Describe("Server", func() {
})
It("errors when parsing the frame on the control stream fails", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
b := &bytes.Buffer{}
(&settingsFrame{}).Write(b)
buf.Write(b.Bytes()[:b.Len()-1])
b := quicvarint.Append(nil, streamTypeControlStream)
b = (&settingsFrame{}).Append(b)
r := bytes.NewReader(b[:len(b)-1])
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -549,11 +547,11 @@ var _ = Describe("Server", func() {
})
It("errors when the client opens a push stream", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypePushStream)
(&dataFrame{}).Write(buf)
b := quicvarint.Append(nil, streamTypePushStream)
b = (&dataFrame{}).Append(b)
r := bytes.NewReader(b)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -573,11 +571,11 @@ var _ = Describe("Server", func() {
It("errors when the client advertises datagram support (and we enabled support for it)", func() {
s.EnableDatagrams = true
buf := &bytes.Buffer{}
quicvarint.Write(buf, streamTypeControlStream)
(&settingsFrame{Datagram: true}).Write(buf)
b := quicvarint.Append(nil, streamTypeControlStream)
b = (&settingsFrame{Datagram: true}).Append(b)
r := bytes.NewReader(b)
controlStr := mockquic.NewMockStream(mockCtrl)
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
controlStr.EXPECT().Read(gomock.Any()).DoAndReturn(r.Read).AnyTimes()
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
return controlStr, nil
})
@ -628,11 +626,10 @@ var _ = Describe("Server", func() {
})
requestData := encodeRequest(exampleGetRequest)
buf := &bytes.Buffer{}
(&dataFrame{Length: 6}).Write(buf) // add a body
buf.Write([]byte("foobar"))
b := (&dataFrame{Length: 6}).Append(nil) // add a body
b = append(b, []byte("foobar")...)
responseBuf := &bytes.Buffer{}
setRequest(append(requestData, buf.Bytes()...))
setRequest(append(requestData, b...))
done := make(chan struct{})
str.EXPECT().Context().Return(reqContext)
str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes()
@ -655,10 +652,9 @@ var _ = Describe("Server", func() {
})
requestData := encodeRequest(exampleGetRequest)
buf := &bytes.Buffer{}
(&dataFrame{Length: 6}).Write(buf) // add a body
buf.Write([]byte("foobar"))
setRequest(append(requestData, buf.Bytes()...))
b := (&dataFrame{Length: 6}).Append(nil) // add a body
b = append(b, []byte("foobar")...)
setRequest(append(requestData, b...))
str.EXPECT().Context().Return(reqContext)
str.EXPECT().Write([]byte("foobar")).Return(6, nil)
@ -673,11 +669,10 @@ var _ = Describe("Server", func() {
})
requestData := encodeRequest(exampleGetRequest)
buf := &bytes.Buffer{}
(&dataFrame{Length: 6}).Write(buf) // add a body
buf.Write([]byte("foobar"))
b := (&dataFrame{Length: 6}).Append(nil) // add a body
b = append(b, []byte("foobar")...)
responseBuf := &bytes.Buffer{}
setRequest(append(requestData, buf.Bytes()...))
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) })
@ -707,9 +702,8 @@ var _ = Describe("Server", func() {
close(handlerCalled)
})
buf := &bytes.Buffer{}
(&dataFrame{}).Write(buf)
setRequest(buf.Bytes())
b := (&dataFrame{}).Append(nil)
setRequest(b)
str.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) {
return len(p), nil
}).AnyTimes()