package module
Version: v0.1.0 Latest Latest

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

Go to latest
Published: Sep 2, 2021 License: MIT Imports: 17 Imported by: 1



wsep is a high performance, web socket command execution protocol. It can be thought of as SSH without encryption.

It's useful in cases where you want to provide a command exec interface into a remote environment. It's implemented with WebSocket so it may be used directly by a browser frontend. Its symmetric design satisfies wsep.Execer for local and remote execution.


Error handling is omitted for brevity.

conn, _, _ := websocket.Dial(ctx, "ws://remote.exec.addr", nil)
defer conn.Close(websocket.StatusAbnormalClosure, "terminate process")

execer := wsep.RemoteExecer(conn)
process, _ := execer.Start(ctx, wsep.Command{
  Command: "cat",
  Args:    []string{"go.mod"},
  Stdin:   false,

go io.Copy(os.Stderr, process.Stderr())
go io.Copy(os.Stdout, process.Stdout())

conn.Close(websocket.StatusNormalClosure, "normal closure")
func (s server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  conn, _ := websocket.Accept(w, r, nil)

  wsep.Serve(r.Context(), conn, wsep.LocalExecer{})

  ws.Close(websocket.StatusNormalClosure, "normal closure")
Development / Testing

Start a local executor:

go run ./dev/server

Start a client:

go run ./dev/client tty bash
go run ./dev/client notty ls
Local performance cost

Local sh through a local wsep connection

$ head -c 100000000 /dev/urandom > /tmp/random; cat /tmp/random | pv | time ./bin/client notty sh -c "cat > /dev/null"

95.4MiB 0:00:00 [ 269MiB/s] [ <=>                                                                                  ]
./bin/client notty sh -c "cat > /dev/null"  0.32s user 0.31s system 31% cpu 2.019 total

Local sh directly

$ head -c 100000000 /dev/urandom > /tmp/random; cat /tmp/random | pv | time  sh -c "cat > /dev/null"

95.4MiB 0:00:00 [1.73GiB/s] [ <=>                                                                                  ]
sh -c "cat > /dev/null"  0.00s user 0.02s system 32% cpu 0.057 total




This section is empty.


This section is empty.


func Serve

func Serve(ctx context.Context, c *websocket.Conn, execer Execer) error

Serve runs the server-side of wsep. The execer may be another wsep connection for chaining. Use LocalExecer for local command execution.


type Command

type Command struct {
	Command    string
	Args       []string
	TTY        bool
	Stdin      bool
	UID        uint32
	GID        uint32
	Env        []string
	WorkingDir string

Command represents an external command to be run

type Execer

type Execer interface {
	Start(ctx context.Context, c Command) (Process, error)

Execer starts commands.

func RemoteExecer

func RemoteExecer(conn *websocket.Conn) Execer

RemoteExecer creates an execution interface from a WebSocket connection.

type ExitError

type ExitError struct {
	Code int

ExitError is sent when the command terminates.

func (ExitError) Error

func (e ExitError) Error() string

type LocalExecer

type LocalExecer struct {
	// ChildProcessPriority overrides the default niceness of all child processes launch by LocalExecer.
	ChildProcessPriority *int

LocalExecer executes command on the local system.

func (LocalExecer) Start

func (l LocalExecer) Start(ctx context.Context, c Command) (Process, error)

Start executes the given command locally

type Process

type Process interface {
	// Pid is populated immediately during a successful start with the process ID.
	Pid() int
	// Stdout returns an io.WriteCloser that will pipe writes to the remote command.
	// Closure of stdin sends the corresponding close message.
	Stdin() io.WriteCloser
	// Stdout returns an io.Reader that is connected to the command's standard output.
	Stdout() io.Reader
	// Stderr returns an io.Reader that is connected to the command's standard error.
	Stderr() io.Reader
	// Resize resizes the TTY if a TTY is enabled.
	Resize(ctx context.Context, rows, cols uint16) error
	// Wait returns ExitError when the command terminates with a non-zero exit code.
	Wait() error
	// Close terminates the process and underlying connection(s).
	// It must be called otherwise a connection or process may leak.
	Close() error

Process represents a started command.


Path Synopsis

Jump to

Keyboard shortcuts

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