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  })