github.com/quic-go/quic-go@v0.44.0/internal/wire/connection_close_frame_test.go (about)

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