github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/http3/capsule.go (about) 1 package http3 2 3 import ( 4 "io" 5 6 "github.com/danielpfeifer02/quic-go-prio-packs/quicvarint" 7 ) 8 9 // CapsuleType is the type of the capsule. 10 type CapsuleType uint64 11 12 type exactReader struct { 13 R *io.LimitedReader 14 } 15 16 func (r *exactReader) Read(b []byte) (int, error) { 17 n, err := r.R.Read(b) 18 if r.R.N > 0 { 19 return n, io.ErrUnexpectedEOF 20 } 21 return n, err 22 } 23 24 // ParseCapsule parses the header of a Capsule. 25 // It returns an io.LimitedReader that can be used to read the Capsule value. 26 // The Capsule value must be read entirely (i.e. until the io.EOF) before using r again. 27 func ParseCapsule(r quicvarint.Reader) (CapsuleType, io.Reader, error) { 28 ct, err := quicvarint.Read(r) 29 if err != nil { 30 if err == io.EOF { 31 return 0, nil, io.ErrUnexpectedEOF 32 } 33 return 0, nil, err 34 } 35 l, err := quicvarint.Read(r) 36 if err != nil { 37 if err == io.EOF { 38 return 0, nil, io.ErrUnexpectedEOF 39 } 40 return 0, nil, err 41 } 42 return CapsuleType(ct), &exactReader{R: io.LimitReader(r, int64(l)).(*io.LimitedReader)}, nil 43 } 44 45 // WriteCapsule writes a capsule 46 func WriteCapsule(w quicvarint.Writer, ct CapsuleType, value []byte) error { 47 b := make([]byte, 0, 16) 48 b = quicvarint.Append(b, uint64(ct)) 49 b = quicvarint.Append(b, uint64(len(value))) 50 if _, err := w.Write(b); err != nil { 51 return err 52 } 53 _, err := w.Write(value) 54 return err 55 }