wsstream

package
v0.29.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2023 License: Apache-2.0 Imports: 12 Imported by: 14

Documentation

Overview

Package wsstream contains utilities for streaming content over WebSockets. The Conn type allows callers to multiplex multiple read/write channels over a single websocket.

"channel.k8s.io"

The Websocket RemoteCommand subprotocol "channel.k8s.io" prepends each binary message with a byte indicating the channel number (zero indexed) the message was sent on. Messages in both directions should prefix their messages with this channel byte. Used for remote execution, the channel numbers are by convention defined to match the POSIX file-descriptors assigned to STDIN, STDOUT, and STDERR (0, 1, and 2). No other conversion is performed on the raw subprotocol - writes are sent as they are received by the server.

Example client session:

CONNECT http://server.com with subprotocol "channel.k8s.io"
WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN)
READ  []byte{1, 10}                # receive "\n" on channel 1 (STDOUT)
CLOSE

"v2.channel.k8s.io"

The second Websocket subprotocol version "v2.channel.k8s.io" is the same as version 1, but it is the first "versioned" subprotocol.

"v3.channel.k8s.io"

The third version of the Websocket RemoteCommand subprotocol adds another channel for terminal resizing events. This channel is prepended with the byte '3', and it transmits two window sizes (encoding TerminalSize struct) with integers in the range (0,65536].

"v4.channel.k8s.io"

The fourth version of the Websocket RemoteCommand subprotocol adds a channel for errors. This channel returns structured errors containing process exit codes. The error is "apierrors.StatusError{}".

"v5.channel.k8s.io"

The fifth version of the Websocket RemoteCommand subprotocol adds a CLOSE signal, which is sent as the first byte of the message. The second byte is the channel id. This CLOSE signal is handled by the websocket server by closing the stream, allowing the other streams to complete transmission if necessary, and gracefully shutdown the connection.

Example client session:

CONNECT http://server.com with subprotocol "v5.channel.k8s.io"
WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN)
WRITE []byte{255, 0}               # send CLOSE signal (STDIN)
CLOSE

Index

Constants

View Source
const Base64ChannelWebSocketProtocol = "base64.channel.k8s.io"

The Websocket subprotocol "base64.channel.k8s.io" base64 encodes each message with a character indicating the channel number (zero indexed) the message was sent on. Messages in both directions should prefix their messages with this channel char. When used for remote execution, the channel numbers are by convention defined to match the POSIX file-descriptors assigned to STDIN, STDOUT, and STDERR ('0', '1', and '2'). The data received on the server is base64 decoded (and must be be valid) and data written by the server to the client is base64 encoded.

Example client session:

CONNECT http://server.com with subprotocol "base64.channel.k8s.io"
WRITE []byte{48, 90, 109, 57, 118, 67, 103, 111, 61} # send "foo\n" (base64: "Zm9vCgo=") on channel '0' (STDIN)
READ  []byte{49, 67, 103, 61, 61} # receive "\n" (base64: "Cg==") on channel '1' (STDOUT)
CLOSE
View Source
const ChannelWebSocketProtocol = "channel.k8s.io"

The Websocket subprotocol "channel.k8s.io" prepends each binary message with a byte indicating the channel number (zero indexed) the message was sent on. Messages in both directions should prefix their messages with this channel byte. When used for remote execution, the channel numbers are by convention defined to match the POSIX file-descriptors assigned to STDIN, STDOUT, and STDERR (0, 1, and 2). No other conversion is performed on the raw subprotocol - writes are sent as they are received by the server.

Example client session:

CONNECT http://server.com with subprotocol "channel.k8s.io"
WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN)
READ  []byte{1, 10}                # receive "\n" on channel 1 (STDOUT)
CLOSE

Variables

This section is empty.

Functions

func IgnoreReceives

func IgnoreReceives(ws *websocket.Conn, timeout time.Duration)

IgnoreReceives reads from a WebSocket until it is closed, then returns. If timeout is set, the read and write deadlines are pushed every time a new message is received.

func IsWebSocketRequest

func IsWebSocketRequest(req *http.Request) bool

IsWebSocketRequest returns true if the incoming request contains connection upgrade headers for WebSockets.

func NewDefaultChannelProtocols

func NewDefaultChannelProtocols(channels []ChannelType) map[string]ChannelProtocolConfig

NewDefaultChannelProtocols returns a channel protocol map with the subprotocols "", "channel.k8s.io", "base64.channel.k8s.io" and the given channels.

func NewDefaultReaderProtocols

func NewDefaultReaderProtocols() map[string]ReaderProtocolConfig

NewDefaultReaderProtocols returns a stream protocol map with the subprotocols "", "channel.k8s.io", "base64.channel.k8s.io".

Types

type ChannelProtocolConfig

type ChannelProtocolConfig struct {
	Binary   bool
	Channels []ChannelType
}

ChannelProtocolConfig describes a websocket subprotocol with channels.

type ChannelType

type ChannelType int
const (
	IgnoreChannel ChannelType = iota
	ReadChannel
	WriteChannel
	ReadWriteChannel
)

type Conn

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

Conn supports sending multiple binary channels over a websocket connection.

func NewConn

func NewConn(protocols map[string]ChannelProtocolConfig) *Conn

NewConn creates a WebSocket connection that supports a set of channels. Channels begin each web socket message with a single byte indicating the channel number (0-N). 255 is reserved for future use. The channel types for each channel are passed as an array, supporting the different duplex modes. Read and Write refer to whether the channel can be used as a Reader or Writer.

The protocols parameter maps subprotocol names to ChannelProtocols. The empty string subprotocol name is used if websocket.Config.Protocol is empty.

func (*Conn) Close

func (conn *Conn) Close() error

Close is only valid after Open has been called

func (*Conn) Open

func (conn *Conn) Open(w http.ResponseWriter, req *http.Request) (string, []io.ReadWriteCloser, error)

Open the connection and create channels for reading and writing. It returns the selected subprotocol, a slice of channels and an error.

func (*Conn) SetIdleTimeout

func (conn *Conn) SetIdleTimeout(duration time.Duration)

SetIdleTimeout sets the interval for both reads and writes before timeout. If not specified, there is no timeout on the connection.

type Reader

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

Reader supports returning an arbitrary byte stream over a websocket channel.

func NewReader

func NewReader(r io.Reader, ping bool, protocols map[string]ReaderProtocolConfig) *Reader

NewReader creates a WebSocket pipe that will copy the contents of r to a provided WebSocket connection. If ping is true, a zero length message will be sent to the client before the stream begins reading.

The protocols parameter maps subprotocol names to StreamProtocols. The empty string subprotocol name is used if websocket.Config.Protocol is empty.

func (*Reader) Copy

func (r *Reader) Copy(w http.ResponseWriter, req *http.Request) error

Copy the reader to the response. The created WebSocket is closed after this method completes.

func (*Reader) SetIdleTimeout

func (r *Reader) SetIdleTimeout(duration time.Duration)

SetIdleTimeout sets the interval for both reads and writes before timeout. If not specified, there is no timeout on the reader.

type ReaderProtocolConfig

type ReaderProtocolConfig struct {
	Binary bool
}

ReaderProtocolConfig describes a websocket subprotocol with one stream.

Jump to

Keyboard shortcuts

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