github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/internal/wire/datagram_frame_test.go (about) 1 package wire 2 3 import ( 4 "bytes" 5 "io" 6 7 "github.com/danielpfeifer02/quic-go-prio-packs/internal/protocol" 8 "github.com/danielpfeifer02/quic-go-prio-packs/quicvarint" 9 10 . "github.com/onsi/ginkgo/v2" 11 . "github.com/onsi/gomega" 12 ) 13 14 var _ = Describe("STREAM frame", func() { 15 Context("when parsing", func() { 16 It("parses a frame containing a length", func() { 17 data := encodeVarInt(0x6) // length 18 data = append(data, []byte("foobar")...) 19 r := bytes.NewReader(data) 20 frame, err := parseDatagramFrame(r, 0x30^0x1, protocol.Version1) 21 Expect(err).ToNot(HaveOccurred()) 22 Expect(frame.Data).To(Equal([]byte("foobar"))) 23 Expect(frame.DataLenPresent).To(BeTrue()) 24 Expect(r.Len()).To(BeZero()) 25 }) 26 27 It("parses a frame without length", func() { 28 data := []byte("Lorem ipsum dolor sit amet") 29 r := bytes.NewReader(data) 30 frame, err := parseDatagramFrame(r, 0x30, protocol.Version1) 31 Expect(err).ToNot(HaveOccurred()) 32 Expect(frame.Data).To(Equal([]byte("Lorem ipsum dolor sit amet"))) 33 Expect(frame.DataLenPresent).To(BeFalse()) 34 Expect(r.Len()).To(BeZero()) 35 }) 36 37 It("errors when the length is longer than the rest of the frame", func() { 38 data := encodeVarInt(0x6) // length 39 data = append(data, []byte("fooba")...) 40 r := bytes.NewReader(data) 41 _, err := parseDatagramFrame(r, 0x30^0x1, protocol.Version1) 42 Expect(err).To(MatchError(io.EOF)) 43 }) 44 45 It("errors on EOFs", func() { 46 const typ = 0x30 ^ 0x1 47 data := encodeVarInt(6) // length 48 data = append(data, []byte("foobar")...) 49 _, err := parseDatagramFrame(bytes.NewReader(data), typ, protocol.Version1) 50 Expect(err).NotTo(HaveOccurred()) 51 for i := range data { 52 _, err = parseDatagramFrame(bytes.NewReader(data[0:i]), typ, protocol.Version1) 53 Expect(err).To(MatchError(io.EOF)) 54 } 55 }) 56 }) 57 58 Context("when writing", func() { 59 It("writes a frame with length", func() { 60 f := &DatagramFrame{ 61 DataLenPresent: true, 62 Data: []byte("foobar"), 63 } 64 b, err := f.Append(nil, protocol.Version1) 65 Expect(err).ToNot(HaveOccurred()) 66 expected := []byte{0x30 ^ 0x1} 67 expected = append(expected, encodeVarInt(0x6)...) 68 expected = append(expected, []byte("foobar")...) 69 Expect(b).To(Equal(expected)) 70 }) 71 72 It("writes a frame without length", func() { 73 f := &DatagramFrame{Data: []byte("Lorem ipsum")} 74 b, err := f.Append(nil, protocol.Version1) 75 Expect(err).ToNot(HaveOccurred()) 76 expected := []byte{0x30} 77 expected = append(expected, []byte("Lorem ipsum")...) 78 Expect(b).To(Equal(expected)) 79 }) 80 }) 81 82 Context("length", func() { 83 It("has the right length for a frame with length", func() { 84 f := &DatagramFrame{ 85 DataLenPresent: true, 86 Data: []byte("foobar"), 87 } 88 Expect(f.Length(protocol.Version1)).To(Equal(1 + quicvarint.Len(6) + 6)) 89 }) 90 91 It("has the right length for a frame without length", func() { 92 f := &DatagramFrame{Data: []byte("foobar")} 93 Expect(f.Length(protocol.Version1)).To(Equal(protocol.ByteCount(1 + 6))) 94 }) 95 }) 96 97 Context("max data length", func() { 98 const maxSize = 3000 99 100 It("returns a data length such that the resulting frame has the right size, if data length is not present", func() { 101 data := make([]byte, maxSize) 102 f := &DatagramFrame{} 103 b := &bytes.Buffer{} 104 for i := 1; i < 3000; i++ { 105 b.Reset() 106 f.Data = nil 107 maxDataLen := f.MaxDataLen(protocol.ByteCount(i), protocol.Version1) 108 if maxDataLen == 0 { // 0 means that no valid STREAM frame can be written 109 // check that writing a minimal size STREAM frame (i.e. with 1 byte data) is actually larger than the desired size 110 f.Data = []byte{0} 111 b, err := f.Append(nil, protocol.Version1) 112 Expect(err).ToNot(HaveOccurred()) 113 Expect(len(b)).To(BeNumerically(">", i)) 114 continue 115 } 116 f.Data = data[:int(maxDataLen)] 117 b, err := f.Append(nil, protocol.Version1) 118 Expect(err).ToNot(HaveOccurred()) 119 Expect(b).To(HaveLen(i)) 120 } 121 }) 122 123 It("always returns a data length such that the resulting frame has the right size, if data length is present", func() { 124 data := make([]byte, maxSize) 125 f := &DatagramFrame{DataLenPresent: true} 126 var frameOneByteTooSmallCounter int 127 for i := 1; i < 3000; i++ { 128 f.Data = nil 129 maxDataLen := f.MaxDataLen(protocol.ByteCount(i), protocol.Version1) 130 if maxDataLen == 0 { // 0 means that no valid STREAM frame can be written 131 // check that writing a minimal size STREAM frame (i.e. with 1 byte data) is actually larger than the desired size 132 f.Data = []byte{0} 133 b, err := f.Append(nil, protocol.Version1) 134 Expect(err).ToNot(HaveOccurred()) 135 Expect(len(b)).To(BeNumerically(">", i)) 136 continue 137 } 138 f.Data = data[:int(maxDataLen)] 139 b, err := f.Append(nil, protocol.Version1) 140 Expect(err).ToNot(HaveOccurred()) 141 // There's *one* pathological case, where a data length of x can be encoded into 1 byte 142 // but a data lengths of x+1 needs 2 bytes 143 // In that case, it's impossible to create a STREAM frame of the desired size 144 if len(b) == i-1 { 145 frameOneByteTooSmallCounter++ 146 continue 147 } 148 Expect(b).To(HaveLen(i)) 149 } 150 Expect(frameOneByteTooSmallCounter).To(Equal(1)) 151 }) 152 }) 153 })