Files
monibuca/plugin/webtransport/internal/frames.go
2025-04-16 13:58:41 +08:00

67 lines
1.2 KiB
Go

package h3
import (
"io"
"github.com/quic-go/quic-go/quicvarint"
)
// Frame types
const (
FRAME_DATA = 0x00
FRAME_HEADERS = 0x01
FRAME_CANCEL_PUSH = 0x03
FRAME_SETTINGS = 0x04
FRAME_PUSH_PROMISE = 0x05
FRAME_GOAWAY = 0x07
FRAME_MAX_PUSH_ID = 0x0D
FRAME_WEBTRANSPORT_STREAM = 0x41
)
// HTTP/3 frame
type Frame struct {
Type uint64
SessionID uint64
Length uint64
Data []byte
}
func (f *Frame) Read(r io.Reader) error {
qr := quicvarint.NewReader(r)
t, err := quicvarint.Read(qr)
if err != nil {
return err
}
l, err := quicvarint.Read(qr)
if err != nil {
return err
}
f.Type = t
// For most (but not all) frame types, l is the data length
switch t {
case FRAME_WEBTRANSPORT_STREAM:
f.Length = 0
f.SessionID = l
f.Data = []byte{}
return nil
default:
f.Length = l
f.Data = make([]byte, l)
_, err := r.Read(f.Data)
return err
}
}
func (f *Frame) Write(w io.Writer) (int, error) {
var buf []byte
buf = quicvarint.Append(buf, f.Type)
if f.Type == FRAME_WEBTRANSPORT_STREAM {
buf = quicvarint.Append(buf, f.SessionID)
} else {
buf = quicvarint.Append(buf, f.Length)
}
return w.Write(append(buf, f.Data...))
}