github.com/TugasAkhir-QUIC/quic-go@v0.0.2-0.20240215011318-d20e25a9054c/http3/frames.go (about)

     1  package http3
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/TugasAkhir-QUIC/quic-go/internal/protocol"
    10  	"github.com/TugasAkhir-QUIC/quic-go/quicvarint"
    11  )
    12  
    13  // FrameType is the frame type of a HTTP/3 frame
    14  type FrameType uint64
    15  
    16  type unknownFrameHandlerFunc func(FrameType, error) (processed bool, err error)
    17  
    18  type frame interface{}
    19  
    20  var errHijacked = errors.New("hijacked")
    21  
    22  func parseNextFrame(r io.Reader, unknownFrameHandler unknownFrameHandlerFunc) (frame, error) {
    23  	qr := quicvarint.NewReader(r)
    24  	for {
    25  		t, err := quicvarint.Read(qr)
    26  		if err != nil {
    27  			if unknownFrameHandler != nil {
    28  				hijacked, err := unknownFrameHandler(0, err)
    29  				if err != nil {
    30  					return nil, err
    31  				}
    32  				if hijacked {
    33  					return nil, errHijacked
    34  				}
    35  			}
    36  			return nil, err
    37  		}
    38  		// Call the unknownFrameHandler for frames not defined in the HTTP/3 spec
    39  		if t > 0xd && unknownFrameHandler != nil {
    40  			hijacked, err := unknownFrameHandler(FrameType(t), nil)
    41  			if err != nil {
    42  				return nil, err
    43  			}
    44  			if hijacked {
    45  				return nil, errHijacked
    46  			}
    47  			// If the unknownFrameHandler didn't process the frame, it is our responsibility to skip it.
    48  		}
    49  		l, err := quicvarint.Read(qr)
    50  		if err != nil {
    51  			return nil, err
    52  		}
    53  
    54  		switch t {
    55  		case 0x0:
    56  			return &dataFrame{Length: l}, nil
    57  		case 0x1:
    58  			return &headersFrame{Length: l}, nil
    59  		case 0x4:
    60  			return parseSettingsFrame(r, l)
    61  		case 0x3: // CANCEL_PUSH
    62  		case 0x5: // PUSH_PROMISE
    63  		case 0x7: // GOAWAY
    64  		case 0xd: // MAX_PUSH_ID
    65  		}
    66  		// skip over unknown frames
    67  		if _, err := io.CopyN(io.Discard, qr, int64(l)); err != nil {
    68  			return nil, err
    69  		}
    70  	}
    71  }
    72  
    73  type dataFrame struct {
    74  	Length uint64
    75  }
    76  
    77  func (f *dataFrame) Append(b []byte) []byte {
    78  	b = quicvarint.Append(b, 0x0)
    79  	return quicvarint.Append(b, f.Length)
    80  }
    81  
    82  type headersFrame struct {
    83  	Length uint64
    84  }
    85  
    86  func (f *headersFrame) Append(b []byte) []byte {
    87  	b = quicvarint.Append(b, 0x1)
    88  	return quicvarint.Append(b, f.Length)
    89  }
    90  
    91  const settingDatagram = 0x33
    92  
    93  type settingsFrame struct {
    94  	Datagram bool
    95  	Other    map[uint64]uint64 // all settings that we don't explicitly recognize
    96  }
    97  
    98  func parseSettingsFrame(r io.Reader, l uint64) (*settingsFrame, error) {
    99  	if l > 8*(1<<10) {
   100  		return nil, fmt.Errorf("unexpected size for SETTINGS frame: %d", l)
   101  	}
   102  	buf := make([]byte, l)
   103  	if _, err := io.ReadFull(r, buf); err != nil {
   104  		if err == io.ErrUnexpectedEOF {
   105  			return nil, io.EOF
   106  		}
   107  		return nil, err
   108  	}
   109  	frame := &settingsFrame{}
   110  	b := bytes.NewReader(buf)
   111  	var readDatagram bool
   112  	for b.Len() > 0 {
   113  		id, err := quicvarint.Read(b)
   114  		if err != nil { // should not happen. We allocated the whole frame already.
   115  			return nil, err
   116  		}
   117  		val, err := quicvarint.Read(b)
   118  		if err != nil { // should not happen. We allocated the whole frame already.
   119  			return nil, err
   120  		}
   121  
   122  		switch id {
   123  		case settingDatagram:
   124  			if readDatagram {
   125  				return nil, fmt.Errorf("duplicate setting: %d", id)
   126  			}
   127  			readDatagram = true
   128  			if val != 0 && val != 1 {
   129  				return nil, fmt.Errorf("invalid value for H3_DATAGRAM: %d", val)
   130  			}
   131  			frame.Datagram = val == 1
   132  		default:
   133  			if _, ok := frame.Other[id]; ok {
   134  				return nil, fmt.Errorf("duplicate setting: %d", id)
   135  			}
   136  			if frame.Other == nil {
   137  				frame.Other = make(map[uint64]uint64)
   138  			}
   139  			frame.Other[id] = val
   140  		}
   141  	}
   142  	return frame, nil
   143  }
   144  
   145  func (f *settingsFrame) Append(b []byte) []byte {
   146  	b = quicvarint.Append(b, 0x4)
   147  	var l protocol.ByteCount
   148  	for id, val := range f.Other {
   149  		l += quicvarint.Len(id) + quicvarint.Len(val)
   150  	}
   151  	if f.Datagram {
   152  		l += quicvarint.Len(settingDatagram) + quicvarint.Len(1)
   153  	}
   154  	b = quicvarint.Append(b, uint64(l))
   155  	if f.Datagram {
   156  		b = quicvarint.Append(b, settingDatagram)
   157  		b = quicvarint.Append(b, 1)
   158  	}
   159  	for id, val := range f.Other {
   160  		b = quicvarint.Append(b, id)
   161  		b = quicvarint.Append(b, val)
   162  	}
   163  	return b
   164  }