websocket

package
v2.1.2 Latest Latest
Warning

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

Go to latest
Published: Sep 5, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package websocket implements RFC 6455 WebSocket servers and outbound clients for net/http applications.

Index

Constants

View Source
const (
	OpcodeContinuation = 0
	OpcodeText         = 1
	OpcodeBinary       = 2
	OpcodeClose        = 8
	OpcodePing         = 9
	OpcodePong         = 10
)

Frame opcodes defined in RFC 6455

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

Close codes defined in RFC 6455

View Source
const (
	TextMessage   = OpcodeText
	BinaryMessage = OpcodeBinary
	CloseMessage  = OpcodeClose
	PingMessage   = OpcodePing
	PongMessage   = OpcodePong
)

WebSocket message-type aliases. The wire-level Opcode* constants live in frame.go; these names are the public, gorilla-compatible API.

Variables

View Source
var (
	ErrInvalidFrame           = errors.New("invalid frame")
	ErrControlFrameTooBig     = errors.New("control frame too big")
	ErrFragmentedControl      = errors.New("fragmented control frame")
	ErrUnexpectedContinuation = errors.New("unexpected continuation frame")
	ErrInvalidCloseCode       = errors.New("invalid close code")
	ErrInvalidUTF8            = errors.New("invalid UTF-8 in text frame")
	ErrMaskingViolation       = errors.New("invalid frame masking")
	ErrNonCanonicalLength     = errors.New("non-canonical payload length")
)

Frame errors

View Source
var (
	ErrNotWebSocket        = errors.New("not a websocket handshake")
	ErrBadHandshake        = errors.New("bad handshake")
	ErrUnsupportedVersion  = errors.New("unsupported websocket version")
	ErrMissingKey          = errors.New("missing Sec-WebSocket-Key")
	ErrMalformedKey        = errors.New("malformed Sec-WebSocket-Key")
	ErrSubprotocolRequired = errors.New("websocket subprotocol required")
)

Errors

View Source
var ErrMessageTooBig = errors.New("message too big")

Error returned when message exceeds size limit

Functions

func CheckOriginWithAllowedList

func CheckOriginWithAllowedList(allowedOrigins []string) func(r *http.Request) bool

CheckOriginWithAllowedList checks if the origin is in the allowed list

func DefaultCheckOrigin

func DefaultCheckOrigin(r *http.Request) bool

DefaultCheckOrigin provides a safe default origin check that enforces same-origin policy

func IsCloseError

func IsCloseError(err error, codes ...int) bool

IsCloseError returns true if the error is a close error with one of the specified codes

func IsUnexpectedCloseError

func IsUnexpectedCloseError(err error, expectedCodes ...int) bool

IsUnexpectedCloseError checks if the error is an unexpected close error

func PerformHandshake

func PerformHandshake(w http.ResponseWriter, r *http.Request, opts *HandshakeOptions) (net.Conn, *bufio.ReadWriter, error)

PerformHandshake performs the WebSocket handshake

func ValidateHandshake

func ValidateHandshake(r *http.Request) error

ValidateHandshake validates a WebSocket upgrade request

Types

type Conn

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

Conn represents a WebSocket connection

func Dial

func Dial(ctx context.Context, rawURL string, opts *DialOptions) (*Conn, *http.Response, error)

Dial opens a WebSocket connection to a ws or wss URL. The context covers TCP, TLS, request, response, and redirect processing. When HTTPClient is provided, its transport owns dialing, TLS, and proxy behavior. On an HTTP handshake failure, the returned response is non-nil when one was received; its body is buffered up to 64 KiB and remains readable after Dial returns.

func (*Conn) Close

func (c *Conn) Close() error

Close closes the WebSocket connection

func (*Conn) CloseHandler

func (c *Conn) CloseHandler() func(code int, text string) error

CloseHandler returns the current close handler

func (*Conn) CloseWithStatus

func (c *Conn) CloseWithStatus(code int, reason string) error

CloseWithStatus sends a close frame with code and reason, then closes the network connection. reason must be valid UTF-8 and fit in one control frame.

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

LocalAddr returns the local network address

func (*Conn) PingHandler

func (c *Conn) PingHandler() func(appData string) error

PingHandler returns the current ping handler

func (*Conn) PongHandler

func (c *Conn) PongHandler() func(appData string) error

PongHandler returns the current pong handler

func (*Conn) Read

func (c *Conn) Read(ctx context.Context) (messageType int, p []byte, err error)

Read reads one text or binary message. Canceling ctx interrupts the read. Only one goroutine may call Read or ReadMessage at a time.

func (*Conn) ReadJSON

func (c *Conn) ReadJSON(v any) error

ReadJSON reads a JSON-encoded message from the connection

func (*Conn) ReadMessage

func (c *Conn) ReadMessage() (messageType int, p []byte, err error)

ReadMessage reads a message from the WebSocket connection. Control-frame dispatch (ping/pong/close) is handled inside lowConn so user-installed handlers fire even when this method blocks on a Text/Binary read.

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

RemoteAddr returns the remote network address

func (*Conn) SetCloseHandler

func (c *Conn) SetCloseHandler(h func(code int, text string) error)

SetCloseHandler sets the handler invoked when a close frame arrives. Passing nil installs the default no-op (the auto-echo of the close frame happens unconditionally inside the wire reader).

func (*Conn) SetPingHandler

func (c *Conn) SetPingHandler(h func(appData string) error)

SetPingHandler sets the handler invoked when a ping frame arrives. When a user handler is installed the wire reader stops sending its automatic pong — the handler must do that (or not) explicitly. Passing nil clears the handler and restores the default auto-pong behaviour.

func (*Conn) SetPongHandler

func (c *Conn) SetPongHandler(h func(appData string) error)

SetPongHandler sets the handler invoked when a pong frame arrives. Passing nil installs a no-op default.

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline sets the read deadline on the connection

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets the write deadline on the connection

func (*Conn) Subprotocol

func (c *Conn) Subprotocol() string

Subprotocol returns the subprotocol selected during the opening handshake.

func (*Conn) Write

func (c *Conn) Write(ctx context.Context, messageType int, data []byte) error

Write writes one complete text or binary message. Canceling ctx interrupts the write. Only one goroutine may call Write, WriteMessage, or WriteControl at a time.

func (*Conn) WriteControl

func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error

WriteControl writes a control message with the given deadline

func (*Conn) WriteJSON

func (c *Conn) WriteJSON(v any) error

WriteJSON writes a JSON-encoded message to the connection

func (*Conn) WriteMessage

func (c *Conn) WriteMessage(messageType int, data []byte) error

WriteMessage writes a message to the WebSocket connection

type DialOptions

type DialOptions struct {
	// HTTPClient performs the opening handshake. Its Transport, proxy,
	// cookie jar, redirect callback, and timeout are preserved. A successful
	// 101 response body must implement io.ReadWriteCloser; http.Transport does.
	// HTTPClient cannot be combined with NetDialer or TLSConfig.
	HTTPClient *http.Client

	// HTTPHeader is copied into the opening handshake. Dial owns the
	// WebSocket protocol headers and overwrites conflicting values.
	HTTPHeader http.Header

	// Subprotocols lists protocols in client preference order.
	Subprotocols []string

	// TLSConfig configures wss connections. It is cloned before use.
	TLSConfig *tls.Config

	// NetDialer controls the underlying TCP connection. The zero value uses
	// net.Dialer.
	NetDialer *net.Dialer

	// MaxMessageSize limits a complete message read from the peer. Values at
	// or below zero use the package default of 1 MiB.
	MaxMessageSize int64
}

DialOptions configures an outbound WebSocket connection.

type Frame

type Frame struct {
	Fin     bool
	RSV1    bool
	RSV2    bool
	RSV3    bool
	Opcode  int
	Masked  bool
	Payload []byte
	MaskKey [4]byte
}

Frame represents a WebSocket frame

func (*Frame) IsControl

func (f *Frame) IsControl() bool

IsControl returns true if this is a control frame

func (*Frame) IsData

func (f *Frame) IsData() bool

IsData returns true if this is a data frame

type FrameReader

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

FrameReader reads WebSocket frames

func NewFrameReader

func NewFrameReader(r *bufio.Reader, maxMessageSize int64) *FrameReader

NewFrameReader creates a new frame reader

func (*FrameReader) ReadFrame

func (fr *FrameReader) ReadFrame() (*Frame, error)

ReadFrame reads a single frame from the reader

type FrameWriter

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

FrameWriter writes WebSocket frames

func NewFrameWriter

func NewFrameWriter(w *bufio.Writer, isServer bool) *FrameWriter

NewFrameWriter creates a new frame writer

func (*FrameWriter) WriteFrame

func (fw *FrameWriter) WriteFrame(frame *Frame) error

WriteFrame writes a frame to the writer

type HandshakeOptions

type HandshakeOptions struct {
	// CheckOrigin returns true if the request Origin header is acceptable
	CheckOrigin func(r *http.Request) bool
	// Subprotocols is the list of supported subprotocols
	Subprotocols []string
	// RequireProtocol rejects the handshake unless a supported subprotocol is negotiated.
	RequireProtocol bool
	// ResponseHeader is copied into the 101 Switching Protocols response.
	ResponseHeader http.Header
	// Extensions is the list of supported extensions
	Extensions []string
	// BeforeUpgrade is called before the upgrade response is sent
	BeforeUpgrade func(w http.ResponseWriter, r *http.Request) error
}

HandshakeOptions contains options for WebSocket handshake

type Upgrader

type Upgrader struct {
	// CheckOrigin returns true if the request Origin header is acceptable
	// If nil, a safe default is used that checks for same-origin requests
	CheckOrigin func(r *http.Request) bool

	// Subprotocols specifies the server's supported protocols in order of preference
	Subprotocols []string

	// Error specifies the function for generating HTTP error responses
	Error func(w http.ResponseWriter, r *http.Request, status int, reason error)

	// MaxMessageSize is the maximum size for a message read from the peer
	MaxMessageSize int64

	// HandshakeTimeout bounds writing the upgrade response after the
	// application-owned BeforeUpgrade hook returns.
	HandshakeTimeout time.Duration

	// BeforeUpgrade is called after origin check but before sending upgrade response
	// This can be used for authentication, rate limiting, or other pre-upgrade checks
	BeforeUpgrade func(w http.ResponseWriter, r *http.Request) error

	// AllowedOrigins is a list of allowed origins for CORS
	// If empty and CheckOrigin is nil, same-origin policy is enforced
	AllowedOrigins []string

	// RequireProtocol ensures the client specifies one of the supported subprotocols
	RequireProtocol bool
}

Upgrader upgrades HTTP connections to WebSocket connections.

func (*Upgrader) Upgrade

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

Upgrade upgrades an HTTP connection to a WebSocket connection

Jump to

Keyboard shortcuts

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