websocket

package
v0.8.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package websocket provides a low-level, zero-dependency WebSocket implementation following RFC 6455. It is used internally by Aero but can also be imported directly for custom WebSocket handling.

Index

Constants

View Source
const (
	MaxHeaderSize  = 14
	MinHeaderSize  = 2
	MaxFrameLength = 1<<63 - 1
)

Variables

View Source
var (
	ErrBadMethod              = errors.New("websocket: request method must be GET")
	ErrBadProtocol            = errors.New("websocket: HTTP version must be at least 1.1")
	ErrBadHost                = errors.New("websocket: missing Host header")
	ErrBadUpgrade             = errors.New("websocket: missing or invalid Upgrade header")
	ErrBadConnection          = errors.New("websocket: missing or invalid Connection header")
	ErrBadSecKey              = errors.New("websocket: missing or invalid Sec-WebSocket-Key")
	ErrBadSecVersion          = errors.New("websocket: missing Sec-WebSocket-Version")
	ErrHeaderLengthUnexpected = errors.New("websocket: header length is too large")
	ErrConnClosed             = errors.New("websocket: connection closed")
	ErrFrameTooLarge          = errors.New("websocket: frame too large")
	ErrBadHandshake           = errors.New("websocket: bad handshake")
	ErrNotWebSocket           = errors.New("websocket: request is not a websocket upgrade")
	ErrBadWebSocketKey        = errors.New("websocket: missing or invalid Sec-WebSocket-Key")
	ErrBadWebSocketVersion    = errors.New("websocket: client must use version 13")
	ErrBadWebSocketKeyLen     = errors.New("websocket: invalid Sec-WebSocket-Key length")
	ErrForbiddenOrigin        = errors.New("websocket: origin not allowed")
	ErrHijackNotSupport       = errors.New("websocket: response does not support hijacking")
	ErrUpgradeRequired        = errors.New("websocket: unsupported Sec-WebSocket-Version, only 13 is supported")
)

Functions

func Mask

func Mask(key [4]byte, b []byte)

Mask applies the WebSocket masking algorithm in-place on b using the 4-byte key. It processes 8 bytes at a time via unsafe uint64 XOR for maximum throughput, falling back to byte-by-byte for the remainder. Masking and unmasking use the same operation, so calling Mask twice restores the original data.

func PutCloseFrameBody

func PutCloseFrameBody(p []byte, code CloseStatusCode, reason string)

PutCloseFrameBody encodes the given status code and reason string into p following the RFC 6455 close frame body layout. p must be at least 2 + len(reason) bytes.

func ReadHeader

func ReadHeader(r *bufio.Reader, dst *Header) error

ReadHeader reads and parses a WebSocket frame header from r into dst. Returns an error if the stream is malformed or the connection is closed.

func RsvBits

func RsvBits(rsv byte) (r1, r2, r3 bool)

RsvBits unpacks the three RSV bits from a raw rsv byte into individual booleans.

func WriteFrame

func WriteFrame(w *bufio.Writer, f Frame) error

WriteFrame encodes and writes a complete WebSocket frame to w.

func WriteHeader

func WriteHeader(w *bufio.Writer, h Header) error

WriteHeader encodes and writes a WebSocket frame header to w.

Types

type CloseError

type CloseError struct {
	Code   uint16
	Reason string
}

CloseError is returned when the remote peer sends a close frame. It carries the status code and optional reason string.

func NewCloseError

func NewCloseError(code CloseStatusCode, reason string) *CloseError

NewCloseError creates a CloseError with the given status code and reason.

func (*CloseError) Error

func (e *CloseError) Error() string

Error implements the error interface, returning a human-readable description of the close event.

type CloseStatusCode added in v0.8.5

type CloseStatusCode uint16

CloseStatusCode represents a WebSocket close status code as defined in RFC 6455 §7.4.

const (
	CloseNormalClosure      CloseStatusCode = 1000
	CloseGoingAway          CloseStatusCode = 1001
	CloseProtocolError      CloseStatusCode = 1002
	CloseUnsupportedData    CloseStatusCode = 1003
	CloseNoStatusReceived   CloseStatusCode = 1005
	CloseAbnormalClosure    CloseStatusCode = 1006
	CloseInvalidPayload     CloseStatusCode = 1007
	ClosePolicyViolation    CloseStatusCode = 1008
	CloseMessageTooBig      CloseStatusCode = 1009
	CloseMandatoryExtension CloseStatusCode = 1010
	CloseInternalServerErr  CloseStatusCode = 1011
	CloseServiceRestart     CloseStatusCode = 1012
	CloseTryAgainLater      CloseStatusCode = 1013
	CloseTLSHandshake       CloseStatusCode = 1015
)

func ParseCloseFrameData

func ParseCloseFrameData(payload []byte) (code CloseStatusCode, reason string)

ParseCloseFrameData decodes the status code and reason string from a close frame payload. Returns CloseNormalClosure with an empty reason if the payload is empty.

func ParseCloseFrameDataUnsafe

func ParseCloseFrameDataUnsafe(payload []byte) (code CloseStatusCode, reason string)

ParseCloseFrameDataUnsafe is identical to ParseCloseFrameData but avoids a heap allocation by returning the reason as a string backed by the original payload slice. The caller must not retain the payload after the returned string is used.

func (CloseStatusCode) Value added in v0.8.5

func (s CloseStatusCode) Value() uint16

Value returns the numeric uint16 representation of the status code, suitable for writing into a close frame payload.

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a WebSocket connection over a raw net.Conn. It provides frame-level read/write primitives. For a higher-level API, use [aero.WSConn] via [aero.WebSocket].

func NewConn

func NewConn(nc net.Conn, br *bufio.Reader, bw *bufio.Writer) *Conn

NewConn wraps an established net.Conn with buffered reader and writer into a WebSocket Conn ready for frame exchange.

func (*Conn) Close

func (c *Conn) Close() error

Close sends a normal closure frame and closes the underlying connection.

func (*Conn) CloseWithError

func (c *Conn) CloseWithError(code CloseStatusCode, reason string) error

CloseWithError sends a close frame with the given status code and reason before closing the underlying connection.

func (*Conn) NextHeader

func (c *Conn) NextHeader(hdr *Header) error

NextHeader reads and returns the next frame header from the connection into hdr. Must be called before Conn.ReadPayload for each frame. Returns an error if the connection is closed or the frame is malformed.

func (*Conn) ReadPayload

func (c *Conn) ReadPayload(hdr Header, dst []byte) error

ReadPayload reads the payload of the frame described by hdr into dst. dst must be pre-allocated to at least hdr.Length bytes. Unmasking is applied automatically if the frame is masked.

func (*Conn) WriteMessage

func (c *Conn) WriteMessage(op OpCode, payload []byte) error

WriteMessage sends a single unfragmented message with the given opcode and payload. It is safe to call from a single goroutine at a time.

type Frame

type Frame struct {
	Header  Header
	Payload []byte
}

Frame is a complete WebSocket frame ready to be written to the wire.

func NewBinaryFrame

func NewBinaryFrame(p []byte) Frame

NewBinaryFrame constructs a FIN binary frame with the given payload.

func NewCloseFrame

func NewCloseFrame(p []byte) Frame

NewCloseFrame constructs a close frame with a raw pre-encoded payload. Prefer NewCloseFrameWithReason when constructing close frames manually.

func NewCloseFrameWithReason

func NewCloseFrameWithReason(code CloseStatusCode, reason string) Frame

NewCloseFrameWithReason constructs a close frame with the given status code and reason string encoded into the payload per RFC 6455 §5.5.1.

func NewFrame

func NewFrame(op OpCode, fin bool, p []byte) Frame

NewFrame constructs a WebSocket frame with the given opcode, FIN bit, and payload.

func NewPingFrame

func NewPingFrame(p []byte) Frame

NewPingFrame constructs a ping control frame with an optional payload (max 125 bytes).

func NewPongFrame

func NewPongFrame(p []byte) Frame

NewPongFrame constructs a pong control frame with an optional payload (max 125 bytes).

func NewTextFrame

func NewTextFrame(p []byte) Frame

NewTextFrame constructs a FIN text frame with the given UTF-8 payload.

type Handshake

type Handshake struct {
	// contains filtered or unexported fields
}
type Header struct {
	Fin    bool    // FIN bit - true if this is the final fragment.
	Rsv    byte    // RSV1-RSV3 bits packed into the low 3 bits.
	OpCode OpCode  // Frame opcode.
	Masked bool    // Whether the payload is masked.
	Mask   [4]byte // Masking key (only meaningful when Masked is true).
	Length uint64  // Payload length in bytes.
}

Header represents a parsed WebSocket frame header.

func (Header) IsControl

func (h Header) IsControl() bool

IsControl reports whether the frame header describes a control frame.

func (Header) RSV1

func (h Header) RSV1() bool

RSV1 reports whether the RSV1 extension bit is set in the frame header.

func (Header) RSV2

func (h Header) RSV2() bool

RSV2 reports whether the RSV2 extension bit is set in the frame header.

func (Header) RSV3

func (h Header) RSV3() bool

RSV3 reports whether the RSV3 extension bit is set in the frame header.

type OpCode

type OpCode byte

OpCode represents a WebSocket frame opcode as defined in RFC 6455 §5.2.

const (
	OpContinuation OpCode = 0x0
	OpText         OpCode = 0x1
	OpBinary       OpCode = 0x2
	// 0x3–0x7: reserved data frames
	OpClose OpCode = 0x8
	OpPing  OpCode = 0x9
	OpPong  OpCode = 0xA
)

func (OpCode) IsControl

func (op OpCode) IsControl() bool

IsControl reports whether op is a control opcode (Close, Ping, or Pong).

func (OpCode) IsData

func (op OpCode) IsData() bool

IsData reports whether op is a data opcode (Text or Binary).

func (OpCode) IsReserved

func (op OpCode) IsReserved() bool

IsReserved reports whether op is a reserved opcode not defined by RFC 6455.

type Upgrader

type Upgrader struct {
	// CheckOrigin validates the Origin header of the upgrade request.
	// Return false to reject the handshake with 403 Forbidden.
	// If nil, all origins are accepted.
	CheckOrigin func(origin string) bool

	// Subprotocols lists the server's supported WebSocket subprotocols.
	// The best match with the client's Sec-WebSocket-Protocol header is
	// selected and echoed in the 101 response.
	Subprotocols []string

	// WriteTimeout sets the deadline for writing the handshake response.
	// A zero value means no timeout.
	WriteTimeout time.Duration
}

Upgrader performs the WebSocket HTTP handshake and upgrades the connection.

func (*Upgrader) Upgrade

func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request) (*Conn, error)

Upgrade validates the HTTP upgrade request and performs the WebSocket handshake. On success it returns a Conn backed by the hijacked connection. On failure it writes an appropriate HTTP error response and returns an error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL