github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/internal/wire/connection_close_frame_test.go (about) 1 package wire 2 3 import ( 4 "bytes" 5 "io" 6 7 "github.com/apernet/quic-go/internal/protocol" 8 9 . "github.com/onsi/ginkgo/v2" 10 . "github.com/onsi/gomega" 11 ) 12 13 var _ = Describe("CONNECTION_CLOSE Frame", func() { 14 Context("when parsing", func() { 15 It("accepts sample frame containing a QUIC error code", func() { 16 reason := "No recent network activity." 17 data := encodeVarInt(0x19) 18 data = append(data, encodeVarInt(0x1337)...) // frame type 19 data = append(data, encodeVarInt(uint64(len(reason)))...) // reason phrase length 20 data = append(data, []byte(reason)...) 21 b := bytes.NewReader(data) 22 frame, err := parseConnectionCloseFrame(b, connectionCloseFrameType, protocol.Version1) 23 Expect(err).ToNot(HaveOccurred()) 24 Expect(frame.IsApplicationError).To(BeFalse()) 25 Expect(frame.ErrorCode).To(BeEquivalentTo(0x19)) 26 Expect(frame.FrameType).To(BeEquivalentTo(0x1337)) 27 Expect(frame.ReasonPhrase).To(Equal(reason)) 28 Expect(b.Len()).To(BeZero()) 29 }) 30 31 It("accepts sample frame containing an application error code", func() { 32 reason := "The application messed things up." 33 data := encodeVarInt(0xcafe) 34 data = append(data, encodeVarInt(uint64(len(reason)))...) // reason phrase length 35 data = append(data, reason...) 36 b := bytes.NewReader(data) 37 frame, err := parseConnectionCloseFrame(b, applicationCloseFrameType, protocol.Version1) 38 Expect(err).ToNot(HaveOccurred()) 39 Expect(frame.IsApplicationError).To(BeTrue()) 40 Expect(frame.ErrorCode).To(BeEquivalentTo(0xcafe)) 41 Expect(frame.ReasonPhrase).To(Equal(reason)) 42 Expect(b.Len()).To(BeZero()) 43 }) 44 45 It("rejects long reason phrases", func() { 46 data := encodeVarInt(0xcafe) 47 data = append(data, encodeVarInt(0x42)...) // frame type 48 data = append(data, encodeVarInt(0xffff)...) // reason phrase length 49 _, err := parseConnectionCloseFrame(bytes.NewReader(data), connectionCloseFrameType, protocol.Version1) 50 Expect(err).To(MatchError(io.EOF)) 51 }) 52 53 It("errors on EOFs", func() { 54 reason := "No recent network activity." 55 data := encodeVarInt(0x19) 56 data = append(data, encodeVarInt(0x1337)...) // frame type 57 data = append(data, encodeVarInt(uint64(len(reason)))...) // reason phrase length 58 data = append(data, []byte(reason)...) 59 b := bytes.NewReader(data) 60 _, err := parseConnectionCloseFrame(b, connectionCloseFrameType, protocol.Version1) 61 Expect(err).NotTo(HaveOccurred()) 62 for i := range data { 63 b := bytes.NewReader(data[:i]) 64 _, err = parseConnectionCloseFrame(b, connectionCloseFrameType, protocol.Version1) 65 Expect(err).To(MatchError(io.EOF)) 66 } 67 }) 68 69 It("parses a frame without a reason phrase", func() { 70 data := encodeVarInt(0xcafe) 71 data = append(data, encodeVarInt(0x42)...) // frame type 72 data = append(data, encodeVarInt(0)...) 73 b := bytes.NewReader(data) 74 frame, err := parseConnectionCloseFrame(b, connectionCloseFrameType, protocol.Version1) 75 Expect(err).ToNot(HaveOccurred()) 76 Expect(frame.ReasonPhrase).To(BeEmpty()) 77 Expect(b.Len()).To(BeZero()) 78 }) 79 }) 80 81 Context("when writing", func() { 82 It("writes a frame without a reason phrase", func() { 83 frame := &ConnectionCloseFrame{ 84 ErrorCode: 0xbeef, 85 FrameType: 0x12345, 86 } 87 b, err := frame.Append(nil, protocol.Version1) 88 Expect(err).ToNot(HaveOccurred()) 89 expected := []byte{connectionCloseFrameType} 90 expected = append(expected, encodeVarInt(0xbeef)...) 91 expected = append(expected, encodeVarInt(0x12345)...) // frame type 92 expected = append(expected, encodeVarInt(0)...) // reason phrase length 93 Expect(b).To(Equal(expected)) 94 }) 95 96 It("writes a frame with a reason phrase", func() { 97 frame := &ConnectionCloseFrame{ 98 ErrorCode: 0xdead, 99 ReasonPhrase: "foobar", 100 } 101 b, err := frame.Append(nil, protocol.Version1) 102 Expect(err).ToNot(HaveOccurred()) 103 expected := []byte{connectionCloseFrameType} 104 expected = append(expected, encodeVarInt(0xdead)...) 105 expected = append(expected, encodeVarInt(0)...) // frame type 106 expected = append(expected, encodeVarInt(6)...) // reason phrase length 107 expected = append(expected, []byte("foobar")...) 108 Expect(b).To(Equal(expected)) 109 }) 110 111 It("writes a frame with an application error code", func() { 112 frame := &ConnectionCloseFrame{ 113 IsApplicationError: true, 114 ErrorCode: 0xdead, 115 ReasonPhrase: "foobar", 116 } 117 b, err := frame.Append(nil, protocol.Version1) 118 Expect(err).ToNot(HaveOccurred()) 119 expected := []byte{applicationCloseFrameType} 120 expected = append(expected, encodeVarInt(0xdead)...) 121 expected = append(expected, encodeVarInt(6)...) // reason phrase length 122 expected = append(expected, []byte("foobar")...) 123 Expect(b).To(Equal(expected)) 124 }) 125 126 It("has proper min length, for a frame containing a QUIC error code", func() { 127 f := &ConnectionCloseFrame{ 128 ErrorCode: 0xcafe, 129 FrameType: 0xdeadbeef, 130 ReasonPhrase: "foobar", 131 } 132 b, err := f.Append(nil, protocol.Version1) 133 Expect(err).ToNot(HaveOccurred()) 134 Expect(b).To(HaveLen(int(f.Length(protocol.Version1)))) 135 }) 136 137 It("has proper min length, for a frame containing an application error code", func() { 138 f := &ConnectionCloseFrame{ 139 IsApplicationError: true, 140 ErrorCode: 0xcafe, 141 ReasonPhrase: "foobar", 142 } 143 b, err := f.Append(nil, protocol.Version1) 144 Expect(err).ToNot(HaveOccurred()) 145 Expect(b).To(HaveLen(int(f.Length(protocol.Version1)))) 146 }) 147 }) 148 })