github.com/mikelsr/quic-go@v0.36.1-0.20230701132136-1d9415b66898/http3/http_stream_test.go (about) 1 package http3 2 3 import ( 4 "bytes" 5 "io" 6 7 mockquic "github.com/mikelsr/quic-go/internal/mocks/quic" 8 9 "github.com/golang/mock/gomock" 10 . "github.com/onsi/ginkgo/v2" 11 . "github.com/onsi/gomega" 12 ) 13 14 var _ = Describe("Stream", func() { 15 Context("reading", func() { 16 var ( 17 str Stream 18 qstr *mockquic.MockStream 19 buf *bytes.Buffer 20 errorCbCalled bool 21 ) 22 23 errorCb := func() { errorCbCalled = true } 24 getDataFrame := func(data []byte) []byte { 25 b := (&dataFrame{Length: uint64(len(data))}).Append(nil) 26 return append(b, data...) 27 } 28 29 BeforeEach(func() { 30 buf = &bytes.Buffer{} 31 errorCbCalled = false 32 qstr = mockquic.NewMockStream(mockCtrl) 33 qstr.EXPECT().Write(gomock.Any()).DoAndReturn(buf.Write).AnyTimes() 34 qstr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes() 35 str = newStream(qstr, errorCb) 36 }) 37 38 It("reads DATA frames in a single run", func() { 39 buf.Write(getDataFrame([]byte("foobar"))) 40 b := make([]byte, 6) 41 n, err := str.Read(b) 42 Expect(err).ToNot(HaveOccurred()) 43 Expect(n).To(Equal(6)) 44 Expect(b).To(Equal([]byte("foobar"))) 45 }) 46 47 It("reads DATA frames in multiple runs", func() { 48 buf.Write(getDataFrame([]byte("foobar"))) 49 b := make([]byte, 3) 50 n, err := str.Read(b) 51 Expect(err).ToNot(HaveOccurred()) 52 Expect(n).To(Equal(3)) 53 Expect(b).To(Equal([]byte("foo"))) 54 n, err = str.Read(b) 55 Expect(err).ToNot(HaveOccurred()) 56 Expect(n).To(Equal(3)) 57 Expect(b).To(Equal([]byte("bar"))) 58 }) 59 60 It("reads DATA frames into too large buffers", func() { 61 buf.Write(getDataFrame([]byte("foobar"))) 62 b := make([]byte, 10) 63 n, err := str.Read(b) 64 Expect(err).ToNot(HaveOccurred()) 65 Expect(n).To(Equal(6)) 66 Expect(b[:n]).To(Equal([]byte("foobar"))) 67 }) 68 69 It("reads DATA frames into too large buffers, in multiple runs", func() { 70 buf.Write(getDataFrame([]byte("foobar"))) 71 b := make([]byte, 4) 72 n, err := str.Read(b) 73 Expect(err).ToNot(HaveOccurred()) 74 Expect(n).To(Equal(4)) 75 Expect(b).To(Equal([]byte("foob"))) 76 n, err = str.Read(b) 77 Expect(err).ToNot(HaveOccurred()) 78 Expect(n).To(Equal(2)) 79 Expect(b[:n]).To(Equal([]byte("ar"))) 80 }) 81 82 It("reads multiple DATA frames", func() { 83 buf.Write(getDataFrame([]byte("foo"))) 84 buf.Write(getDataFrame([]byte("bar"))) 85 b := make([]byte, 6) 86 n, err := str.Read(b) 87 Expect(err).ToNot(HaveOccurred()) 88 Expect(n).To(Equal(3)) 89 Expect(b[:n]).To(Equal([]byte("foo"))) 90 n, err = str.Read(b) 91 Expect(err).ToNot(HaveOccurred()) 92 Expect(n).To(Equal(3)) 93 Expect(b[:n]).To(Equal([]byte("bar"))) 94 }) 95 96 It("skips HEADERS frames", func() { 97 b := getDataFrame([]byte("foo")) 98 b = (&headersFrame{Length: 10}).Append(b) 99 b = append(b, make([]byte, 10)...) 100 b = append(b, getDataFrame([]byte("bar"))...) 101 buf.Write(b) 102 r := make([]byte, 6) 103 n, err := io.ReadFull(str, r) 104 Expect(err).ToNot(HaveOccurred()) 105 Expect(n).To(Equal(6)) 106 Expect(r).To(Equal([]byte("foobar"))) 107 }) 108 109 It("errors when it can't parse the frame", func() { 110 buf.Write([]byte("invalid")) 111 _, err := str.Read([]byte{0}) 112 Expect(err).To(HaveOccurred()) 113 }) 114 115 It("errors on unexpected frames, and calls the error callback", func() { 116 b := (&settingsFrame{}).Append(nil) 117 buf.Write(b) 118 _, err := str.Read([]byte{0}) 119 Expect(err).To(MatchError("peer sent an unexpected frame: *http3.settingsFrame")) 120 Expect(errorCbCalled).To(BeTrue()) 121 }) 122 }) 123 124 Context("writing", func() { 125 It("writes data frames", func() { 126 buf := &bytes.Buffer{} 127 qstr := mockquic.NewMockStream(mockCtrl) 128 qstr.EXPECT().Write(gomock.Any()).DoAndReturn(buf.Write).AnyTimes() 129 str := newStream(qstr, nil) 130 str.Write([]byte("foo")) 131 str.Write([]byte("foobar")) 132 133 f, err := parseNextFrame(buf, nil) 134 Expect(err).ToNot(HaveOccurred()) 135 Expect(f).To(Equal(&dataFrame{Length: 3})) 136 b := make([]byte, 3) 137 _, err = io.ReadFull(buf, b) 138 Expect(err).ToNot(HaveOccurred()) 139 Expect(b).To(Equal([]byte("foo"))) 140 141 f, err = parseNextFrame(buf, nil) 142 Expect(err).ToNot(HaveOccurred()) 143 Expect(f).To(Equal(&dataFrame{Length: 6})) 144 b = make([]byte, 6) 145 _, err = io.ReadFull(buf, b) 146 Expect(err).ToNot(HaveOccurred()) 147 Expect(b).To(Equal([]byte("foobar"))) 148 }) 149 }) 150 })