websocat
Websocket proxy, socat-style
websocat 1.0.0-alpha
Vitaly "_Vi" Shukela <vi0oss@gmail.com>
Connection forwarder from/to web sockets to/from usual sockets, in style of socat
USAGE:
websocat [FLAGS] [OPTIONS] <s1> <s2>
FLAGS:
--dump-spec Instead of running, dump the specifiers representation to stdout
--exit-on-eof Close a data transfer direction if the other one reached EOF
-h, --help Prints help information
--long-help Show full help aboput specifiers and examples
--oneshot Serve only once
--udp-oneshot udp-listen: replies only one packet per client
-u, --unidirectional Inhibit copying data from right specifier to left
-U, --unidirectional-reverse Inhibit copying data from left specifier to right
--unlink Unlink listening UNIX socket before binding to it
-V, --version Prints version information
-t, --text Send text WebSocket messages instead of binary
OPTIONS:
--exec-args <exec_args>... Arguments for the `exec:` specifier. Must be the last option, everything
after it gets into the exec args list.
--protocol <websocket_protocol> Specify Sec-WebSocket-Protocol: header
--ws-c-uri <ws_c_uri> URI to use for ws-c: specifier [default: ws://0.0.0.0/]
ARGS:
<s1> First, listening/connecting specifier. See --long-help for info about specifiers.
<s2> Second, connecting specifier
Basic examples:
Connect stdin/stdout to a websocket:
websocat - ws://echo.websocket.org/
Listen websocket and redirect it to a TCP port:
websocat ws-l:127.0.0.1:8080 tcp:127.0.0.1:5678
See more examples with the --long-help option
Short list of specifiers (see --long-help):
ws:// wss:// - inetd: ws-listen: inetd-ws: tcp: tcp-l: ws-c:
autoreconnect: reuse: mirror: threadedstdio: clogged:
literal: literalreply: assert: udp-connect: open-async:
readfile: writefile: open-fd: unix-connect: unix-listen:
unix-dgram: abstract-connect: abstract-listen:
exec: sh-c:
It runs singlethreaded. There is old non-async threaded version in legacy
branch of releases prior to 0.5.
Specify listening part first, unless you want websocat to serve once (like in --oneshot
mode).
IPv6 supported, just use specifiers like ws-l:[::1]:4567
Web socket usage is not obligatory, you can use any specs on both sides.
If you want wss://
server, use socat or nginx in addition to websocat until this function is implemented properly.
Pre-built binaries for Linux (usual and musl), Windows, OS X and Android (ARM) are available on the releases page. Most are built without SSL support, so can't connect to secure wss://
websockets, only ws://
.
Limitations
- Replies to WebSocket pings are not tested at all
- Windows not tested at all
- Only partial SSL support.
Full list of specifiers
(available as --long-help
)
-
-
-- Stdin/stdoutRead input from console, print to console. Can be specified only one time.
Aliases:
stdio:
,inetd:
inetd:
also disables logging to stderr (TODO).Example: like
cat(1)
.websocat - -
Example: for inetd mode
websocat inetd: literal:$'Hello, world.\n'
Example: SSH transport
ssh -c ProxyCommand='websocat - ws://myserver/mywebsocket' user@myserver
-
ws://<url>
,wss://<url>
-- WebSocket clientExample: forward port 4554 to a websocket
websocat tcp-l:127.0.0.1:4554 wss://127.0.0.1/some_websocket
-
ws-listen:<spec>
- Listen for websocket connectionsA combining specifier, but given IPv4 address as argument auto-inserts
tcp-l:
Aliases:
listen-ws:
ws-l:
l-ws:
Example:
websocat ws-l:127.0.0.1:8808 -
Example: the same, but more verbose:
websocat ws-l:tcp-l:127.0.0.1:8808 reuse:-
-
inetd-ws:
- Alias ofws-l:inetd:
Example of inetd.conf line:
1234 stream tcp nowait myuser /opt/websocat websocat inetd-ws: tcp:127.0.0.1:22
-
tcp:<hostport>
- connect to specified TCP host and portAliases:
tcp-connect:
,connect-tcp:
,c-tcp:
,tcp-c:
Example: like netcat
websocat - tcp:127.0.0.1:22
Example: IPv6
websocat ws-l:0.0.0.0:8084 tcp:[::1]:22
-
tcp-l:<hostport>
- listen TCP port on specified address Aliases:l-tcp:
tcp-listen:
listen-tcp:
Example: echo server
websocat tcp-l:0.0.0.0:1441 mirror:
-
exec:<program_path> --exec-args <arguments...>
Execute a program (subprocess) directly, without a subshell.
Example: date server
websocat -U ws-l:127.0.0.1:5667 exec:date
Example: pinger
websocat -U ws-l:127.0.0.1:5667 exec:ping --exec-args 127.0.0.1 -c 1
-
sh-c:<command line>
- start subprocess though 'sh -c' orcmd /C
Example: unauthenticated shell
websocat --exit-on-eof ws-l:127.0.0.1:5667 sh-c:'bash -i 2>&1'
-
udp:<hostport>
- send and receive packets to specified UDP socketAliases:
udp-connect:
connect-udp:
c-udp:
udp-c:
-
udp-listen:<hostport>
- bind to socket on host and portAliases:
udp-l:
,l-udp:
,listen-udp:
Note that it is not a multiconnect specifier: entire lifecycle of the UDP socket is the same connection.
Packets get sent to the most recent seen peer. If no peers are seen yet, it waits for the first packet.
File a feature request on Github if you want proper DNS-like request-reply UDP mode here.
-
ws-connect:<spec>
- low-level WebSocket connectorA combining specifier. Underlying specifier is should be after the colon. URL and Host: header being sent are independent from underlying specifier Aliases:
ws-c:
c-ws:
connect-ws:
Example: connect to echo server in more explicit way
websocat --ws-c-uri=ws://echo.websocket.org/ - ws-c:tcp:174.129.224.73:80
-
autoreconnect:<spec>
- Auto-reconnectorRe-establish underlying specifier on any error or EOF
Example: keep connecting to the port or spin 100% CPU trying if it is closed.
websocat - autoreconnect:tcp:127.0.0.1:5445
TODO: implement delays
-
reuse:<spec>
- Reuse one connection for serving multiple clientsBetter suited for unidirectional connections
Example (unreliable): don't disconnect SSH when websocket reconnects
websocat ws-l:[::]:8088 reuse:tcp:127.0.0.1:22
-
threadedstdio:
- Stdin/stdout, spawning a threadLike
-
, but forces threaded mode instead of async mode Use when standard input is notepoll(7)
-able. Replaces-
whenno_unix_stdio
Cargo feature is activated -
mirror:
- Simply copy output to inputSimilar to
exec:cat
. -
open-async:<path>
- Open file for read and write and use it like a socketNot for regular files, see
readfile:
andwritefile:
instead.Example:
websocat - open-async:/dev/null
-
open-fd:<number>
- Use specified file descriptor like a socket -
unix-connect:<path>
- Connect to UNIX socket Aliases:unix:
,connect-unix:
,unix-c:
,c-unix:
-
unix-listen:<path>
- Listen for connections on a UNIX socket Aliases:unix-l:
,listen-unix:
,l-unix:
Example: with nginx
umask 0000 websocat --unlink ws-l:unix-l:/tmp/wstest tcp:[::]:22
Nginx config:
location /ws {{
proxy_read_timeout 7d;
proxy_send_timeout 7d;
#proxy_pass http://localhost:3012;
proxy_pass http://unix:/tmp/wstest;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}}
-
unix-dgram:<path>:<path>
- Send packets to one path, receive from the other -
abstract-connect:<string>
- Connect to Linux abstract-namespaced socketAliases:
abstract-c:
,connect-abstract:
,c-abstract:
,abstract:
-
abstract-listen:<path>
- Listen for connections on Linux abstract-namespaced socketAliases:
abstract-l:
,listen-abstract:
,l-abstract:
-
readfile:<path>
- synchronously read filesBlocking on operations with the file pauses the whole process
Example:
websocat ws-l:127.0.0.1:8000 readfile:hello.json
-
writefile:<path>
- synchronously write filesBlocking on operations with the file pauses the whole process Files are opened in overwrite mode.
Example:
websocat ws-l:127.0.0.1:8000 reuse:writefile:log.txt
TODO:
appendfile:
-
clogged:
- Do nothingDon't read or write any bytes. Keep connections hanging.
-
literal:<string>
- Output a string, discard input.Ignore all input, use specified string as output.
-
literalreply:<string>
- Reply with this string for each input packetExample:
websocat ws-l:127.0.0.1:3456 literalreply:Hello_world
-
assert:<string>
- Check the input.Read entire input and panic the program if the input is not equal to the specified string.
P.S. Here is oneliner to remove non-blocking mode from terminal's stdin:
perl -we 'use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); open F, "<&=", 0; my $flags = fcntl(F, F_GETFL, 0); fcntl(F, F_SETFL, $flags & !O_NONBLOCK);'
Planned features
- Driving SSL server websockets (specifying cert and key)
- Pure Rust version with SSL support?
- SOCK_SEQPACKET mode for
exec:
? - SOCK_SEQPACKET SCTP mode?
- Option for auto
\n
insertion - Add WebRTC's DataChannel to the mix (separate project)?