Introduction

This is documentation for Websocat4 (which eventually will be designated as just "Websocat").

Websocat is a flexible tool that bridges Web world (with HTTP, WebSockets, browsers) and UNIX/networking world (with sockets, processes and file descriptors).

Easiest use is to just serve as as command-line client and server to manually check WebSocket-related things during development, but it also contains many other socket types and modes.

Basic examples

CLI WebSocket client

$ websocat wss://ws.vi-server.org/mirror
1234
1234
555555
555555

By default, if you just specify a WebSocket URL as a sole parameter, Websocat will connect to it and turn each line you types in console into a WebSocket text message and each incoming WebSocket message into a line.

Embedded newslines in WebSocket messages would be substituted by spaces to preserve one line = one message properly.

There are a number of command line switches and options to adjust details of this behaviour, e.g. you can use --separator-n=2 to make empty lines act as a delimiter instead of line feeds.

CLI WebSocket server

$ websocat -s 1234

It would start listening ws://127.0.0.1:1234 and dumping all incoming WebSocket messages to console. Typed lines will be also converted into WebSocket messages aimed at clients.

It supports multiple simultaneously connected clients, though by default only one of connected clients would get replies from console.

--help output

Command-line client for web sockets, like netcat/curl/socat for ws://.

Usage: websocat [OPTIONS] <SPEC1> [SPEC2]

Arguments:
  <SPEC1>
          Left endpoint (e.g. a WebSocket URL). May be prefixed by one or more overlays

  [SPEC2]
          Right endpoint (or stdout if omitted). May be prefixed by one or more overlays

Options:
      --dump-spec
          do not execute this Websocat invocation, print equivalent Rhai script instead

      --dump-spec-phase0
          do not execute this Websocat invocation, print debug representation of specified arguments. In --compose mode it should be the second argument (i.e. just after --compose)

      --dump-spec-phase1
          do not execute this Websocat invocation, print debug representation of specified arguments

      --dump-spec-phase2
          do not execute this Websocat invocation, print debug representation of specified arguments

  -x, --scenario
          execute specified file as Rhai script (e.g. resulting from --dump-spec option output)

  -t, --text
          use text mode (one line = one WebSocket text message)

  -b, --binary
          use binary mode (arbitrary byte chunk = one WebSocket binary message)

      --late-resolve
          resolve hostnames to IP addresses late (every time when forwarding a connection) instead of one time at the beginning

  -k, --insecure
          accept invalid domains and root certificates for TLS client connections

      --tls-domain <TLS_DOMAIN>
          manually specify domain for `tls:` overlay or override domain for `wss://` URLs

  -s, --server
          listen for WebSocket connections instead of establishing client WebSocket connection

      --log-verbose
          log more data from `log:` overlay

      --log-omit-content
          do not log full content of the data from `log:` overlay, just chunk lengths

      --log-hex
          use hex lines instead of escaped characters for `log:`` overlay

      --log-timestamps
          Include relative timestamps in log messages

      --log-traffic
          automatically insert `log:` overlay in an appropriate place to debug issues by displaying traffic chunks

      --ws-c-uri <WS_C_URI>
          URI for `ws-c:` overlay

      --read-buffer-limit <READ_BUFFER_LIMIT>
          parameter for read_chunk_limiter: overlay, defaults to 1

      --write-buffer-limit <WRITE_BUFFER_LIMIT>
          parameter for write_chunk_limiter: overlay, defaults to 1

      --separator <SEPARATOR>
          override byte value that separates stdin-supplied text WebSocket messages from each other from default '\n'

      --separator-n <SEPARATOR_N>
          require this number of newline (or other) bytes to separate WebSocket messages

      --separator-inhibit-substitution
          prevent mangling incoming text WebSocket by replacing `\n`  (or other separator sequence) with spaces (and trimming leading and trailing separator bytes)

      --separator-inline
          make separator (such as trailing \n) a part text WebSocket messages, do not remove it when splitting messages

  -0, --null-terminated
          Same as setting `--separator` to `0`. Make text mode messages separated by zero byte instead of newline

      --udp-bind-target-addr <UDP_BIND_TARGET_ADDR>
          initial target sendto address for `udp-bind:` mode. If unset, it will try to send to neutral address (unsuccessfully)

      --udp-bind-restrict-to-one-address
          only allow incoming datagrams from specified target address for `upd-bind:` mode

      --udp-bind-redirect-to-last-seen-address
          automatically change target address for `udp-bind:` mode based in coming datagrams

      --udp-bind-connect-to-first-seen-address
          turn `udp-bind:` into `udp-connect:` as soon as we receive some datagram. Implied when `--udp-bind-target-addr` is not specified

      --udp-bind-inhibit-send-errors
          ignore failed `sendto` calls. Attempts to send without a configured target address are ignored implicitly

      --udp-server-timeout-ms <UDP_SERVER_TIMEOUT_MS>
          Client timeout of udp-server: mode

      --udp-server-max-clients <UDP_SERVER_MAX_CLIENTS>
          Maximum number of parallel handlers in udp-server: mode

      --udp-server-buffer-size <UDP_SERVER_BUFFER_SIZE>
          Size of receive buffer for udp-server: mode. `-B` is distinct, but can also affect operation

      --udp-server-qlen <UDP_SERVER_QLEN>
          Queue length for udp-server: mode

      --udp-server-backpressure
          Delay receiving more datagrams in udp-server: mode instead of dropping them in case of slow handlers

      --exec-args [<EXEC_ARGS>...]
          Command line arguments for `exec:` endpoint.
          
          This option is interpreted specially: it stops processing all other options uses everything after it as a part of the command line

      --exec-monitor-exits
          Immediately expire `cmd:` or `exec:` endpoints if child process terminates.
          
          This may discard some data that remained buffered in a pipe.

      --exec-uid <EXEC_UID>
          On Unix, try to set uid to this numeric value for the subprocess

      --exec-gid <EXEC_GID>
          On Unix, try to set uid to this numeric value for the subprocess

      --exec-chdir <EXEC_CHDIR>
          Try to change current directory to this value for the subprocess

      --exec-windows-creation-flags <EXEC_WINDOWS_CREATION_FLAGS>
          On Windows, try to set this numeric process creation flags

      --exec-arg0 <EXEC_ARG0>
          On Unix, set first subprocess's argv[0] to this value

      --exec-dup2 <EXEC_DUP2>
          On Unix, use dup2 and forward sockets directly to child processes (ignoring any overlays) instead of piping though stdin/stdout. Argument is comma-separated list of file descriptor slots to duplicate the socket into, e.g. `0,1` for stdin and stdout.
          
          This is a low-level option that is less tested than other things. Expect non-user-friendly error messages if misused.

      --exec-dup2-keep-nonblocking
          When using --exec-dup2, do not set inherited file descriptors to blocking mode

      --exec-dup2-execve
          on Unix, When using `--exec-dup2`, do not return to Websocat, instead substitute Websocat process with the given command

      --dummy-hangup
          Make dummy nodes also immediately signal hangup

      --exit-on-hangup
          Exit the whole process if hangup is detected

      --exit-after-one-session
          Exit the whole process after serving one connection; alternative to to --oneshot

  -u, --unidirectional
          Transfer data only from left to right specifier

  -U, --unidirectional-reverse
          Transfer data only from right to left specifier

      --unidirectional-late-drop
          Do not shutdown inactive directions when using `-u` or `-U`

  -E, --exit-on-eof
          Stop transferring data when one of the transfer directions reached EOF

  -B, --buffer-size <BUFFER_SIZE>
          Override buffer size for main data transfer session. Note that some overlays and endpoints may have separate buffers with separately adjustable sizes.
          
          Message can span multiple over multiple fragments and exceed this buffer size

  -n, --no-close
          Do not send WebSocket close message when there is no more data to send there

      --ws-no-flush
          Do not flush after each WebSocket frame

      --ws-shutdown-socket-on-eof
          Shutdown write direction of the underlying socket backing a WebSocket on EOF

      --ws-ignore-invalid-masks
          Do not fail WebSocket connections if masked frame arrives instead of unmasked or vice versa

      --ws-dont-check-headers
          Ignore absence or invalid values of `Sec-Websocket-*` things and just continue connecting

      --ws-no-auto-buffer
          Do not automatically insert buffering layer after WebSocket if underlying connections does not support `writev`

      --ws-omit-headers
          Skip request or response headers for Websocket upgrade

  -H, --header <HEADER>
          Add this custom header to WebSocket upgrade request when connecting to a Websocket. Colon separates name and value

      --server-header <SERVER_HEADER>
          Add this custom header to WebSocket upgrade response when serving a Websocket connection. Colon separates name and value

      --protocol <PROTOCOL>
          Specify this Sec-WebSocket-Protocol: header when connecting to a WebSocket

      --server-protocol <SERVER_PROTOCOL>
          Use this `Sec-WebSocket-Protocol:` value when serving a Websocket, and reject incoming connections if the don't specify this protocol

      --server-protocol-lax
          Don't reject incoming connections that fail to specify proper `Sec-WebSocket-Protocol` header. The header would be omitted from the response in this case

      --server-protocol-choose-first
          If client specifies Sec-WebSocket-Protocol, choose the first mentioned protocol and use if for response's Sec-WebSocket-Protocol

      --unlink
          When listening UNIX sockets, attempt to delete the file first to avoid the failure to bind

      --chmod-owner
          When listening UNIX sockets, change socket filesystem permissions to only allow owner connections

      --chmod-group
          When listening UNIX sockets, change socket filesystem permissions to allow owner and group connections

      --chmod-everyone
          When listening UNIX sockets, change socket filesystem permissions to allow connections from everywhere

      --oneshot
          Serve only one connection

      --no-lints
          Do not display warnings about potential CLI misusage

      --no-fixups
          Do not automatically transform endpoints and overlays to their appropriate low-level form. Many things will fail in this mode

      --less-fixups
          Inhibit some optional transformations of specifier stacks, such as auto-inserting of a reuser

      --udp-max-send-datagram-size <UDP_MAX_SEND_DATAGRAM_SIZE>
          Maximum size of an outgoing UDP datagram. Incoming datagram size is likely limited by --buffer-size
          
          [default: 4096]

      --seqpacket-max-send-datagram-size <SEQPACKET_MAX_SEND_DATAGRAM_SIZE>
          Maximum size of an outgoing SEQPACKET datagram. Incoming datagram size is likely limited by --buffer-size
          
          [default: 1048576]

      --random-seed <RANDOM_SEED>
          Use specified random seed instead of initialising RNG from OS

      --registry-connect-bufsize <REGISTRY_CONNECT_BUFSIZE>
          Use specified max buffer size for
          
          [default: 1024]

      --mirror-bufsize <MIRROR_BUFSIZE>
          Use specified buffer size for mirror: endpoint
          
          [default: 1024]

      --lengthprefixed-little-endian
          Use little-endian framing headers instead of big-endian for `lengthprefixed:` overlay

      --lengthprefixed-skip-read-direction
          Only affect one direction of the `lengthprefixed:` overlay, bypass transformation for the other one

      --lengthprefixed-skip-write-direction
          Only affect one direction of the `lengthprefixed:` overlay, bypass transformation for the other one

      --lengthprefixed-nbytes <LENGTHPREFIXED_NBYTES>
          Use this number of length header bytes for `lengthprefixed:` overlay
          
          [default: 4]

      --lengthprefixed-continuations
          Do not reassemble messages from fragments, stream them as chunks. Highest bit of the prefix would be set if the message is non-final

      --lengthprefixed-max-message-size <LENGTHPREFIXED_MAX_MESSAGE_SIZE>
          Maximum size of `lengthprefixed:` message (that needs to be reassembled from fragments)
          
          Connections would fail when messages exceed this size.
          
          Ignored if `--lengthprefixed-continuations` is active, but `nbytes`-based limitation can still fail connections.
          
          [default: 1048576]

      --lengthprefixed-include-control
          Include inline control messages (i.e. WebSocket pings or close frames) as content in `lengthprefixed:`.
          
          A bit would be set to signify a control message and opcode will be prepended as the first byte.
          
          When both continuations and controls are enabled, control messages may appear between continued data message chunks. Control messages can themselves be subject to continuations.

      --lengthprefixed-tag-text
          Set a bit in the prefix of `lengthprefixed:` frames when the frame denotes a text WebSocket message instead of binary

      --inhibit-pongs <INHIBIT_PONGS>
          Stop automatic replying to WebSocket pings after sending specified number of pongs. May be zero to just disable replying to pongs

      --global-timeout-ms <GLOBAL_TIMEOUT_MS>
          Abort whatever Websocat is doing after specified number of milliseconds, regardless of whether something is connected or not

      --global-timeout-force-exit
          Force process exit when global timeout is reached

      --sleep-ms-before-start <SLEEP_MS_BEFORE_START>
          Wait for this number of milliseconds before starting endpoints. Mostly intended for testing Websocat, in combination with --compose mode

      --stdout-announce-listening-ports
          Print a line to stdout when a port you requested to be listened is ready to accept connections

      --exec-after-listen <EXEC_AFTER_LISTEN>
          Execute this command line after binding listening port
          
          Connections are not actually accepted until the command exits (exit code is ignored)

      --exec-after-listen-append-port
          Append TCP or UDP port number to command line specified in --exec-after-listen
          
          Makes listening port "0" practical.

      --accept-from-fd
          Show dedicated error message explaining how to migrate Websocat1's --accept-from-fd to the new scheme

      --reuser-tolerate-torn-msgs
          When using `reuse-raw:` (including automatically inserted), do not abort connections on unrecoverable broken messages, instead produce a trimmed message and continue

      --compose
          Interpret special command line arguments like `&`, `;`, '^', `(` and `)` as separators for composed scenarios mode. This argument must come first.
          
          This allows to execute multiple sub-scenarios in one Websocat invocation, sequentially (;), in parallel (&) or in parallel with early exit (^). You can also use parentheses to combine disparate operations.

      --write-file-no-overwrite
          For `writefile:` endpoint, do not overwrite existing files

      --write-file-auto-rename
          For `writefile:` endpoint, do not overwrite existing files, instead use other, neighbouring file names

      --origin <ORIGIN>
          Add Origin HTTP header to Websocket client request

      --ua <UA>
          Add User-Agent HTTP header to Websocket client request

      --random-fast
          For `random:` endpoint, use smaller and faster RNG instead of secure one

      --write-splitoff <WRITE_SPLITOFF>
          Specify the write counterpart for `write-splitoff:` overlay. Expects a specifier like `tcp:127.0.0.1:1234`, like a positional argument

      --write-splitoff-omit-shutdown
          Do not write-shutdown the read part of a `write-splitoff:` overlay

      --filter <FILTER>
          Pass traffic through this socket prior to transfer data from left to right specifiers.
          
          The filter itself can be any specifier (including with overlays), e.g. `--filter=lines:tcp:127.0.0.1:1234`

      --filter-reverse <FILTER_REVERSE>
          Pass traffic through this socket prior to transfer data from right to left specifiers

      --async-fd-force
          Force using a file descriptor for `async-fd:` even when it cannot be registered for events.
          
          In case of EWOULDBLOCK Websocat would wait for some short time in a loop.
          
          In some cases the whole Websocat process may be blocked.

      --defragment-max-size <DEFRAGMENT_MAX_SIZE>
          Maximum buffered message size for `defragment:` overlay
          
          [default: 1048576]

      --tee <TEE>
          Copy output datagrams also to this specifier; also merge in incoming datagrams from this specifier
          
          May insert a `tee:` overlay automatically if not specified.

      --tee-propagate-failures
          Cause `tee:` overlay to fail datagram read or write if any (instead of all) nodes failed the operation

      --tee-propagate-eof
          Cause `tee:` overlay's reading direction to propagate EOF when any of the nodes signaled EOF instead of all of them

      --tee-tolerate-torn-msgs
          When using `tee:`, do not abort reading side of the connections on unrecoverable broken messages, instead produce a trimmed message and continue

      --tee-use-hangups
          Terminate `tee:` specifier when any of the tee nodes signal hangup

      --tee-use-first-hangup
          Terminate `tee:` specifier when main tee node (the one after `tee:` instead of `--tee`) signals hangup

      --enable-sslkeylog
          When built with rustls, write encryption information to a files based on `SSLKEYLOGFILE` environment variable to assist decrypting traffic for analysis

      --bind-before-connect <BIND_BEFORE_CONNECT>
          Bind outgoing TCP socket to this address and/or port prior to connecting to the destination

      --reuseaddr <REUSEADDR>
          Explicitly force SO_REUSEADDR on or off on the socket
          
          [possible values: true, false]

      --reuseport
          Set SO_REUSEPORT (fails if unsupported by platform)

      --socket-bind-to-device <SOCKET_BIND_TO_DEVICE>
          Set SO_BINDTODEVICE (fails if unsupported by platform)

      --socket-listen-backlog <SOCKET_LISTEN_BACKLOG>
          Use this backlog argument for `listen(2)` syscall. Maximum number of queued connections pending for accept(2)

      --socket-transparent
          Set IP_TRANSPARENT for the socket

      --socket-freebind
          Set IP_FREEBIND for the socket

      --socket-tclass-v6 <SOCKET_TCLASS_V6>
          Set IPV6_TCLASS for the socket, in case when it is IPv6

      --socket-tos-v4 <SOCKET_TOS_V4>
          Set IP_TOS for the socket, in case when it is IPv4

      --socket-ttl <SOCKET_TTL>
          Set IP_TTL for a IPv4 socket or IPV6_UNICAST_HOPS for an IPv6 socket

      --socket-linger-s <SOCKET_LINGER_S>
          Set SO_LINGER for the socket

      --socket-out-of-band-inline
          Set SO_OOBINLINE for the socket

      --socket-only-v6 <SOCKET_ONLY_V6>
          Set IPV6_V6ONLY for the socket in case when it is IPv6
          
          [possible values: true, false]

      --socket-nodelay <SOCKET_NODELAY>
          Set TCP_NODELAY (no Nagle) for the socket
          
          [possible values: true, false]

      --socket-tcp-congestion <SOCKET_TCP_CONGESTION>
          Set TCP_CONGESTION for the socket

      --socket-cpu-affinity <SOCKET_CPU_AFFINITY>
          Set SO_INCOMING_CPU for the socket

      --socket-user-timeout-s <SOCKET_USER_TIMEOUT_S>
          Set TCP_USER_TIMEOUT for the socket

      --socket-priority <SOCKET_PRIORITY>
          Set SO_PRIORITY for the socket

      --socket-recv-buffer-size <SOCKET_RECV_BUFFER_SIZE>
          Set SO_RCVBUF for the socket

      --socket-send-buffer-size <SOCKET_SEND_BUFFER_SIZE>
          Set SO_SNDBUF for the socket

      --socket-mss <SOCKET_MSS>
          Set TCP_MAXSEG for the socket

      --socket-mark <SOCKET_MARK>
          Set SO_MARK for the socket

      --socket-thin-linear-timeouts <SOCKET_THIN_LINEAR_TIMEOUTS>
          Set TCP_THIN_LINEAR_TIMEOUTS for the socket
          
          [possible values: true, false]

      --socket-notsent-lowat <SOCKET_NOTSENT_LOWAT>
          Set TCP_NOTSENT_LOWAT for the socket

      --socket-keepalive <SOCKET_KEEPALIVE>
          Set SO_KEEPALIVE for the socket
          
          [possible values: true, false]

      --socket-keepalive-retries <SOCKET_KEEPALIVE_RETRIES>
          Set TCP_KEEPCNT for the socket

      --socket-keepalive-interval-s <SOCKET_KEEPALIVE_INTERVAL_S>
          Set TCP_KEEPINTVL for the socket

      --socket-keepalive-idletime-s <SOCKET_KEEPALIVE_IDLETIME_S>
          Set TCP_KEEPALIVE for the socket

      --socket-broadcast
          Set SO_BROADCAST for the UDP socket

      --socket-multicast <SOCKET_MULTICAST>
          Use IP_ADD_MEMBERSHIP or IPV6_ADD_MEMBERSHIP for the UDP socket

      --socket-multicast-interface-addr <SOCKET_MULTICAST_INTERFACE_ADDR>
          Use this interface address instead of 0.0.0.0 when joining multicast

      --socket-multicast-interface-index <SOCKET_MULTICAST_INTERFACE_INDEX>
          Use this interface index instead of 0 when joining multicast

      --socket-multicast-specific-source <SOCKET_MULTICAST_SPECIFIC_SOURCE>
          Use IP_ADD_SOURCE_MEMBERSHIP instead of IP_ADD_MEMBERSHIP

      --socket-multicast-all <SOCKET_MULTICAST_ALL>
          Set IP_MULTICAST_ALL or IPV6_MULTICAST_ALL for the UDP socket
          
          [possible values: true, false]

      --socket-multicast-loop <SOCKET_MULTICAST_LOOP>
          Set IP_MULTICAST_LOOP or IPV6_MULTICAST_LOOP for the UDP socket
          
          [possible values: true, false]

      --socket-multicast-ttl <SOCKET_MULTICAST_TTL>
          Set IP_MULTICAST_TTL or IPV6_MULTICAST_HOPS for the UDP socket

      --exclude-ws-from-sockopts
          Do not apply `socket_*`, `reuseaddr`, `reuseport` and `bind_before_connect` to specifier stacks that include WebSocket framer
          
          You can attain the reverse effect by playing with --compose mode, registry-send: and registry-stream-listen: , as socket options (like most other options) only affect single sub-session of the compose mode.

      --tcp-race-interval-ms <TCP_RACE_INTERVAL_MS>
          Delay between initiating subsequent connections when connecting to a TCP using multiple address variants
          
          [default: 20]

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

Short list of endpoint prefixes:
  abstract:
  abstract-listen:
  seqpacket-abstract:
  seqpacket-abstract-listen:
  appendfile:
  async-fd:
  cmd:
  empty:
  devnull:
  exec:
  literal:
  literal-base64:
  mirror:
  mock_stream_socket:
  random:
  readfile:
  registry-datagram-connect:
  registry-datagram-listen:
  registry-send:
  registry-stream-connect:
  registry-stream-listen:
  seqpacket:
  seqpacket-listen:
  seqpacket-listen-fd:
  seqpacket-listen-fdname:
  stdio:
  tcp:
  tcp-listen:
  tcp-listen-fd:
  tcp-listen-fdname:
  udp-bind:
  udp:
  udp-fd:
  udp-fdname:
  udp-server:
  udp-server-fd:
  udp-server-fdname:
  unix:
  unix-listen:
  unix-listen-fd:
  unix-listen-fdname:
  writefile:
  ws-listen:
  ws://
  wss://
  zero:

Short list of overlay prefixes:
  defragment:
  lengthprefixed:
  lines:
  log:
  read_chunk_limiter:
  reuse-raw:
  chunks:
  tee:
  tls:
  write_buffer:
  write_chunk_limiter:
  write-splitoff:
  ws-accept:
  ws-connect:
  ws-lowlevel-client:
  ws-lowlevel-server:
  ws-upgrade:
  ws-request:

Examples:

  websocat ws://127.0.0.1:1234
    Simple WebSocket client

  websocat -s 1234
    Simple WebSocket server

  websocat -b tcp-l:127.0.0.1:1234 wss://ws.vi-server.org/mirror
    TCP-to-WebSocket converter

  websocat -b ws-l:127.0.0.1:8080 udp:127.0.0.1:1234
    WebSocket-to-UDP converter

Use https://websocat.net/websocat4/ (or 'doc' directory in the source code) for reference of all Websocat functions

Reference

Sub-chapters here include content generated from special //@ documentation comments found in Websocat source code.

Endpoints

This part describes what you can put as a positional argument for Websocat.

Typically things have <prefix>:[<value>] format. For example, in tcp:127.0.0.1:1234 endpoint tcp: is prefix and 127.0.0.1:1234 is value.

Some endpoints deviate from this pattern, for example, - for stdin/stdout and ws:// / wss:// URLs to activate the client.

Endpoints are final, leaf nodes of Specifier Stacks. Note that colon-prefixed things like autoreconnect: or broadcast: before endpoints are not another endpoints, but Overlays.

They are described in a neghbouring chapter.

List of endpoints:

AbstractConnect

Connect to the specified abstract-namespaced UNIX socket (Linux)

Prefixes:

  • abstract:
  • abstract-connect:
  • connect-abstract:
  • abstract-c:
  • c-abstract:
  • abs:

AbstractListen

Listen UNIX socket on specified abstract path (Linux)

Prefixes:

  • abstract-listen:
  • listen-abstract:
  • abstract-l:
  • l-abstract:
  • l-abs:
  • abs-l:

AbstractSeqpacketConnect

Connect to specified UNIX SOCK_SEQPACKET socket by abstract (Linux) name

Prefixes:

  • seqpacket-abstract:
  • seqpacket-abstract-connect:
  • seqpacket-abstract-c:
  • abstract-seqpacket:
  • abstract-seqpacket-connect:
  • abstract-seqpacket-c:
  • abs-seqp:
  • seqp-abs:

AbstractSeqpacketListen

Listen specified UNIX SOCK_SEQPACKET socket by abstract (Linux) name

Prefixes:

  • seqpacket-abstract-listen:
  • seqpacket-abstract-l:
  • abstract-seqpacket-listen:
  • abstract-seqpacket-l:
  • abs-seqp-l:
  • seqp-abs-l:
  • l-abs-seqp:
  • l-seqp-abs:

AppendFile

Append to specified file.

Prefixes:

  • appendfile:

AsyncFd

Use specified inherited file descriptor for reading and writing, assuming it supports read(2) and writev(2) and can be put in epoll (or analogue).

Trying to specify unexisting FD, especially low-numbered (e.g from 3 to 20) may lead to undefined behaviour.

Gives a StreamSocket. If you want a packet-oriented socket, use defragment:chunks:async-fd:X overlay chain.

Prefixes:

  • async-fd:
  • open-fd:

Cmd

Execute given command line and use its stdin/stdout as a socket.

Prefixes:

  • cmd:
  • sh-c:

DummyDatagrams

Datagram socket that ignores all incoming data and signals EOF immediately

Prefixes:

  • empty:
  • null:
  • dummy-datagrams:
  • dummy:

DummyStream

Byte stream socket that ignores all incoming data and immediately EOF-s read attempts

Prefixes:

  • devnull:
  • dummy-stream:

Exec

Execute given program as a subprocess and use its stdin/stdout as a socket. Specify command line arguments using --exec-args command line option.

Prefixes:

  • exec:

Literal

Byte stream socket that produces specified content and ignores incoming data

Prefixes:

  • literal:

LiteralBase64

Byte stream socket that produces specified content (base64-encoded) and ignores incoming data

Prefixes:

  • literal-base64:

Mirror

Read data that is written to this endpoint.

Prefixes:

  • mirror:

MockStreamSocket

Byte stream socket for tests that can produce and consume (assert) data according to special scenario supplied as an argument

Prefixes:

  • mock_stream_socket:
  • mock-stream-socket:
  • mss:

Random

Generate random bytes

Prefixes:

  • random:

ReadFile

Read specified file. Ignores writes.

Prefixes:

  • readfile:

RegistryDatagramConnect

Connect to a virtual intra-Websocat address using a datagram socket

This is different from registry-send: that it creates a temporary buffer and can use overlays. The buffer is like two mirror: endpoints.

Prefixes:

  • registry-datagram-connect:
  • regdg-c:

RegistryDatagramListen

Listen for virtual intra-Websocat datagram connections at specified address.

Connections can be made with registry-datagrams-connect: or registry-send: endpoints.

Prefixes:

  • registry-datagram-listen:
  • regdg-l:

RegistrySend

Send the {socket this endpoint is paired with} to a virtual intra-Websocat address

Prefixes:

  • registry-send:
  • regsend:

RegistryStreamConnect

Connect to a virtual intra-Websocat address using a stream socket

This is different from registry-send: that it creates a temporary buffer and can use overlays. The buffer is like two mirror: endpoints.

Prefixes:

  • registry-stream-connect:
  • regstr-c:

RegistryStreamListen

Listen for virtual intra-Websocat stream connections at specified address.

Connections can be made with registry-stream-connect: and registry-send: endpoints.

Prefixes:

  • registry-stream-listen:
  • regstr-l:

SeqpacketConnect

Connect to specified UNIX SOCK_SEQPACKET socket by path

Unlike Websocat1, @-prefixed addresses do not get converted to Linux abstract namespace

Prefixes:

  • seqpacket:
  • seqpacket-connect:
  • connect-seqpacket:
  • seqpacket-c:
  • c-seqpacket:
  • seqp:

SeqpacketListen

Listen specified UNIX SOCK_SEQPACKET socket

Unlike Websocat1, @-prefixed addresses do not get converted to Linux abstract namespace

Prefixes:

  • seqpacket-listen:
  • listen-seqpacket:
  • seqpacket-l:
  • l-seqpacket:
  • l-seqp:
  • seqp-l:

SeqpacketListenFd

Listen for incoming TCP connections on one TCP socket that is already ready for accepting incoming connections, with specified file descriptor (inherited from parent process)

Prefixes:

  • seqpacket-listen-fd:
  • listen-seqpacket-fd:
  • seqpacket-l-fd:
  • l-seqpacket-fd:
  • l-seqp-fd:
  • seqp-l-fd:

SeqpacketListenFdNamed

Listen for incoming TCP connections on one TCP socket that is already ready for accepting incoming connections, with specified file descriptor (inherited from parent process) based on LISTEN_FDNAMES environment variable (i.e. from SystemD)

Prefixes:

  • seqpacket-listen-fdname:
  • listen-seqpacket-fdname:
  • seqpacket-l-fdname:
  • l-seqpacket-fdname:
  • l-seqp-fdname:
  • seqp-l-fdname:

SimpleReuserEndpoint

Implementation detail of reuse-raw: overlay

This endpoint cannot be directly specified as a prefix to a positional CLI argument, there may be some other way to access it.

Stdio

Console, terminal: read bytes from stdin, write bytes to stdout.

Uses additional thread, which may cause lower latency and throughput.

Prefixes:

  • stdio:

TcpConnectByEarlyHostname

Connect to a TCP socket by hostname. Hostname resolution happens once, on scenario start. If multiple address are resolved, they are tried simultaneously, first connected one wins.

See prefixes for TcpConnectByIp.

TcpConnectByIp

Connected to a TCP socket using one explicitly specified IPv4 or IPv6 socket address.

Prefixes:

  • tcp:
  • tcp-connect:
  • connect-tcp:
  • tcp-c:
  • c-tcp:

TcpConnectByLateHostname

Connect to a TCP socket by hostname. Hostname resolution is repeated every time a connection is initiated. If multiple address are resolved, they are tried simultaneously, first connected one wins.

See prefixes for TcpConnectByIp

TcpListen

Listen for incoming TCP connections on one TCP socket, bound to the specified IPv4 or IPv6 address.

Prefixes:

  • tcp-listen:
  • listen-tcp:
  • tcp-l:
  • l-tcp:

TcpListenFd

Listen for incoming TCP connections on one TCP socket that is already ready for accepting incoming connections, with specified file descriptor (inherited from parent process)

Prefixes:

  • tcp-listen-fd:
  • listen-tcp-fd:
  • tcp-l-fd:
  • l-tcp-fd:

TcpListenFdNamed

Listen for incoming TCP connections on one TCP socket that is already ready for accepting incoming connections, with specified file descriptor (inherited from parent process) based on LISTEN_FDNAMES environment variable (i.e. from SystemD)

Prefixes:

  • tcp-listen-fdname:
  • listen-tcp-fdname:
  • tcp-l-fdname:
  • l-tcp-fdname:

Tee

Implementation detail of tee: overlay

This endpoint cannot be directly specified as a prefix to a positional CLI argument, there may be some other way to access it.

UdpBind

Bind UDP socket to this address. Command line options greatly affect behaviour of this endpoint. It can be turned into a flexible UdpConnect analogue.

Prefixes:

  • udp-bind:
  • bind-udp:
  • udp-listen:
  • listen-udp:
  • udp-l:
  • l-udp:

UdpConnect

Connect to this UDP socket. Not affected by `--udp-bind-*`` CLI options.

Prefixes:

  • udp:
  • udp-connect:
  • connect-udp:
  • udp-c:
  • c-udp:

UdpFd

Use inherited pre-bound UDP socket from specified file descriptor.

Prefixes:

  • udp-fd:
  • udp-bind-fd:

UdpFdNamed

Use inherited pre-bound UDP socket from specified file descriptor (using LISTEN_FDNAMES)

Prefixes:

  • udp-fdname:
  • udp-bind-fdname:

UdpServer

Bind UDP socket and spawn a separate task for each client. Connections get closed when there are too many active clients or by a timeout.

Prefixes:

  • udp-server:

UdpServerFd

Use inherited pre-bound UDP socket from specified file descriptor, spawning a task for each client

Prefixes:

  • udp-server-fd:

UdpServerFdNamed

Use inherited pre-bound UDP socket from specified file descriptor (using LISTEN_FDNAMES), spawning a task for each client

Prefixes:

  • udp-server-fdname:

UnixConnect

Connect to the specified UNIX socket path using stream socket

Prefixes:

  • unix:
  • unix-connect:
  • connect-unix:
  • unix-c:
  • c-unix:

UnixListen

Listen specified UNIX socket path for SOCK_STREAM connections

Prefixes:

  • unix-listen:
  • listen-unix:
  • unix-l:
  • l-unix:

UnixListenFd

Listen for incoming AF_UNIX SOCK_STREAM connections on one socket that is already ready for accepting incoming connections, with specified file descriptor (inherited from parent process)

Prefixes:

  • unix-listen-fd:
  • listen-unix-fd:
  • unix-l-fd:
  • l-unix-fd:

UnixListenFdNamed

Listen for incoming AF_UNIX SOCK_STREAM connections on one socket that is already ready for accepting incoming connections, with specified file descriptor (inherited from parent process) based on LISTEN_FDNAMES environment variable (i.e. from SystemD)

Prefixes:

  • unix-listen-fdname:
  • listen-unix-fdname:
  • unix-l-fdname:
  • l-unix-fdname:

WriteFile

Write specified file.

Prefixes:

  • writefile:

WriteSplitoff

Implementation detail of write-splitoff: overlay

This endpoint cannot be directly specified as a prefix to a positional CLI argument, there may be some other way to access it.

WsListen

Listen for incoming WebSocket connections at specified TCP socket address.

Prefixes:

  • ws-listen:
  • ws-l:
  • l-ws:
  • listen-ws:

WsUrl

Connect to specified WebSocket plain (insecure) URL

Prefixes:

  • ws://

WssUrl

Connect to specified WebSocket TLS URL

Prefixes:

  • wss://

Zero

Generate zero bytes

Prefixes:

  • zero:

Overlays

Overlays modify some aspect of underlying connection, allowing to attach processing steps to the connection. You can specify multiple overlays by prepending its prefix (that typically ends in a colon) to the specifier.

For example, if tcp:127.0.0.1:443 is a plain TCP connection, tls:tcp:127.0.0.1:443 is a TLS client that uses a TCP connection under the hood and ws-c:tls:tcp:127.0.0.1:443 is a WebSocket client that uses a TLS client that uses a TCP connection.

Unlike Endpoints, Overlays do not have values (only downstream specifiers). Configuration for overlays goes to CLI options.

There are two socket types: Bytestream and Datagrams. Overlays typically handle only one of the types, a mismatch can lead to a failure in resulting Scenario.

Here is list of all overlays:

Defragment

Defragment potential partial messages into complete messages.

Prefixes:

  • defragment:

LengthPrefixedChunks

Convert downstream stream-oriented socket to packet-oriented socket by prefixing each message with its length (and maybe other flags, depending on options).

Prefixes:

  • lengthprefixed:

LineChunks

Convert downstream stream-oriented socket to packet-oriented socket by using newline byte as a packet separator. Written data get modified to ensure that one line = one message.

May be automatically inserted in text (-t) mode.

Prefixes:

  • lines:

Log

Print encountered data to stderr for debugging

Prefixes:

  • log:

ReadChunkLimiter

Limit this stream's read buffer size to --read-buffer-limit By splitting reads to many (e.g. single byte) chunks, we can test and debug trickier code paths in various overlays

Prefixes:

  • read_chunk_limiter:

SimpleReuser

Share underlying datagram connection between multiple outer users.

All users can write messages to the socket, messages would be interleaved (though each individual message should be atomic). Messages coming from inner socket will be delivered to some one arbitrary connected user. If that users disconnect, they will route to some other user. A message can be lost when user disconnects. User disconnections while writing a message may abort the whole reuser (or result in a broken, trimmed message, depending on settings).

Prefixes:

  • reuse-raw:
  • raw-reuse:

StreamChunks

Converts downstream stream-oriented socket to packet-oriented socket by chunking the stream arbitrarily (i.e. as syscalls happened to deliver the data)

May be automatically inserted in binary (-b) mode.

Prefixes:

  • chunks:

Tee

Use both this underlying datagram specifier and also additional ones specified by --tee command line option.

Each write is copied to all of the nodes, each node can also produce a message.

Prefixes:

  • tee:

TlsClient

Establishes client-side TLS connection using specified stream-oriented downstream connection

Prefixes:

  • tls:
  • ssl-connect:
  • ssl-c:
  • ssl:
  • tls-connect:
  • tls-c:
  • c-ssl:
  • connect-ssl:
  • c-tls:
  • connect-tls:

WriteBuffer

Insert write buffering layer that combines multiple write calls to one bigger

Prefixes:

  • write_buffer:

WriteChunkLimiter

Limit this stream's write buffer size to --write-buffer-limit By enforcing short writes, we can test and debug trickier code paths in various overlays

Prefixes:

  • write_chunk_limiter:

WriteSplitoff

Only read from inner specifier, route writes to other, CLI-specified Socket

Prefixes:

  • write-splitoff:
  • write-divert:
  • wrdvrt:

WsAccept

Expects a HTTP/1 WebSocket upgrade request from downstream stream socket. If valid, replies with Upgrade HTTP reply. After than connects (i.e. exchanges bytes) downstream to upstream.

Does not provide WebSocket framing.

Prefixes:

  • ws-accept:

WsClient

Combined WebSocket upgrader and framer, but without TCP or TLS things URI is taken from --ws-c-uri CLI argument If it is not specified, it defaults to /, with a missing host: header

Prefixes:

  • ws-connect:
  • connect-ws:
  • ws-c:
  • c-ws:

WsFramer

Converts downstream stream to upstream packets using WebSocket framing.

Automatically handles WebSocket pings and CloseFrames, but does not fully terminate the connection on CloseFrame, only signaling EOF instead.

Client or server mode is chosen depending on prefix you use.

Prefixes:

  • ws-lowlevel-client:
  • ws-ll-client:
  • ws-ll-c:
  • ws-lowlevel-server:
  • ws-ll-server:
  • ws-ll-s:

WsServer

Combined WebSocket acceptor and framer.

Prefixes:

  • ws-upgrade:
  • upgrade-ws:
  • ws-u:
  • u-ws:

WsUpgrade

Send HTTP/1 WebSocket upgrade to specified stream-oriented connection and accept and parse a reply, then connects (i.e. exchanges bytes) the downstream connection to upstream.

Does not provide WebSocket framing.

Prefixes:

  • ws-request:
  • ws-r:

Scenario functions

Prior to doing any network things, Websocat prepares a Scenario (Websocat Rhai Script) based on you command line options. Scenarios are less stable than usual Websocat API, but allow fine tuning Websocat behaviour. You can view scenarios using --dump-spec option and execute them the with -x option.

In this chapter, each entry corresponds to one native Rhai function. If heading begins with Something::, it means this is a method to be called on objects of the type Something.

Often functions take a Rhai object map (#{...}) and Rhai closures || { ... } as parameters. Map elements and closure parameters are also documented.

Note that types here are rendered as Rush types, but it should be straightforward to deduce Rhai things to use using common sense.

The following functions and methods are used in scenarios:

Child::kill

Terminate a child process. Child instance cannot be used after this.

Returns Hangup

Child::socket

Convert the child process handle to a Stream Socket of its stdin and stdout (but not stderr). In case of non-piped (2) FDs, the resulting socket would be incomplete.

Returns StreamSocket

Child::take_stderr

Take stderr handle as a Stream Reader (i.e. half-socket). In case of non-piped (2) FDs, the handle would be null

Returns StreamRead

Child::wait

Obtain a Hangup handle that resolves when child process terminates. Child instance cannot be used after this.

Returns Hangup

Command::arg

Add one command line argument to the array

Parameters:

  • arg (String)

Returns ()

Command::arg0

Override process's name / zeroth command line argument on Unix.

Parameters:

  • arg0 (String)

Returns ()

Command::arg0_osstr

Override process's name / zeroth command line argument on Unix.

Parameters:

  • arg0 (OsString)

Returns ()

Command::arg_osstr

Add one possibly non-UTF8 command line argument to the array

Parameters:

  • arg (OsString)

Returns ()

Command::chdir

Change current directory for the subprocess.

Parameters:

  • dir (String)

Returns ()

Command::chdir_osstr

Change current directory for the subprocess.

Parameters:

  • dir (OsString)

Returns ()

Command::configure_fds

Configure what to do with subprocess's stdin, stdout and stderr

Each numeric argument accepts the following values:

  • 0 meaning the fd will be /dev/null-ed.
  • 1 meaning leave it connected to Websocat's fds.
  • 2 meaning we can capture process's input or output.

Parameters:

  • stdin (i64)
  • stdout (i64)
  • stderr (i64)

Returns ()

Command::dup2

dup2 specified file descriptor over specified file descriptor numbers in the executed process

Parameters:

  • source_fd (i64)
  • destination_fds (rhai::Dynamic)
  • set_to_blocking (bool)

Returns ()

Command::env

Add or set environment variable for the subprocess

Parameters:

  • key (String)
  • value (String)

Returns ()

Command::env_clear

Clear all environment variables for the subprocess.

Returns ()

Command::env_osstr

Add or set environment variable for the subprocess (possibly non-UTF8)

Parameters:

  • key (OsString)
  • value (OsString)

Returns ()

Command::env_remove

Add or set environment variable for the subprocess.

Parameters:

  • key (String)

Returns ()

Command::env_remove_osstr

Add or set environment variable for the subprocess.

Parameters:

  • key (OsString)

Returns ()

Command::execute

Spawn the prepared subprocess. What happens next depends on used Child:: methods.

Returns Child

Command::execute_for_output

Execute the prepared subprocess and wait for its exit, storing output of stdout and stderr in memory. Status code the callback receives follows similar rules as in subprocess_execute_for_status. Second and third arguments of the callback are stdout and stderr respectively.

Parameters:

  • continuation (Fn(i64, Vec<u8>, Vec<u8>) -> Task) - Rhai function that will be called to continue processing

Returns Task

Command::execute_for_status

Execute the prepared subprocess and wait for its exit code Callback receives exit code or -1 meaning that starting failed or -2 meaning the process exited because of signal

Parameters:

  • continuation (Fn(i64) -> Task) - Rhai function that will be called to continue processing

Returns Task

Command::execve

Substitute Websocat process with the prepared command, abandoning other connections if they exist.

Returns Child

Command::gid

Set subprocess's uid on Unix.

Parameters:

  • gid (i64)

Returns ()

Command::raw_windows_arg

Add literal, unescaped text to Windows's command line

Parameters:

  • arg (OsString)

Returns ()

Command::uid

Set subprocess's uid on Unix.

Parameters:

  • uid (i64)

Returns ()

Command::windows_creation_flags

Set Windows's process creation flags.

Parameters:

  • flags (i64)

Returns ()

DatagramSocketSlot::send

Put DatagramSocket into its slot, e.g. to initialize a reuser.

Acts immediately and returns a dummy task just as a convenience (to make Rhai scripts typecheck).

Parameters:

  • socket (DatagramSocket)

Returns Task

SimpleReuser::connect

Obtain a shared DatagramSocket pointing to the socket that was specified as inner into simple_reuser function.

Returns DatagramSocket

SimpleReuserListener::maybe_init_then_connect

Initialize a persistent, shared DatagramSocket connection available for multiple clients (or just obtain a handle to it)

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • initializer (Fn(DatagramSocketSlot) -> Task) - Callback that is called on first call of this function and skipped on the rest (unless recover is set and needed) The callback is supposed to send a DatagramSocket to the slot.
  • continuation (Fn(DatagramSocket) -> Task) - Callback that is called every time

Returns Task

Options:

  • connect_again (bool) - Do not cache failed connection attempts, retry initialisation if a new client arrive. Note that successful, but closed connections are not considered failed and that regard and will stay cached. (use autoreconnect to handle that case)
  • disconnect_on_broken_message (bool) - Drop underlying connection if some client leaves in the middle of writing a message, leaving us with unrecoverably broken message.

Slot::send

Fulfill a Slot with a value, e.g to complete one of initialisers for init_in_parallel.

Acts immediately and returns a dummy task just as a convenience (to make Rhai scripts typecheck).

Parameters:

  • x (Dynamic)

Returns Task

TriggerableEvent::take_hangup

Take the waitable part (Hangup) from an object created by triggerable_event_create

Returns Hangup

TriggerableEvent::take_trigger

Take the activatable part from an object created by triggerable_event_create

Returns TriggerableEventTrigger

TriggerableEventTrigger::fire

Trigger the activatable part from an object created by triggerable_event_create. This should cause a hangup even on the associated Hangup object.

Returns ()

async_fd

Use specified file descriptor for input/output, returning a StreamSocket.

If you want it as a DatagramSocket, just wrap it in a chunks wrapper.

May cause unsound behaviour if misused.

Parameters:

  • fd (i64)
  • force (bool)

Returns StreamSocket

b64str

Decode base64 string to another string

Parameters:

  • x (&str)

Returns String

bytemirror_socket

Create a bytestream socket that reads everything written to it.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function

Returns StreamSocket

Options:

  • max_buf_size (usize) - Maximum size of buffer for data in flight

combine_read_and_write_bytestream

Take reading part s1 and write part of s2 and make a new socket that routes reads to s1 and writes to s2.

Close notifications (hangup tokens) are combined from s1 and s2.

Write part of s1 and read part of s2 remain in the original sockets which become incomplete (but not null).

Parameters:

  • s1 (StreamSocket)
  • s2 (StreamSocket)

Returns StreamSocket

combine_read_and_write_datagram

Take reading part s1 and write part of s2 and make a new socket that routes reads to s1 and writes to s2.

Close notifications (hangup tokens) are combined from s1 and s2.

Write part of s1 and read part of s2 remain in the original sockets which become incomplete (but not null).

Parameters:

  • s1 (DatagramSocket)
  • s2 (DatagramSocket)

Returns DatagramSocket

connect_registry_datagrams

Connect to an intra-Websocat stream socket listening on specified virtual address.

Uses intermediate buffer mechanism like in the mirror: endpoint.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • continuation (Fn(DatagramSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • addr (String)

connect_registry_stream

Connect to an intra-Websocat stream socket listening on specified virtual address.

Uses intermediate buffer mechanism like in the mirror: endpoint.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • addr (String)
  • max_buf_size (usize) - Maximum size of buffer for data in flight

connect_seqpacket

Connect to a SOCK_SEQPACKET UNIX stream socket

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • path (OsString)
  • continuation (Fn(DatagramSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • abstract (bool) - On Linux, connect to an abstract-namespaced socket instead of file-based
  • text (bool) - Mark received datagrams as text
  • max_send_datagram_size (usize) - Defragmenter buffer limit

connect_tcp

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • addr (SocketAddr)
  • bind (Option<SocketAddr>) - Bind TCP socket to this address and/or port before issuing connect
  • reuseaddr (Option<bool>) - Set SO_REUSEADDR for the socket
  • reuseport (bool) - Set SO_REUSEPORT for the socket
  • bind_device (Option<String>) - Set SO_BINDTODEVICE for the socket
  • transparent (bool) - Set IP_TRANSPARENT for the socket
  • freebind (bool) - Set IP_FREEBIND for the socket
  • only_v6 (Option<bool>) - Set IPV6_V6ONLY for the socket in case when it is IPv6
  • tclass_v6 (Option<u32>) - Set IPV6_TCLASS for the socket, in case when it is IPv6.
  • tos_v4 (Option<u32>) - Set IP_TOS for the socket, in case when it is IPv4.
  • ttl (Option<u32>) - Set IP_TTL for a IPv4 socket or IPV6_UNICAST_HOPS for an IPv6 socket
  • linger_s (Option<u32>) - Set SO_LINGER for the socket
  • out_of_band_inline (bool) - Set SO_OOBINLINE for the socket
  • nodelay (Option<bool>) - Set TCP_NODELAY (no Nagle) for the socket
  • tcp_congestion (Option<String>) - Set TCP_CONGESTION for the socket
  • cpu_affinity (Option<usize>) - Set SO_INCOMING_CPU for the socket
  • user_timeout_s (Option<u32>) - Set TCP_USER_TIMEOUT for the socket
  • priority (Option<u32>) - Set SO_PRIORITY for the socket
  • recv_buffer_size (Option<usize>) - Set SO_RCVBUF for the socket
  • send_buffer_size (Option<usize>) - Set SO_SNDBUF for the socket
  • mss (Option<u32>) - Set TCP_MAXSEG for the socket
  • mark (Option<u32>) - Set SO_MARK for the socket
  • thin_linear_timeouts (Option<bool>) - Set TCP_THIN_LINEAR_TIMEOUTS for the socket
  • notsent_lowat (Option<u32>) - Set TCP_NOTSENT_LOWAT for the socket
  • keepalive (Option<bool>) - Set SO_KEEPALIVE for the socket
  • keepalive_retries (Option<u32>) - Set TCP_KEEPCNT for the socket
  • keepalive_interval_s (Option<u32>) - Set TCP_KEEPINTVL for the socket
  • keepalive_idletime_s (Option<u32>) - Set TCP_KEEPALIVE for the socket

connect_tcp_race

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • addrs (Vec<SocketAddr>)
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • race_interval_ms (u32) - Interval between connection attempts
  • bind (Option<SocketAddr>) - Bind TCP socket to this address and/or port before issuing connect
  • reuseaddr (Option<bool>) - Set SO_REUSEADDR for the listening socket
  • reuseport (bool) - Set SO_REUSEPORT for the listening socket
  • bind_device (Option<String>) - Set SO_BINDTODEVICE for the listening socket
  • transparent (bool) - Set IP_TRANSPARENT for the listening socket
  • freebind (bool) - Set IP_FREEBIND for the listening socket
  • only_v6 (Option<bool>) - Set IPV6_V6ONLY for the socket in case when it is IPv6
  • tclass_v6 (Option<u32>) - Set IPV6_TCLASS for the socket, in case when it is IPv6.
  • tos_v4 (Option<u32>) - Set IP_TOS for the socket, in case when it is IPv4.
  • ttl (Option<u32>) - Set IP_TTL for a IPv4 socket or IPV6_UNICAST_HOPS for an IPv6 socket
  • linger_s (Option<u32>) - Set SO_LINGER for the socket
  • out_of_band_inline (bool) - Set SO_OOBINLINE for the socket
  • nodelay (Option<bool>) - Set TCP_NODELAY (no Nagle) for the socket
  • tcp_congestion (Option<String>) - Set TCP_CONGESTION for the socket
  • cpu_affinity (Option<usize>) - Set SO_INCOMING_CPU for the socket
  • user_timeout_s (Option<u32>) - Set TCP_USER_TIMEOUT for the socket
  • priority (Option<u32>) - Set SO_PRIORITY for the socket
  • recv_buffer_size (Option<usize>) - Set SO_RCVBUF for the socket
  • send_buffer_size (Option<usize>) - Set SO_SNDBUF for the socket
  • mss (Option<u32>) - Set TCP_MAXSEG for the socket
  • mark (Option<u32>) - Set SO_MARK for the socket
  • thin_linear_timeouts (Option<bool>) - Set TCP_THIN_LINEAR_TIMEOUTS for the socket
  • notsent_lowat (Option<u32>) - Set TCP_NOTSENT_LOWAT for the socket
  • keepalive (Option<bool>) - Set SO_KEEPALIVE for the socket
  • keepalive_retries (Option<u32>) - Set TCP_KEEPCNT for the socket
  • keepalive_interval_s (Option<u32>) - Set TCP_KEEPINTVL for the socket
  • keepalive_idletime_s (Option<u32>) - Set TCP_KEEPALIVE for the socket

connect_unix

Connect to a UNIX stream socket of some kind

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • path (OsString)
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • abstract (bool) - On Linux, connect to an abstract-namespaced socket instead of file-based

copy_bytes

Forward unframed bytes from source to sink

Parameters:

  • bufsize (i64) - buffer size to use for copying
  • from (StreamRead) - stream source to read from
  • to (StreamWrite) - stream sink to write to

Returns Task - task that finishes when forwarding finishes or exists with an error

copy_packets

Copy packets from one datagram stream (half-socket) to a datagram sink.

Parameters:

  • bufsize (i64)
  • from (DatagramRead)
  • to (DatagramWrite)

Returns Task

datagram_logger

Wrap datagram socket in an overlay that logs every inner read and write to stderr. Stderr is assumed to be always available. Backpressure would cause whole process to stop serving connections and inability to log may abort the process.

It is OK if a read or write handle of the source socket is null - resulting socket would also be incomplete. This allows to access the logger having only reader or writer instead of a complete socket.

This component is not performance-optimised and is intended for mostly for debugging.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • inner (DatagramSocket)

Returns DatagramSocket

Options:

  • verbose (bool) - Show more messages and more info within messages
  • read_prefix (Option<String>) - Prepend this instead of "READ " to each line printed to stderr
  • write_prefix (Option<String>) - Prepend this instead of "WRITE " to each line printed to stderr
  • omit_content (bool) - Do not log full content of the stream, just the chunk lengths.
  • hex (bool) - Use hex lines instead of string literals with espaces
  • include_timestamps (bool) - Also print relative timestamps for each log message

defragment_writes

Buffer up fragments of messages written to this overlay and only issue complete writes to inner socket.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • inner (DatagramSocket)

Returns DatagramSocket

Options:

  • max_send_datagram_size (usize) - Defragmenter buffer limit

display_pkts

Sample sink for packets for demonstration purposes

Returns DatagramWrite

drop

Attempt to drop a socket or task or other handle

Parameters:

  • x (Dynamic)

Returns ()

dummy_datagram_socket

Create datagram socket with a source handle that continuously emits EOF-marked empty buffers and a sink handle that ignores all incoming data and null hangup handle.

Can also be used a source of dummies for individual directions, with take_sink_part and take_source_part functions

Returns DatagramSocket

dummy_stream_socket

Create stream socket with a read handle that emits EOF immediately, write handle that ignores all incoming data and null hangup handle.

Can also be used a source of dummies for individual directions, with take_read_part and take_write_part functions

Returns StreamSocket

dummy_task

A task that immediately finishes

Returns Task

empty_hangup_handle

Create null Hangup handle

Returns Hangup

exchange_bytes

Copy bytes between two stream-oriented sockets

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • s1 (StreamSocket)
  • s2 (StreamSocket)

Returns Task

Options:

  • unidirectional (bool) - Transfer data only from s1 to s2
  • unidirectional_reverse (bool) - Transfer data only from s2 to s1
  • exit_on_eof (bool) - abort one transfer direction when the other reached EOF
  • unidirectional_late_drop (bool) - keep inactive transfer direction handles open
  • buffer_size_forward (Option<usize>) - allocate this amount of buffers for transfer from s1 to s2
  • buffer_size_reverse (Option<usize>) - allocate this amount of buffers for transfer from s2 to s1

exchange_packets

Exchange packets between two datagram-oriented sockets

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • s1 (DatagramSocket)
  • s2 (DatagramSocket)

Returns Task

Options:

  • unidirectional (bool) - Transfer data only from s1 to s2
  • unidirectional_reverse (bool) - Transfer data only from s2 to s1
  • exit_on_eof (bool) - abort one transfer direction when the other reached EOF
  • unidirectional_late_drop (bool) - keep inactive transfer direction handles open
  • buffer_size_forward (Option<usize>) - allocate this amount of buffers for transfer from s1 to s2
  • buffer_size_reverse (Option<usize>) - allocate this amount of buffers for transfer from s2 to s1

exit_process

Exit Websocat process. If WebSocket is serving multiple connections, they all get aborted.

Parameters:

  • code (i64)

Does not return anything.

file_socket

Open specified file and read/write it.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • path (OsString)
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • write (bool) - Open specified file for writing, not reading
  • append (bool) - Open specified file for appending, not reading
  • no_overwrite (bool) - Do not overwrite existing files, instead use modified randomized name. Only relevant for write mode.
  • auto_rename (bool) - Do not overwrite existing files, instead use modified randomized name. Only relevant for write mode.

get_fd

Get underlying file descriptor from a socket, or -1 if is cannot be obtained

Parameters:

  • x (Dynamic)

Returns i64

get_ip

Extract IP address from SocketAddr

Parameters:

  • sa (&mut SocketAddr)

Returns String

get_port

Extract port from SocketAddr

Parameters:

  • sa (&mut SocketAddr)

Returns i64

handle_hangup

Spawn a task that calls continuation when specified socket hangup handle fires

Parameters:

  • hangup (Hangup)
  • continuation (Fn() -> Task) - Rhai function that will be called to continue processing

Returns ()

hangup2task

Convert a hangup token into a task. I don't know why this may be needed.

Parameters:

  • hangup (Hangup)

Returns Task

http1_client

Converts a downstream stream socket into a HTTP 1 client, suitable for sending e.g. WebSocket upgrade request.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • inner (StreamSocket)

Returns Http1Client

http1_serve

Converts a downstream stream socket into a HTTP 1 server, suitable for accepting e.g. WebSocket upgrade request.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • inner (StreamSocket)
  • continuation (Fn(IncomingRequest, Hangup, i64) -> OutgoingResponse) - Rhai function that will be called to continue processing

Returns Task

init_in_parallel

Initialize multiple things in parallel using a array of closures, then call final closure with results of the initialisation

Parameters:

  • initialisers (Vec<Dynamic>) - Array of functions to call to prepare the Vec<Dynamic> for continuation below. Each function should have signature like Fn(Slot) -> Task.
  • continuation (Fn(Vec<Dynamic>) -> Task) - Rhai function that will be called to continue processing

Returns Task

length_prefixed_chunks

Convert downstream stream socket into upstream packet socket using a byte separator

If you want just source or sink conversion part, create incomplete socket, use this function, then extract the needed part from resulting incomplete socket.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • x (StreamSocket)

Returns DatagramSocket

Options:

  • length_mask (u64) - Maximum message length that can be encoded in header, power of two minus one
  • nbytes (usize) - Number of bytes in header field
  • max_message_size (usize) - Maximum size of a message that can be encoded, unless continuations is set to true. Does not affect decoded messages.
  • little_endian (bool) - Encode header as a little-endian number instead of big endian
  • skip_read_direction (bool) - Inhibit adding header to data transferred in read direction, pass byte chunks unmodified
  • skip_write_direction (bool) - Inhibit adding header to data transferred in read direction, pass byte chunks unmodified
  • continuations (Option<u64>) - Do not defragment written messages, write WebSocket frames instead of messages (and bitwise-or specified number into the header).
  • controls (Option<u64>) - Also write pings, pongs and CloseFrame messages, setting specified bit (pre-shifted) in header and prepending opcode in content. Length would include this prepended byte. Affects read direction as well, allowing manually triggering WebSocket control messages.
  • tag_text (Option<u64>) - Set specified pre-shifted bit in header when dealing with text WebSocket messages. Note that with continuations, messages can be split into fragments in middle of a UTF-8 characters.

line_chunks

Convert downstream stream socket into upstream packet socket using a byte separator

If you want just source or sink conversion part, create incomplete socket, use this function, then extract the needed part from resulting incomplete socket.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • x (StreamSocket)

Returns DatagramSocket

Options:

  • separator (Option<u8>) - Use this byte as a separator. Defaults to 10 (\n).
  • separator_n (Option<usize>) - Use this number of repetitions of the specified byte to consider it as a separator. Defaults to 1.
  • substitute (Option<u8>) - When framing messages, look for byte sequences within the message that may alias with the separator and substitute last byte of such pseudo-separators with this byte value. If active, leading and trailing separator bytes are also removed from the datagrams
  • inline (bool) - When framing messages, preserve separators as a part of the content at the end of each message.

listen_registry_datagrams

Listen for intra-Websocat datagram socket connections on a specified virtual address

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • continuation (Fn(DatagramSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • addr (String)
  • autospawn (bool) - Automatically spawn a task for each accepted connection
  • oneshot (bool) - Exit listening loop after processing a single connection

listen_registry_stream

Listen for intra-Websocat stream socket connections on a specified virtual address

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • addr (String)
  • autospawn (bool) - Automatically spawn a task for each accepted connection
  • oneshot (bool) - Exit listening loop after processing a single connection

listen_seqpacket

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • path (OsString) - Path to a socket file to create, name of abstract address to use or empty string if fd is used.
  • when_listening (Fn() -> Task) - Called once after the port is bound
  • on_accept (Fn(DatagramSocket) -> Task) - Call on each incoming connection

Returns Task

Options:

  • fd (Option<i32>) - Inherited file descriptor to accept connections from
  • named_fd (Option<String>) - Inherited file named (`LISTEN_FDNAMES``) descriptor to accept connections from
  • fd_force (bool) - Skip socket type check when using fd.
  • abstract (bool) - On Linux, connect to an abstract-namespaced socket instead of file-based
  • chmod (Option<u32>) - Change filesystem mode (permissions) of the file after listening
  • autospawn (bool) - Automatically spawn a task for each accepted connection
  • text (bool) - Mark received datagrams as text
  • oneshot (bool) - Exit listening loop after processing a single connection
  • max_send_datagram_size (usize) - Defragmenter buffer limit

listen_tcp

Listen TCP socket at specified address

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • when_listening (Fn(SocketAddr) -> Task) - Called once after the port is bound
  • on_accept (Fn(StreamSocket, SocketAddr) -> Task) - Called on each connection

Returns Task

Options:

  • addr (Option<SocketAddr>) - Socket address to bind listening socket to
  • fd (Option<i32>) - Inherited file descriptor to accept connections from
  • named_fd (Option<String>) - Inherited file named (`LISTEN_FDNAMES``) descriptor to accept connections from
  • fd_force (bool) - Skip socket type check when using fd.
  • autospawn (bool) - Automatically spawn a task for each accepted connection
  • oneshot (bool) - Exit listening loop after processing a single connection
  • reuseaddr (Option<bool>) - Set SO_REUSEADDR for the listening socket
  • reuseport (bool) - Set SO_REUSEPORT for the listening socket
  • bind_device (Option<String>) - Set SO_BINDTODEVICE for the listening socket
  • backlog (Option<u32>) - Set size of the queue of unaccepted pending connections for this socket. Default is 1024 when oneshot is off and 1 and oneshot is on.
  • transparent (bool) - Set IP_TRANSPARENT for the listening socket
  • freebind (bool) - Set IP_FREEBIND for the listening socket
  • only_v6 (Option<bool>) - Set IPV6_V6ONLY for the listening socket
  • tclass_v6 (Option<u32>) - Set IPV6_TCLASS for accepted IPv6 sockets
  • tos_v4 (Option<u32>) - Set IP_TOS for accepted IPv4 sockets
  • ttl (Option<u32>) - Set IP_TTL accepted IPv4 sockets and or IPV6_UNICAST_HOPS for an IPv6
  • linger_s (Option<u32>) - Set SO_LINGER for accepted sockets
  • out_of_band_inline (bool) - Set SO_OOBINLINE for accepted sockets
  • nodelay (Option<bool>) - Set TCP_NODELAY (no Nagle) for accepted sockets
  • tcp_congestion (Option<String>) - Set TCP_CONGESTION for accepted sockets
  • cpu_affinity (Option<usize>) - Set SO_INCOMING_CPU for accepted sockets
  • user_timeout_s (Option<u32>) - Set TCP_USER_TIMEOUT for accepted sockets
  • priority (Option<u32>) - Set SO_PRIORITY for accepted sockets
  • recv_buffer_size (Option<usize>) - Set SO_RCVBUF for accepted sockets
  • send_buffer_size (Option<usize>) - Set SO_SNDBUF for accepted sockets
  • mss (Option<u32>) - Set TCP_MAXSEG for accepted sockets
  • mark (Option<u32>) - Set SO_MARK for accepted sockets
  • thin_linear_timeouts (Option<bool>) - Set TCP_THIN_LINEAR_TIMEOUTS for accepted sockets
  • notsent_lowat (Option<u32>) - Set TCP_NOTSENT_LOWAT for accepted sockets
  • keepalive (Option<bool>) - Set SO_KEEPALIVE for accepted sockets
  • keepalive_retries (Option<u32>) - Set TCP_KEEPCNT for accepted sockets
  • keepalive_interval_s (Option<u32>) - Set TCP_KEEPINTVL for accepted sockets
  • keepalive_idletime_s (Option<u32>) - Set TCP_KEEPALIVE for accepted sockets

listen_unix

Listen UNIX or abstract socket

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • path (OsString) - Path to a socket file to create, name of abstract address to use or empty string if fd is used.
  • when_listening (Fn() -> Task) - Called once after the port is bound
  • on_accept (Fn(StreamSocket) -> Task) - Called on each accepted connection

Returns Task

Options:

  • fd (Option<i32>) - Inherited file descriptor to accept connections from
  • named_fd (Option<String>) - Inherited file named (`LISTEN_FDNAMES``) descriptor to accept connections from
  • fd_force (bool) - Skip socket type check when using fd.
  • abstract (bool) - On Linux, listen an abstract-namespaced socket instead of file-based
  • chmod (Option<u32>) - Change filesystem mode (permissions) of the file after listening
  • autospawn (bool) - Automatically spawn a task for each accepted connection
  • oneshot (bool) - Exit listening loop after processing a single connection

literal_socket

Create a stream socket with a read handle emits specified data, then EOF; and write handle that ignores all incoming data and null hangup handle.

Parameters:

  • data (String)

Returns StreamSocket

literal_socket_base64

Create a stream socket with a read handle emits specified data, then EOF; and write handle that ignores all incoming data and null hangup handle.

Parameters:

  • data (String)

Returns StreamSocket

lookup_host

Perform a DNS lookup of the specified hostname and call a continuation with the list of IPv4 and IPv6 socket addresses

Parameters:

  • addr (String)
  • continuation (Fn(Vec<SocketAddr>) -> Task) - Rhai function that will be called to continue processing

Returns Task

make_socket_addr

Build SocketAddr from IP and port

Parameters:

  • ip (&str)
  • port (i64)

Returns SocketAddr

mock_stream_socket

Create special testing stream socket that emits user-specified data in user-specified chunks and verifies that incoming data matches specified samples.

If something is unexpected, Websocat will exit (panic).

Argument is a specially formatted string describing operations, separated by | character.

Operations:

  • R - make the socket return specified chunk of data
  • W - make the socket wait for incoming data and check if it matches the sample
  • ER / EW - inject read or write error
  • T0 ... T9 - sleep for some time interval, from small to large.
  • N - set name of the mock object

Example: R hello|R world|W ping |R pong|T5|R zero byte \0 other escapes \| \xff \r\n\t|EW

Parameters:

  • content (String)

Returns StreamSocket

null_datagram_socket

Create datagram socket with null read, write and hangup handles. Use put_source_part and put_sink_part to fill in the data transfer directions.

Returns DatagramSocket

null_stream_socket

Create stream socket with null read, write and hangup handles. Use put_read_part and put_write_part to fill in the data transfer directions.

Returns StreamSocket

osstr_base64_unchecked_encoded_bytes

Decode base64 buffer and interpret using Rust's OsString::from_encoded_bytes_unchecked. This format is not intended to be portable and is mostly for internal use within Websocat.

Parameters:

  • x (String)

Returns OsString

osstr_base64_unix_bytes

On Unix or WASI platforms, decode base64 buffer and convert it OsString.

Parameters:

  • x (String)

Returns OsString

osstr_base64_windows_utf16le

On Windows, decode base64 buffer and convert it OsString.

Parameters:

  • x (String)

Returns OsString

osstr_str

Convert a usual UTF-8 string to an OsString

Parameters:

  • x (String)

Returns OsString

packetmirror_socket

Create a datagram socket that reads everything written to it.

Buffer size is unlimited in theory, but should be be larger that -B size in practice.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function

Returns DatagramSocket

parallel

Execute specified tasks in parallel, waiting them all to finish.

Parameters:

  • tasks (Vec<Dynamic>)

Returns Task

pre_triggered_hangup_handle

Create a Hangup handle that immediately resolves (i.e. signals hangup)

Returns Hangup

Print a string to stderr (synchronously)

Parameters:

  • x (&str)

Returns ()

Print a string to stdout (synchronously)

Parameters:

  • x (&str)

Does not return anything.

put_hangup_part

Modify Socket, filling in the hangup signal with the specified one

Parameters:

  • h (Dynamic)
  • x (Hangup)

Returns ()

put_read_part

Modify stream-oriented Socket, filling in the read direction with the specified one

Parameters:

  • h (StreamSocket)
  • x (StreamRead)

Returns ()

put_sink_part

Modify datagram-oriented Socket, filling in the write direction with the specified one

Parameters:

  • h (DatagramSocket)
  • x (DatagramWrite)

Returns ()

put_source_part

Modify datagram-oriented Socket, filling in the read direction with the specified one

Parameters:

  • h (DatagramSocket)
  • x (DatagramRead)

Returns ()

put_write_part

Modify stream-oriented Socket, filling in the write direction with the specified one

Parameters:

  • h (StreamSocket)
  • x (StreamWrite)

Returns ()

race

Execute specified tasks in parallel, aborting all others if one of them finishes.

Parameters:

  • tasks (Vec<Dynamic>)

Returns Task

random_socket

Create a StreamSocket that reads random bytes (affected by --random-seed) and ignores writes

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function

Returns StreamSocket

Options:

  • fast (bool) - Use small, less secure RNG instead of slower secure one.

read_chunk_limiter

Transform stream source so that reads become short reads if there is enough data. For development and testing.

Parameters:

  • x (StreamRead)
  • limit (i64)

Returns StreamRead

read_stream_chunks

Convert a stream source to a datagram source

Parameters:

  • x (StreamRead)

Returns DatagramRead

registry_recv_all

Receive all objects from a named slot in the registry and call continuation for each one

Parameters:

  • addr (&str)
  • continuation (Fn(Dynamic) -> Task) - Rhai function that will be called to continue processing

Returns Task

registry_recv_one

Receive one object from a named slot in the registry and call continuation once for it

Parameters:

  • addr (&str)
  • continuation (Fn(Dynamic) -> Task) - Rhai function that will be called to continue processing

Returns Task

registry_send

Send some object to named slot in the registry. Blocks if no receivers yet.

Parameters:

  • addr (&str)
  • x (Dynamic)

Returns Task

sequential

Execute specified tasks in order, starting another and previous one finishes.

Parameters:

  • tasks (Vec<Dynamic>)

Returns Task

shutdown_and_drop

Shutdown the writing part of a socket and drop it. If reading part was used extracted and used elsewhere, it stays active.

Parameters:

  • x (Dynamic)

Returns ()

simple_reuser

Create object that multiplexes multiple DatagramSocket connections into one, forwarding inner reads to arbitrary outer readers.

If inner socket disconnects, reuser will not attempt to reestablish the connection

Parameters:

  • inner (DatagramSocket) - Datagram socket to multiplex connections to
  • disconnect_on_torn_datagram (bool) - Drop inner connection when user begins writing a message, but leaves before finishing it, leaving inner connection with incomplete message that cannot ever be completed. If false, the reuser would commit the torn message and continue processing.

Returns SimpleReuser

simple_reuser_listener

Create an inactive SimpleReuserListener. It becomes active when maybe_init_then_connect is called the first time

Returns SimpleReuserListener

sleep_ms

A task that finishes after specified number of milliseconds

Parameters:

  • ms (i64)

Returns Task

spawn_task

Start execution of the specified task in background

Parameters:

  • task (Task)

Does not return anything.

stdio_socket

Obtain a stream socket made of stdin and stdout. This spawns a OS thread to handle interactions with the stdin/stdout and may be inefficient.

Returns StreamSocket

str

Turn any object into some string representation

Parameters:

  • x (Dynamic)

Returns String

stream_chunks

Convert a stream socket to a datagram socket. Like write_stream_chunks + read_stream_chunks while also preserving the hangup signal.

Parameters:

  • x (StreamSocket)

Returns DatagramSocket

stream_logger

Wrap stream socket in an overlay that logs every inner read and write to stderr. Stderr is assumed to be always available. Backpressure would cause whole process to stop serving connections and inability to log may abort the process.

It is OK a if read or write handle of the source socket is null - resulting socket would also be incomplete. This allows to access the logger having only reader or writer instead of a complete socket.

This component is not performance-optimised and is intended for mostly for debugging.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • inner (StreamSocket)

Returns StreamSocket

Options:

  • verbose (bool) - Show more messages and more info within messages
  • read_prefix (Option<String>) - Prepend this instead of "READ " to each line printed to stderr
  • write_prefix (Option<String>) - Prepend this instead of "WRITE " to each line printed to stderr
  • omit_content (bool) - Do not log full content of the stream, just the chunk lengths.
  • hex (bool) - Use hex lines instead of string literals with espaces
  • include_timestamps (bool) - Also print relative timestamps for each log message

subprocess_new

Prepare subprocess, setting up executable name. See Command:: methods for further steps.

Parameters:

  • program_name (String)

Returns Command

subprocess_new_osstr

Prepare subprocess, setting up possibly non-UTF8 executable name. See Command:: methods for further steps.

Parameters:

  • program_name (OsString)

Returns Command

swap_readers

Exchange read or source parts of two stream or two datagram sockets.

Parameters:

  • a (Dynamic)
  • b (Dynamic)

Returns ()

swap_writers

Exchange write or sink parts of two stream or two datagram sockets.

Parameters:

  • a (Dynamic)
  • b (Dynamic)

Returns ()

system

Simplified function to just execute a command line

Parameters:

  • cmdline (&str)

Returns Hangup

take_hangup_part

Modify Socket, taking the hangup signal part, if it is set.

Parameters:

  • h (Dynamic)

Returns Hangup

take_read_part

Modify stream-oriented Socket, taking the read part and returning it separately. Leaves behind an incomplete socket.

Parameters:

  • h (StreamSocket)

Returns StreamRead

take_sink_part

Modify datagram-oriented Socket, taking the write part and returning it separately. Leaves behind an incomplete socket.

Parameters:

  • h (DatagramSocket)

Returns DatagramWrite

take_source_part

Modify datagram-oriented Socket, taking the read part and returning it separately. Leaves behind an incomplete socket.

Parameters:

  • h (DatagramSocket)

Returns DatagramRead

take_write_part

Modify stream-oriented Socket, taking the write part and returning it separately. Leaves behind an incomplete socket.

Parameters:

  • h (StreamSocket)

Returns StreamWrite

task2hangup

Create hangup handle that gets triggered when specified task finishes.

Parameters:

  • task (Task)
  • mode (i64) - 0 means unconditionally, 1 means only when task has failed, 2 means only when task has succeeded.

Returns Hangup

task_wrap

Create a Task that runs specified Rhai code when scheduled.

Parameters:

  • continuation (Fn() -> Task) - Rhai function that will be called to continue processing

Returns Task

tee

Combine multiple datagram sockets into one that writes to all specified inner sockets and reads from any of them.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • sockets (Vec<Dynamic>) - Array of DatagramSockets

Returns DatagramSocket

Options:

  • write_fail_all_if_one_fails (bool) - Disconnect all the inner socket writers if one hangs up or fails a write
  • read_fail_all_if_one_fails (bool) - Disconnect all the inner socket writers if one hangs up or fails a write
  • propagate_eofs (bool) - If one of tee:'s branches signed EOF, propagate it to user
  • tolerate_torn_msgs (bool) - If a node starts emitting a datagram, then goes away; do not abort the reading side of the connection, instead just make a trimmed, corrupted message and continue.
  • use_hangups (bool) - Cause hangup if any of the branches signals a hangup
  • use_first_hangup (bool) - Use hangup token specifically from the first of specified sockets

timeout_ms_hangup_handle

Create a Hangup handle that resolves after specific number of milliseconds

Parameters:

  • ms (i64)

Returns Hangup

tls_client

Perform TLS handshake using downstream stream-oriented socket, then expose stream-oriented socket interface to upstream that encrypts/decrypts the data.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • connector (Arc<tokio_native_tls::TlsConnector>)
  • inner (StreamSocket)
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • domain (String)

tls_client_connector

Create environment for using TLS clients.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function

Returns Arc<tokio_native_tls::TlsConnector>

Options:

  • min_protocol_version (Option<String>)
  • max_protocol_version (Option<String>)
  • root_certificates_pem (Vec<String>)
  • root_certificates_der_base64 (Vec<String>)
  • disable_built_in_roots (bool)
  • request_alpns (Vec<String>)
  • danger_accept_invalid_certs (bool)
  • danger_accept_invalid_hostnames (bool)
  • no_sni (bool)

triggerable_event_create

Create new one-time synchronisation object that allows to trigger a hangup event explicitly from Rhai code.

Returns TriggerableEvent

trivial_pkts

Sample source of packets for demonstration purposes

Returns DatagramRead

udp_server

Create a single Datagram Socket that is bound to a UDP port, typically for connecting to a specific UDP endpoint

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • when_listening (Fn(SocketAddr) -> Task) - Called once after the port is bound
  • on_accept (Fn(DatagramSocket, SocketAddr) -> Task) - Called when new client is sending us datagrams

Returns Task

Options:

  • bind (Option<SocketAddr>) - Specify address to bind the socket to.
  • fd (Option<i32>) - Inherited file descriptor to accept connections from
  • named_fd (Option<String>) - Inherited file named (`LISTEN_FDNAMES``) descriptor to accept connections from
  • fd_force (bool) - Skip socket type check when using fd.
  • timeout_ms (Option<u64>) - Mark the connection as closed when this number of milliseconds elapse without a new datagram from associated peer address
  • max_clients (Option<usize>) - Maximum number of simultaneously connected clients. If exceed, stale clients (based on the last received datagram) will be hung up.
  • buffer_size (Option<usize>) - Buffer size for receiving UDP datagrams. Default is 4096 bytes.
  • qlen (Option<usize>) - Queue length for distributing received UDP datagrams among spawned DatagramSocekts Defaults to 1.
  • tag_as_text (bool) - Tag incoming UDP datagrams to be sent as text WebSocket messages instead of binary. Note that Websocat does not check for UTF-8 correctness and may send non-compliant text WebSocket messages.
  • backpressure (bool) - In case of one slow client handler, delay incoming UDP datagrams instead of dropping them
  • inhibit_send_errors (bool) - Do not exit if sendto returned an error.
  • max_send_datagram_size (usize) - Defragmenter buffer limit
  • reuseaddr (Option<bool>) - Set SO_REUSEADDR for the socket
  • reuseport (bool) - Set SO_REUSEPORT for the socket
  • bind_device (Option<String>) - Set SO_BINDTODEVICE for the socket
  • transparent (bool) - Set IP_TRANSPARENT for the socket
  • freebind (bool) - Set IP_FREEBIND for the socket
  • only_v6 (Option<bool>) - Set IPV6_V6ONLY for the socket in case when it is IPv6
  • tclass_v6 (Option<u32>) - Set IPV6_TCLASS for the IPv6 socket
  • tos_v4 (Option<u32>) - Set IP_TOS for the IPv4 socket
  • ttl (Option<u32>) - Set IP_TTL the IPv4 socket or IPV6_UNICAST_HOPS for an IPv6
  • cpu_affinity (Option<usize>) - Set SO_INCOMING_CPU for the socket
  • priority (Option<u32>) - Set SO_PRIORITY for the socket
  • recv_buffer_size (Option<usize>) - Set SO_RCVBUF for the socket
  • send_buffer_size (Option<usize>) - Set SO_SNDBUF for the socket
  • mark (Option<u32>) - Set SO_MARK for the socket
  • broadcast (bool) - Set SO_BROADCAST to true for the socket
  • multicast (Option<IpAddr>) - Use IP_ADD_MEMBERSHIP or IPV6_ADD_MEMBERSHIP for the socket
  • multicast_interface_addr (Option<Ipv4Addr>) - Use this interface address instead of 0.0.0.0 when joining multicast
  • multicast_interface_index (Option<u32>) - Use this interface index instead of 0 when joining multicast.
  • multicast_specific_source (Option<Ipv4Addr>) - Use IP_ADD_SOURCE_MEMBERSHIP instead of IP_ADD_MEMBERSHIP.
  • multicast_all (Option<bool>) - Set IP_MULTICAST_ALL or IPV6_MULTICAST_ALL for the socket
  • multicast_loop (Option<bool>) - Set IP_MULTICAST_LOOP or IPV6_MULTICAST_LOOP for the socket
  • multicast_ttl (Option<u32>) - Set IP_MULTICAST_TTL or IPV6_MULTICAST_HOPS for the socket

udp_socket

Create a single Datagram Socket that is bound to a UDP port, typically for connecting to a specific UDP endpoint

The node does not have it's own buffer size - the buffer is supplied externally

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function

Returns DatagramSocket

Options:

  • addr (SocketAddr) - Send datagrams to and expect datagrams from this address. Specify neutral address like 0.0.0.0:0 to blackhole outgoing packets until correct address is determined.
  • fd (Option<i32>) - Inherited file descriptor to accept connections from
  • named_fd (Option<String>) - Inherited file named (`LISTEN_FDNAMES``) descriptor to accept connections from
  • fd_force (bool) - Skip socket type check when using fd.
  • bind (Option<SocketAddr>) - Specify address to bind the socket to. By default it binds to 0.0.0.0:0 or [::]:0
  • sendto_mode (bool) - Use sendto instead of connect + send. This mode ignores ICMP reports that target is not reachable.
  • allow_other_addresses (bool) - Do not filter out incoming datagrams from addresses other than addr. Useless without sendto_mode.
  • redirect_to_last_seen_address (bool) - Send datagrams to address of the last seen incoming datagrams, using addr only as initial address until more data is received. Useless without allow_other_addresses. May have security implications.
  • connect_to_first_seen_address (bool) - When using redirect_to_last_seen_address, lock the socket to that address, preventing more changes and providing disconnects. Useless without redirect_to_last_seen_address.
  • tag_as_text (bool) - Tag incoming UDP datagrams to be sent as text WebSocket messages instead of binary. Note that Websocat does not check for UTF-8 correctness and may send non-compliant text WebSocket messages.
  • inhibit_send_errors (bool) - Do not exit if sendto returned an error.
  • max_send_datagram_size (usize) - Defragmenter buffer limit
  • reuseaddr (Option<bool>) - Set SO_REUSEADDR for the socket
  • reuseport (bool) - Set SO_REUSEPORT for the socket
  • bind_device (Option<String>) - Set SO_BINDTODEVICE for the socket
  • transparent (bool) - Set IP_TRANSPARENT for the socket
  • freebind (bool) - Set IP_FREEBIND for the socket
  • only_v6 (Option<bool>) - Set IPV6_V6ONLY for the socket in case when it is IPv6
  • tclass_v6 (Option<u32>) - Set IPV6_TCLASS for the IPv6 socket
  • tos_v4 (Option<u32>) - Set IP_TOS for the IPv4 socket
  • ttl (Option<u32>) - Set IP_TTL the IPv4 socket or IPV6_UNICAST_HOPS for an IPv6
  • cpu_affinity (Option<usize>) - Set SO_INCOMING_CPU for the socket
  • priority (Option<u32>) - Set SO_PRIORITY for the socket
  • recv_buffer_size (Option<usize>) - Set SO_RCVBUF for the socket
  • send_buffer_size (Option<usize>) - Set SO_SNDBUF for the socket
  • mark (Option<u32>) - Set SO_MARK for the socket
  • broadcast (bool) - Set SO_BROADCAST to true for the socket
  • multicast (Option<IpAddr>) - Use IP_ADD_MEMBERSHIP or IPV6_ADD_MEMBERSHIP for the socket
  • multicast_interface_addr (Option<Ipv4Addr>) - Use this interface address instead of 0.0.0.0 when joining multicast
  • multicast_interface_index (Option<u32>) - Use this interface index instead of 0 when joining multicast.
  • multicast_specific_source (Option<Ipv4Addr>) - Use IP_ADD_SOURCE_MEMBERSHIP instead of IP_ADD_MEMBERSHIP.
  • multicast_all (Option<bool>) - Set IP_MULTICAST_ALL or IPV6_MULTICAST_ALL for the socket
  • multicast_loop (Option<bool>) - Set IP_MULTICAST_LOOP or IPV6_MULTICAST_LOOP for the socket
  • multicast_ttl (Option<u32>) - Set IP_MULTICAST_TTL or IPV6_MULTICAST_HOPS for the socket

Parameters:

  • path (OsString)
  • bail_if_fails (bool) - Emit error if unlinking fails.

Returns ()

write_buffer

Wrap stream writer in a buffering overlay that may accumulate data, e.g. to write in one go on flush

Parameters:

  • inner (StreamWrite)
  • capacity (i64)

Returns StreamWrite

write_chunk_limiter

Transform stream sink so that writes become short writes if the buffer is too large. For development and testing.

Parameters:

  • x (StreamWrite)
  • limit (i64)

Returns StreamWrite

write_stream_chunks

Convert a stream sink to a datagram sink

Parameters:

  • x (StreamWrite)

Returns DatagramWrite

ws_accept

Perform WebSocket server handshake, then recover the downstream stream socket that was used for http_server.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • custom_headers (rhai::Map)
  • rq (IncomingRequest)
  • close_handle (Hangup)
  • fd (i64)
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns OutgoingResponse

Options:

  • lax (bool) - Do not check incoming headers for correctness
  • omit_headers (bool) - Do not include any headers in response
  • choose_protocol (Option<String>) - If client supplies Sec-WebSocket-Protocol and it contains this one, include the header in response.
  • require_protocol (bool) - Fail incoming connection if Sec-WebSocket-Protocol lacks the value specified in choose_protocol field (or any protocol if protocol_choose_first is active).
  • protocol_choose_first (bool) - Round trip Sec-WebSocket-Protocol from request to response, choosing the first protocol if there are multiple

ws_decoder

Wrap downstream stream-oriented reader to make expose packet-oriented source using WebSocket framing

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • inner (StreamRead)

Returns DatagramRead

Options:

  • require_masked (bool) - Require decoded frames to be masked (i.e. coming from a client)
  • require_unmasked (bool) - Require decoded frames to be unmasked (i.e. coming from a server)

ws_encoder

Wrap downstream stream-oriented writer to make expose packet-oriented sink using WebSocket framing

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • inner (StreamWrite)

Returns DatagramWrite

Options:

  • masked (bool) - Use masking (i.e. client-style)
  • no_flush_after_each_message (bool)
  • no_close_frame (bool) - Do not emit ConnectionClose frame when shutting down
  • shutdown_socket_on_eof (bool) - Shutdown downstream socket for writing when shutting down

ws_upgrade

Perform WebSocket client handshake, then recover the downstream stream socket that was used for http_client.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • custom_headers (rhai::Map) - Additional request headers to include
  • client (Http1Client)
  • continuation (Fn(StreamSocket) -> Task) - Rhai function that will be called to continue processing

Returns Task

Options:

  • url (String)
  • host (Option<String>)
  • lax (bool) - Do not check response headers for correctness. Note that some Upgrade: header is required to continue connecting.
  • omit_headers (bool) - Do not include any headers besides 'Host' (if any) in request

ws_wrap

Like ws_encoder + ws_decoder, but also set up automatic replier to WebSocket pings.

Parameters:

  • opts (Dynamic) - object map containing dynamic options to the function
  • inner (StreamSocket)

Returns DatagramSocket

Options:

  • client (bool) - Mask outgoing frames and require unmasked incoming frames
  • ignore_masks (bool) - Accept masked (unmasked) frames in client (server) mode.
  • no_flush_after_each_message (bool) - Inhibit flushing of underlying stream writer after each complete message
  • no_close_frame (bool) - Do not emit ConnectionClose frame when writing part is getting shut down
  • shutdown_socket_on_eof (bool) - Propagate upstream writer shutdown to downstream
  • no_auto_buffer_wrap (bool) - Do not automatically wrap WebSocket frames writer in a write_buffer: overlay when it detects missing vectored writes support
  • max_ping_replies (Option<usize>) - Stop replying to WebSocket pings after sending this number of Pong frames.

zero_socket

Create a StreamSocket that reads zero bytes and ignores writes

Returns StreamSocket

Glossary

  • Specifier - WebSocket URL, TCP socket address or other connection type Websocat recognizes, or an overlay that transforms other Specifier.
  • Endpoint - leaf-level specifier that directly creates some sort of Socket, without requiring another Socket first.
  • Overlay - intermediate specifier that transforms inner specifier. From overlay's viewpoint, inner socket is called Downstream and whatever uses the overlay is called Upstream.
  • Socket - a pair of byte stream- or datagram-oriented data flows: write (sink) and read (source), optionally with a hangup signal. Can be stream- and packet-oriented.
  • Incomplete socket - socket where one of direction (reader or writer) is absent (null). Not to be confused with half-shutdown socket that can be read, but not written.
  • Scenario = Websocat Rhai Script - detailed instruction of how Websocat would perform its operation. Normally it is generated automatically from CLI arguments, then executed; but you can separate those steps and customize the scenario to fine tune of how Websocat operates. Just like usual CLI API, Rhai functions API is also intended to be semver-stable API of Websocat.
  • Scenario function - Rhai native function that Websocat registers with Rhai engine that can be used in Scenarios.
  • Scenario Planner - part of Websocat implementation that parses command line arguments and prepares a Scenario
  • Scenario Executor - part of Websocat implementation that executes a Scenario.
  • CLI arguments - combination of a positional arguments (typically Specifiers) and various flags (e.g. --binary) and options (e.g. --buffer-size 4096) that affect Scenario Planner. Sometimes, in narrow sense, it may refer to an individual block of --compose-ed arguments.
  • CLI API - Things in Websocat that are accessible when starting Websocat executable and supplying various command-line arguments (except of -x or --no-fixups). This is expected to be more stable and easier to use, but less flexible compared to Scenario Functions.
  • Packet = Datagram = Message - A byte buffer with associated flags. Correspond to one WebSocket message. Within WebSocket, packets can be split to chunks, but that should not affect user-visible properties.
  • Chunk = Frame = Fragment - portion of data read or written to/from stream or datagram socket in one go. Maybe a fragment of a Message or be the whole Message.
  • Orphaned fragment - fragment of a larger message produced by a datagram socket that is gone. For tools that combines multiple data streams into one without buffering (reuse-raw:, tee:), this either aborts the connection or produces artificially trimmed datagram.
  • Task - a logical thread of execution. Rhai code is expected to create and combine some tasks. Typically each connection runs in its own task. Corresponds to Tokio tasks.
  • Hangup - similar to Task, but used in context of signaling various events, especially abrupt reset of sockets.
  • Specifier Stack - Individual components of a Specifier - Endpoint and a vector of Overlays.
  • Left side, first specifier - first positional argument you have specified at the left side of the Websocat CLI invocation (maybe after some transformation). Designed to handle both one-time use connectors and multi-use listeners.
  • Right side, second specifier - second positional argument of the Websocat CLI invocation (may be auto-generated). Designed for single-use things to attach to connections obtained from the Left side.
  • Listener - Type of Specifier that waits for incoming connections, spawning a task with a Socket for each incoming connection.

Design principles of Websocat4

  • Starting up Websocat and connection establishment is allowed to be slow (i.e. allowed to parse strings, allocate memory, walk trees). Data transfer in already established connections should be fast.
  • Rhai is used as a "control plane" and decides what connect to what and how transform layers are connected to each other.
  • When serving multiple connections, it is OK to execute Rhai code each time. It is not OK to execute Rhai code for each transferred packet within a connection.
  • Rhai script fully defines Websocat behaviour. Most other CLI options just affect how Rhai script is generated. Filenames / process arguments get serialized as bytes, maybe inserted as base64 into the script if needed.
  • It is OK to have Rhai functions that are reachable only when explicitly specifying the script (unused by high-level CLI).
  • Each connection (or connection direction) is either bytestream-oriented or datagram-oriented. Bytestream-oriented use tokio::io::{AsyncRead, AsyncWrite}, datagram-oriented connections use custom traits (not Stream<Bytes> / Sink<Bytes>).
  • Custom traits for datagram connections are geared towards Websocket use case and allows typical use cases without allocations or excessive copying data around each invocation. Unusual decisions include mutable buffer for writer (to aid in-place masking for WebSocket) and partial buffer immutability guarantees for readers.
  • WebSocket framing library is custom, designed with avoiding allocations in mind.
  • It is OK to have multiple indirections for each transferred data chunk (i.e. dyn layer between stdio and line wrapper, then between line wrapper and WebSocket framer, then between the framer and TLS layer, then between the TLS layer and TCP socket).
  • fn poll is also the way, not everything needs to be fn async .await.
  • It is OK to add more elaborate scenario_executor things to simplify Websocat's Rhai scripts.
  • Address types and overlay stacks use enum approach, not dyn.
  • Generated Rhai code should be readable and may be optimised a bit, but "callback hell" is allowed.
  • Documentation is generated by a hacky script parsing source code with regexes. Rust source code may need to be adjusted a bit to aid this.
  • Most of things should be within Safe Rust realm, but various low-level tricky things (custom socket types, raw sockets, tty, fork, dup2, signals) may use unsafe, with soundness that relies on sanity of choices supplied by end user.
  • Most of things should be accessible from CLI API, but fine-tuning order of operations or using the a specifier/overlay multiple times with different parameters may require editing Rhai script. If actually requested by users, this editing can be somehow simplified.

How Websocat process CLI arguments

TODO: write textual description of this

diagram

History or Websocat redesigns

Websocat started in 2016. In 2018 I decided that it's time to call it 1.0.0.

Eventually it has became my most popular project, so I keep extending and maintaining it.

However, v1.0.0 is based on legacy dependencies and does not use async/await (and has some other inconvenient design decisions), so I started redesigning it. It took multiple attempts to find the way I am satisfied with, but even abandoned attempts provided good educational value.

Fortunately, Websocat v1 remained maintained all the way through this experimentation.

0.4

Sync version, used thread per data transfer direction. Used websocket crate, clap for CLI.

1.0

Based on tokio-core, later on Tokio v0.1. Specifier stacks, using dyn-based pluggable overlays and address types. Locked to single async IO thread only. Uses Rc<RefCell> a lot. Iffy error handing. Still uses websocket crate.

2.0

Attempt to upgrade to Tokio 0.3 (and later Tokio 1.0) and Hyper 0.14 and make it multi-crate. Attempt to migrate websocket crate from hyper 0.10 to hyper 0.14.

Abandoned attempts to make arch saner incrementally.

3.0

"Second-system" edition.

Based on Tokio 1.0 from the beginning, based on tokio-tungstenite. Custom CLI framework, custom lisp-esque low-level specifier language (there is even a quasi-quote operator inside). Playground for rolling my own proc macros.

Even reached an alpha Github release, but I after thinking about flexibility and complexity and memory allocations I decided to count it as educational efforts and move on.

There are more plans and ideas of what to do next in Websocat4.

Firstly, some important functions from Websocat1 should be ported to Websocat4.

Then it will mostly depend on my own needs, inspiration and ongoing Github and other issues and questions.

For beta

  • TLS server
  • TLS client auth
  • outgoing pings
  • preamble/preamble-reverse
  • More datagram tools (autoreconnect, foreachmsg, literalreply)
  • base64 mode, text and binary prefixes
  • one message mode
  • broadcast reuser
  • inhibit Host: header when explicit one specified / http proxy option

Later

  • Lints for unused options

  • one message mode

  • More datagram tools (combine/fanout, limit)

  • (non-Websocket) HTTP games

  • HTTP/2 games

  • Proxies

  • TCP reset monitoring

  • Rich console with history

  • Compression overlay

  • base64 overlay

  • async stdio

  • JSON RPC tool

  • exit of specific byte mode

  • print ping RTTs

  • timestamp overlay

  • expose more TLS options to high-level UI

  • just-generate-accept and just-generate-key

  • max messages

  • speed limit

  • conncap (parallel connections limiter)

  • outgoing ping limiter

  • static files / strict URI mode

  • inetd mode

  • clogged

  • socks5 proxy

  • http proxy

  • Prometheus integration

  • simple encryptor/decryptor

  • waitfordata

  • left-to-right features to set envvars based on incoming request

  • Good, helpful -v logs

  • Automatic percent-encoding of URLs instead of invalid uri character.

  • DTLS

  • SCTP

  • QUIC

  • Play with cargo-auditable