Command-line client for WebSockets, like netcat (or curl) for ws:// with advanced socat-like functions

Overview

websocat

Netcat, curl and socat for WebSockets.

Build Status Gitter

Examples

Connect to public echo server

$ websocat ws://echo.websocket.org
123
123
ABC
ABC

Serve and connect

A$ websocat -s 1234
Listening on ws://127.0.0.1:1234/
ABC
123

B$ websocat ws://127.0.0.1:1234/
ABC
123

Open a tab in Chromium using remote debugging.

$ chromium --remote-debugging-port=9222&
$ curl -sg http://127.0.0.1:9222/json/new | grep webSocketDebuggerUrl | cut -d'"' -f4 | head -1
ws://127.0.0.1:9222/devtools/page/A331E56CCB8615EB4FCB720425A82259
$ echo 'Page.navigate {"url":"https://example.com"}' | websocat -n1 --jsonrpc ws://127.0.0.1:9222/devtools/page/A331E56CCB8615EB4FCB720425A82259
{"id":2,"result":{"frameId":"A331E56CCB8615EB4FCB720425A82259","loaderId":"EF5AAD19F2F8BB27FAF55F94FFB27DF9"}}

Proxy TCP connections to WebSocket connections and back.

$ websocat --oneshot -b ws-l:127.0.0.1:1234 tcp:127.0.0.1:22&
$ websocat --oneshot -b tcp-l:127.0.0.1:1236 ws://127.0.0.1:1234/&
$ nc 127.0.0.1 1236
SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u3
qwertyu
Protocol mismatch.

Broadcast all messages between connected WebSocket clients

A$ websocat -t ws-l:127.0.0.1:1234 broadcast:mirror:
B$ websocat ws://127.0.0.1:1234
C$ websocat ws://127.0.0.1:1234

See moreexamples.md for further examples.

Features

  • Connecting to and serving WebSockets from command line.
  • Executing external program and making it communicate to WebSocket using stdin/stdout.
  • Text and binary modes, converting between lines (or null-terminated records) and messages.
  • Inetd mode, UNIX sockets (including abstract namespaced on Linux).
  • Integration with Nginx using TCP or UNIX sockets.
  • Directly using unauthenticated SOCKS5 servers for connecting to WebSockets and listening WebSocket connection.
  • Auto-reconnect and connection-reuse modes.
  • Linux, Windows and Mac support, with pre-built executables.
  • Low-level WebSocket clients and servers with overridable underlying transport connection, e.g. calling external program to serve as a transport for websocat (for SSL, proxying, etc.).
  • Buildable by Rust starting from v1.34. Websocats up to version 1.5.0 are buildable by Rust 1.31. Websocat version 1.2.0 (or from a tag) should be buildable by 1.28.0. Websocat version 1.1.0 and earlier should be buildable with Rust v1.23.0. There is legacy non-async version buildable by even older Rust.

Installation

There are multiple options for installing WebSocat. From easy to hard:

  • If you're on Linux Debian or Ubuntu (or other dpkg-based), try downloading a pre-build deb package from GitHub releases and install from GUI or with command like gdebi websocat_..._.deb
  • If you're on Fedora, you can install WebSocat from Copr: sudo dnf copr enable atim/websocat -y && sudo dnf install websocat
  • If you're on FreeBSD, you may install WebSocat with the following command: pkg install websocat.
  • If you're on Mac, you can do brew install websocat.
  • Download a pre-build executable and install it to PATH.
  • Install the Rust toolchain and do cargo install --features=ssl websocat. If something fails with a -sys crate, try without --features=ssl;
  • Build Websocat from source code (see below), then move target/release/websocat somewhere to the PATH.

--help=long output

websocat 1.7.0
Vitaly "_Vi" Shukela <[email protected]>
Command-line client for web sockets, like netcat/curl/socat for ws://.

USAGE:
    websocat ws://URL | wss://URL               (simple client)
    websocat -s port                            (simple server)
    websocat [FLAGS] [OPTIONS] <addr1> <addr2>  (advanced mode)

FLAGS:
        --async-stdio                           [A] On UNIX, set stdin and stdout to nonblocking mode instead of
                                                spawning a thread. This should improve performance, but may break other
                                                programs running on the same console.
        --dump-spec                             [A] Instead of running, dump the specifiers representation to stdout
    -e, --set-environment                       Set WEBSOCAT_* environment variables when doing exec:/cmd:/sh-c:
                                                Currently it's WEBSOCAT_URI and WEBSOCAT_CLIENT for
                                                request URI and client address (if TCP)
                                                Beware of ShellShock or similar security problems.
    -E, --exit-on-eof                           Close a data transfer direction if the other one reached EOF
        --jsonrpc                               Format messages you type as JSON RPC 2.0 method calls. First word
                                                becomes method name, the rest becomes parameters, possibly automatically
                                                wrapped in [].
        --just-generate-key                     [A] Just a Sec-WebSocket-Key value without running main Websocat
        --linemode-strip-newlines               [A] Don't include trailing \n or \r\n coming from streams in WebSocket
                                                messages
    -0, --null-terminated                       Use \0 instead of \n for linemode
        --no-line                               [A] Don't automatically insert line-to-message transformation
        --no-exit-on-zeromsg                    [A] Don't exit when encountered a zero message. Zero messages are used
                                                internally in Websocat, so it may fail to close connection at all.
        --no-fixups                             [A] Don't perform automatic command-line fixups. May destabilize
                                                websocat operation. Use --dump-spec without --no-fixups to discover what
                                                is being inserted automatically and read the full manual about Websocat
                                                internal workings.
        --no-async-stdio                        [A] Inhibit using stdin/stdout in a nonblocking way if it is not a tty
    -1, --one-message                           Send and/or receive only one message. Use with --no-close and/or -u/-U.
        --oneshot                               Serve only once. Not to be confused with -1 (--one-message)
        --exec-sighup-on-stdin-close            [A] Make exec: or sh-c: or cmd: send SIGHUP on UNIX when input is
                                                closed.
        --exec-sighup-on-zero-msg               [A] Make exec: or sh-c: or cmd: send SIGHUP on UNIX when facing incoming
                                                zero-length message.
    -q                                          Suppress all diagnostic messages, except of startup errors
        --reuser-send-zero-msg-on-disconnect    [A] Make reuse-raw: send a zero-length message to the peer when some
                                                clients disconnects.
    -s, --server-mode                           Simple server mode: specify TCP port or addr:port as single argument
    -S, --strict                                strict line/message mode: drop too long messages instead of splitting
                                                them, drop incomplete lines.
    -k, --insecure                              Accept invalid certificates and hostnames while connecting to TLS
        --udp-broadcast                         [A] Set SO_BROADCAST
        --udp-multicast-loop                    [A] Set IP[V6]_MULTICAST_LOOP
        --udp-oneshot                           [A] udp-listen: replies only one packet per client
        --udp-reuseaddr                         [A] Set SO_REUSEADDR for UDP socket. Listening TCP sockets are always
                                                reuseaddr.
    -u, --unidirectional                        Inhibit copying data in one direction
    -U, --unidirectional-reverse                Inhibit copying data in the other direction (or maybe in both directions
                                                if combined with -u)
        --unlink                                [A] Unlink listening UNIX socket before binding to it
    -V, --version                               Prints version information
    -v                                          Increase verbosity level to info or further
    -b, --binary                                Send message to WebSockets as binary messages
    -n, --no-close                              Don't send Close message to websocket on EOF
        --websocket-ignore-zeromsg              [A] Silently drop incoming zero-length WebSocket messages. They may
                                                cause connection close due to usage of zero-len message as EOF flag
                                                inside Websocat.
    -t, --text                                  Send message to WebSockets as text messages
        --base64                                Encode incoming binary WebSocket messages in one-line Base64 If
                                                `--binary-prefix` (see `--help=full`) is set, outgoing WebSocket
                                                messages that start with the prefix are decoded from base64 prior to
                                                sending.
        --base64-text                           [A] Encode incoming text WebSocket messages in one-line Base64. I don't
                                                know whether it can be ever useful, but it's for symmetry with
                                                `--base64`.

OPTIONS:
        --socks5 <auto_socks5>
            Use specified address:port as a SOCKS5 proxy. Note that proxy authentication is not supported yet. Example:
            --socks5 127.0.0.1:9050
        --autoreconnect-delay-millis <autoreconnect_delay_millis>
            [A] Delay before reconnect attempt for `autoreconnect:` overlay. [default: 20]

        --queue-len <broadcast_queue_len>
            [A] Number of pending queued messages for broadcast reuser [default: 16]

    -B, --buffer-size <buffer_size>                                  Maximum message size, in bytes [default: 65536]
    -H, --header <custom_headers>...
            Add custom HTTP header to websocket client request. Separate header name and value with a colon and
            optionally a single space. Can be used multiple times. Note that single -H may eat multiple further
            arguments, leading to confusing errors. Specify headers at the end or with equal sign like -H='X: y'.
        --server-header <custom_reply_headers>...
            Add custom HTTP header to websocket upgrade reply. Separate header name and value with a colon and
            optionally a single space. Can be used multiple times. Note that single -H may eat multiple further
            arguments, leading to confusing errors.
        --exec-args <exec_args>...
            [A] Arguments for the `exec:` specifier. Must be the last option, everything after it gets into the exec
            args list.
        --header-to-env <headers_to_env>...
            Forward specified incoming request header to H_* environment variable for `exec:`-like specifiers.

    -h, --help <help>
            See the help.
            --help=short is the list of easy options and address types
            --help=long lists all options and types (see [A] markers)
            --help=doc also shows longer description and examples.
        --just-generate-accept <just_generate_accept>
            [A] Just a Sec-WebSocket-Accept value based on supplied Sec-WebSocket-Key value without running main
            Websocat
        --max-messages <max_messages>
            Maximum number of messages to copy in one direction.

        --max-messages-rev <max_messages_rev>
            Maximum number of messages to copy in the other direction.

        --conncap <max_parallel_conns>
            Maximum number of simultaneous connections for listening mode

        --origin <origin>                                            Add Origin HTTP header to websocket client request
        --pkcs12-der <pkcs12_der>
            Pkcs12 archive needed to accept SSL connections, certificate and key.
            A command to output it: openssl pkcs12 -export -out output.pkcs12 -inkey key.pem -in cert.pem
            Use with -s (--server-mode) option or with manually specified TLS overlays.
            See moreexamples.md for more info.
        --pkcs12-passwd <pkcs12_passwd>
            Password for --pkcs12-der pkcs12 archive. Required on Mac.

        --request-header <request_headers>...
            [A] Specify HTTP request headers for `http-request:` specifier.

    -X, --request-method <request_method>                            [A] Method to use for `http-request:` specifier
        --request-uri <request_uri>                                  [A] URI to use for `http-request:` specifier
        --restrict-uri <restrict_uri>
            When serving a websocket, only accept the given URI, like `/ws`
            This liberates other URIs for things like serving static files or proxying.
    -F, --static-file <serve_static_files>...
            Serve a named static file for non-websocket connections.
            Argument syntax: <URI>:<Content-Type>:<file-path>
            Argument example: /index.html:text/html:index.html
            Directories are not and will not be supported for security reasons.
            Can be specified multiple times. Recommended to specify them at the end or with equal sign like `-F=...`,
            otherwise this option may eat positional arguments
        --socks5-bind-script <socks5_bind_script>
            [A] Execute specified script in `socks5-bind:` mode when remote port number becomes known.

        --socks5-destination <socks_destination>
            [A] Examples: 1.2.3.4:5678  2600:::80  hostname:5678

        --tls-domain <tls_domain>
            [A] Specify domain for SNI or certificate verification when using tls-connect: overlay

        --udp-multicast <udp_join_multicast_addr>...
            [A] Issue IP[V6]_ADD_MEMBERSHIP for specified multicast address. Can be specified multiple times.

        --udp-multicast-iface-v4 <udp_join_multicast_iface_v4>...
            [A] IPv4 address of multicast network interface. Has to be either not specified or specified the same number
            of times as multicast IPv4 addresses. Order matters.
        --udp-multicast-iface-v6 <udp_join_multicast_iface_v6>...
            [A] Index of network interface for IPv6 multicast. Has to be either not specified or specified the same
            number of times as multicast IPv6 addresses. Order matters.
        --udp-ttl <udp_ttl>                                          [A] Set IP_TTL, also IP_MULTICAST_TTL if applicable
        --protocol <websocket_protocol>
            Specify this Sec-WebSocket-Protocol: header when connecting

        --server-protocol <websocket_reply_protocol>
            Force this Sec-WebSocket-Protocol: header when accepting a connection

        --websocket-version <websocket_version>                      Override the Sec-WebSocket-Version value
        --binary-prefix <ws_binary_prefix>
            [A] Prepend specified text to each received WebSocket binary message. Also strip this prefix from outgoing
            messages, explicitly marking them as binary even if `--text` is specified
        --ws-c-uri <ws_c_uri>
            [A] URI to use for ws-c: overlay [default: ws://0.0.0.0/]

        --ping-interval <ws_ping_interval>                           Send WebSocket pings each this number of seconds
        --ping-timeout <ws_ping_timeout>
            Drop WebSocket connection if Pong message not received for this number of seconds

        --text-prefix <ws_text_prefix>
            [A] Prepend specified text to each received WebSocket text message. Also strip this prefix from outgoing
            messages, explicitly marking them as text even if `--binary` is specified

ARGS:
    <addr1>    In simple mode, WebSocket URL to connect. In advanced mode first address (there are many kinds of
               addresses) to use. See --help=types for info about address types. If this is an address for
               listening, it will try serving multiple connections.
    <addr2>    In advanced mode, second address to connect. If this is an address for listening, it will accept only
               one connection.


Basic examples:
  Command-line websocket client:
    websocat ws://echo.websocket.org/
    
  WebSocket server
    websocat -s 8080
    
  WebSocket-to-TCP proxy:
    websocat --binary ws-l:127.0.0.1:8080 tcp:127.0.0.1:5678
    

Full list of address types:
	ws://           	Insecure (ws://) WebSocket client. Argument is host and URL.
	wss://          	Secure (wss://) WebSocket client. Argument is host and URL.
	ws-listen:      	WebSocket server. Argument is host and port to listen.
	inetd-ws:       	WebSocket inetd server. [A]
	l-ws-unix:      	WebSocket UNIX socket-based server. [A]
	l-ws-abstract:  	WebSocket abstract-namespaced UNIX socket server. [A]
	ws-lowlevel-client:	[A] Low-level HTTP-independent WebSocket client connection without associated HTTP upgrade.
	ws-lowlevel-server:	[A] Low-level HTTP-independent WebSocket server connection without associated HTTP upgrade.
	wss-listen:     	Listen for secure WebSocket connections on a TCP port
	http:           	[A] Issue HTTP request, receive a 1xx or 2xx reply, then pass
	asyncstdio:     	[A] Set stdin and stdout to nonblocking mode, then use it as a communication counterpart. UNIX-only.
	inetd:          	Like `asyncstdio:`, but intented for inetd(8) usage. [A]
	tcp:            	Connect to specified TCP host and port. Argument is a socket address.
	tcp-listen:     	Listen TCP port on specified address.
	ssl-listen:     	Listen for SSL connections on a TCP port
	sh-c:           	Start specified command line using `sh -c` (even on Windows)
	cmd:            	Start specified command line using `sh -c` or `cmd /C` (depending on platform)
	exec:           	Execute a program directly (without a subshell), providing array of arguments on Unix [A]
	readfile:       	Synchronously read a file. Argument is a file path.
	writefile:      	Synchronously truncate and write a file.
	appendfile:     	Synchronously append a file.
	udp:            	Send and receive packets to specified UDP socket, from random UDP port  
	udp-listen:     	Bind an UDP socket to specified host:port, receive packet
	open-async:     	Open file for read and write and use it like a socket. [A]
	open-fd:        	Use specified file descriptor like a socket. [A]
	threadedstdio:  	[A] Stdin/stdout, spawning a thread (threaded version).
	-               	Read input from console, print to console. Uses threaded implementation even on UNIX unless requested by `--async-stdio` CLI option.
	unix:           	Connect to UNIX socket. Argument is filesystem path. [A]
	unix-listen:    	Listen for connections on a specified UNIX socket [A]
	unix-dgram:     	Send packets to one path, receive from the other. [A]
	abstract:       	Connect to UNIX abstract-namespaced socket. Argument is some string used as address. [A]
	abstract-listen:	Listen for connections on a specified abstract UNIX socket [A]
	abstract-dgram: 	Send packets to one address, receive from the other. [A]
	mirror:         	Simply copy output to input. No arguments needed.
	literalreply:   	Reply with a specified string for each input packet.
	clogged:        	Do nothing. Don't read or write any bytes. Keep connections in "hung" state. [A]
	literal:        	Output a string, discard input.
	assert:         	Check the input.  [A]
	assert2:        	Check the input. [A]
	seqpacket:      	Connect to AF_UNIX SOCK_SEQPACKET socket. Argument is a filesystem path. [A]
	seqpacket-listen:	Listen for connections on a specified AF_UNIX SOCK_SEQPACKET socket [A]
Full list of overlays:
	ws-upgrade:     	WebSocket upgrader / raw server. Specify your own protocol instead of usual TCP. [A]
	http-request:   	[A] Issue HTTP request, receive a 1xx or 2xx reply, then pass
	http-post-sse:  	[A] Accept HTTP/1 request. Then, if it is GET,
	ssl-connect:    	Overlay to add TLS encryption atop of existing connection [A]
	ssl-accept:     	Accept an TLS connection using arbitrary backing stream. [A]
	reuse-raw:      	Reuse subspecifier for serving multiple clients: unpredictable mode. [A]
	broadcast:      	Reuse this connection for serving multiple clients, sending replies to all clients.
	autoreconnect:  	Re-establish underlying connection on any error or EOF
	ws-c:           	Low-level WebSocket connector. Argument is a some another address. [A]
	msg2line:       	Line filter: Turns messages from packet stream into lines of byte stream. [A]
	line2msg:       	Line filter: turn lines from byte stream into messages as delimited by '\\n' or '\\0' [A]
	foreachmsg:     	Execute something for each incoming message.
	log:            	Log each buffer as it pass though the underlying connector.
	jsonrpc:        	[A] Turns messages like `abc 1,2` into `{"jsonrpc":"2.0","id":412, "method":"abc", "params":[1,2]}`.
	socks5-connect: 	SOCKS5 proxy client (raw) [A]
	socks5-bind:    	SOCKS5 proxy client (raw, bind command) [A]

Pre-built binaries for Linux (usual and musl), Windows, OS X and Android are available on the releases page.

Building from source code

  1. Install the Rust toolchain
  2. cargo build --release --features=ssl.
  3. Find the executable somewhere under target/, e.g. in target/release/websocat.

SSL on Android

websocat's wss:// may fail on Android. As a workaround, download certificate bundle, for example, from https://curl.haxx.se/ca/cacert.pem and specify it explicitly:

SSL_CERT_FILE=cacert.pem /data/local/tmp/websocat wss://echo.websocket.org

Or just use --insecure option.

Reference

There is a work-in-progress reference document that contains more options and examples.

Some notes

  • IPv6 is supported, surround your IP in square brackets or use it as is, depending on context.
  • Web socket usage is not obligatory, you can use any specs on both sides.
  • Typically one line in binary stream correspond to one WebSocket text message. This is adjustable with options.

Limitations

  • It is not convenient when text and binary WebSocket messages are mixed. This affects mirror: specifier, making it a bit different from ws://echo.websocket.org. There are --binary-prefix, --text-prefix and --base64 options to handle mixture of binary and text.
  • Current version of Websocat don't receive notification about closed sockets. This makes serving without -E or -u options or in backpressure scenarios prone to socket leak.
  • Readline is not integrated. Users are advices to wrap websocat using rlwrap tool for more convenient CLI.
  • Build process of current version of Websocat is not properly automated and is fragile.

See also

Comments
  • race condition when piping and closing

    race condition when piping and closing

    There is a race condition when piping to Websocat : please see this two tests, using Websocat v1.0beta:

    here I received the response, good :

    $ printf  foo | websocat.exe - ws://127.0.0.1:9222/
    {"error":{"code":-32700,"message":"Message must be a valid JSON"}}
    

    here with the same test I did not receive the response :

    $ printf  foo | websocat.exe - ws://127.0.0.1:9222/
    

    if I repeat the test 10 times then only 3 or 4 times I receive the response...

    fiddling with Wireshark I see that the close opcode flag is sent by Websocat sometimes before receiving the response of the server. if the server take time to answer then Websocat will close the connection before receiving the response. is it possible to add a delay for the response, and if no response is received in that delay then close. or maybe there is a better solution?

    NB: using this solution I can close when needed and everything works fine because the race condition can never happen, but I wanted to know if it is possible to make it work with simple pipes. Thank you

    opened by alkorsan 26
  • advice on how to redirect udp multicast messages

    advice on how to redirect udp multicast messages

    I am attempting to redirect broadcast UDP messages to javascript webpage clients.

    My current approach is as follows as follows:

    1. create a named pipe: mkisofs /tmp/pipe
    2. tail the pipe and forward to websocat: tail -f /tmp/pipe | websocat -t -s 10.0.0.1:1234
    3. run a socat command in an infinite loop to receive messages from my base service that publishes UDP broadcast messages and append them to the pipe like this: while true; do socat -t 0 UDP4-RECVFROM:30000,ip-add-membership=224.223.222.221:127.0.0.1,reuseaddr STDOUT >> /tmp/pipe; done

    The issue I'm seeing in my java script webpage is that some messages seem to batch up and arrive in groups while others do not. Messages are JSON arriving once every 4-8 seconds.

    Is there a more straight forward approach I should be using to forward the UDP messages? Any ideas on messages seeming to batch?

    thanks!

    opened by deanhuff 18
  • Output of received messages to stdout truncated to 1024 bytes

    Output of received messages to stdout truncated to 1024 bytes

    Hi, I have a websockets endpoint that outputs messages of around 1500 bytes. When I run websocat ws://my-endpoint the output to my terminal is truncated to 1024 bytes. Then the next message is received, the remaining ~300 bytes of the first message, and the full next message are displayed. Then for the third message, the process repeats, with a truncation to 1024 bytes at first.

    I verified that the websockets data itself is correct via inspection through tcpdump.

    When I pipe the output to a file, the entire message is written to it. When I pipe the output through less, same. When I pipe the output through cat I get the message: cat: write error: Resource temporarily unavailable

    What's an explanation for this behaviour? Could it be related to nonblocking output, e.g. UnixFile::raw_new(std::io::stdout()).set_nonblocking(false);?

    opened by rollulus 16
  • Using websocat as a websocket proxy

    Using websocat as a websocket proxy

    Suppose we would want to create a websocket proxy server using websocat. For instance, client A needs to access ws://somedomain/somewhere. But the websocat to use would be on another computer, acting as a proxy.

    What would be the easiest way to do that using websocat? I think it would necessitate another program that would accept the connection, read the target uri and then instantiate websocat with that target uri and a mirror:. Is there a simpler way?

    opened by grepsuzette 16
  • Authentication support for websocat?

    Authentication support for websocat?

    Hi Vi,

    Is there a way to authenticate with websocat to a websocket? I'm currently using wscat (node) but I'm having trouble backgrounding it (backgrounding wscat makes it crash), so I'm wondering if websocat can do something similair to this:

    wscat -c wss://socket.domain.tld/stream?token=AABBCCDDEEFF --auth user:password
    
    opened by pieterhouwen 14
  • is it possible to send a message without initiating the initial three-way handshake?

    is it possible to send a message without initiating the initial three-way handshake?

    is it possible to send a websocket message without initiating the initial three-way handshake, because the handshake initiate a new tcp stream so the websocket server treat my message in a different scope (environment). the chrome websocket server need the messages to be sent using the same tcp stream. thank you

    opened by alkorsan 14
  • SSH through CDN

    SSH through CDN

    I was following this tutorial: https://kernal.eu/posts/ssh-over-websocket/ Version was the latest linux amd 64 static release. Instead of Cloudflare I tested AWS Cloudfront. If I do a normal site to site connection without CDN then ssh+websocat works. However if I use the CDN in between and on the client do:

    ssh -o "ProxyCommand=/sbin/websocat --binary ws://bla.cloudfront.net/ -vvvvv" [email protected] -vvv

    I get:

    [DEBUG websocat::sessionserve] Serving Stdio to WsClient("ws://d164xsza3zusai.cloudfront.net/") with Options { websocket_text_mode: false, websocket_protocol: None, websoc ket_reply_protocol: None, udp_oneshot_mode: false, udp_broadcast: false, udp_multicast_loop: false, udp_ttl: None, udp_join_multicast_addr: [], udp_join_multicast_iface_v4 : [], udp_join_multicast_iface_v6: [], udp_reuseaddr: false, unidirectional: false, unidirectional_reverse: false, max_messages: None, max_messages_rev: None, exit_on_eof: false, oneshot: false, unlink_unix_socket: false, exec_args: [], ws_c_uri: "ws://0.0.0.0/", linemode_strip_newlines: false, linemode_strict: false, origin: None, custom_h eaders: [], custom_reply_headers: [], websocket_version: None, websocket_dont_close: false, websocket_ignore_zeromsg: false, one_message: false, no_auto_linemode: false, b uffer_size: 65536, broadcast_queue_len: 16, read_debt_handling: Silent, linemode_zero_terminated: false, restrict_uri: None, serve_static_files: [], exec_set_env: false, n o_exit_on_zeromsg: false, reuser_send_zero_msg_on_disconnect: false, process_zero_sighup: false, process_exit_sighup: false, socks_destination: None, auto_socks5: None, so cks5_bind_script: None, tls_domain: None, tls_insecure: false, headers_to_env: [], max_parallel_conns: None, ws_ping_interval: None, ws_ping_timeout: None, request_uri: No ne, request_method: None, request_headers: [], autoreconnect_delay_millis: 20, ws_text_prefix: None, ws_binary_prefix: None, ws_binary_base64: false, ws_text_base64: false } [DEBUG websocat::stdio_peer] get_stdio_peer (async) [DEBUG websocat::stdio_peer] Setting stdin to nonblocking mode [DEBUG websocat::stdio_peer] Setting stdout to nonblocking mode [DEBUG websocat::stdio_peer] Installing signal handler [INFO websocat::ws_client_peer] get_ws_client_peer [DEBUG websocat::stdio_peer] restore_blocking_status [DEBUG websocat::stdio_peer] Restoring blocking status for stdin [DEBUG websocat::stdio_peer] Restoring blocking status for stdout websocat: WebSocketError: Received unexpected status code (400 Bad Request) [DEBUG websocat::stdio_peer] restore_blocking_status [DEBUG websocat::stdio_peer] Restoring blocking status for stdin [DEBUG websocat::stdio_peer] Restoring blocking status for stdout websocat: error running kex_exchange_identification: Connection closed by remote host

    On the remote end:

    sudo websocat --binary ws-l:127.0.0.1:8022 tcp:127.0.0.1:22 -vvv &

    Websocat gives an error:

    [INFO websocat::net_peer] Incoming TCP connection from Some(V4(127.0.0.1:48418)) [DEBUG websocat::sessionserve] Underlying connection established [INFO websocat::sessionserve] Serving 1 ongoing connections [DEBUG websocat::readdebt] Fullfulling the debt of 135 bytes [DEBUG websocat::trivial_peer] LiteralPeer debt [DEBUG websocat::trivial_peer] LiteralPeer finished [DEBUG websocat::my_copy] zero len [DEBUG websocat::my_copy] read_done [DEBUG websocat::my_copy] done websocat: WebSocketError: I/O failure

    From tcpdump I could see:

    0x0070: 616d 617a 6f6e 6177 732e 636f 6d0d 0a43 amazonaws.com..C 0x0080: 6f6e 6e65 6374 696f 6e3a 2075 7067 7261 onnection:.upgra 0x0090: 6465 0d0a 5570 6772 6164 653a 2077 6562 de..Upgrade:.web 0x00a0: 736f 636b 6574 0d0a 5573 6572 2d41 6765 socket..User-Age 0x00b0: 6e74 3a20 416d 617a 6f6e 2043 6c6f 7564 nt:.Amazon.Cloud 0x00c0: 4672 6f6e 740d 0a56 6961 3a20 312e 3120 Front..Via:.1.1. 0x00d0: 6133 3732 6465 3732 6634 6461 6366 3163 a372de72f4dacf1c 0x00e0: 6664 3437 6231 6534 3662 6631 3136 3636 fd47b1e46bf11666 0x00f0: 2e63 6c6f 7564 6672 6f6e 742e 6e65 7420 .cloudfront.net. 0x0100: 2843 6c6f 7564 4672 6f6e 7429 0d0a 582d (CloudFront)..X- 0x0110: 466f 7277 6172 6465 642d 466f 723a 2031 Forwarded-For:.1 0x0120: 332e 3233 332e 3139 382e 3130 310d 0a58 3.233.198.102..X 0x0130: 2d41 6d7a 2d43 662d 4964 3a20 7a6c 3579 -Amz-Cf-Id:.zl5y 0x0140: 4e70 494a 3756 4361 6e39 746f 6162 336c NpIJ7VCan9toab3l 0x0150: 3731 6857 4f4b 326b 3755 5072 3474 726d 71hWOK2k7UPr4trm 0x0160: 6a46 6a65 3871 5679 4e58 7559 7664 6663 jFje8qVyNXuYvdfc 0x0170: 3541 3d3d 0d0a 0d0a 5A==.... 15:33:39.232608 IP 172.26.8.156.80 > 70.132.7.132.28236: Flags [.], ack 325, win 974, options [nop,nop,TS val 3737434823 ecr 2929295091], length 0 0x0000: 4500 0034 a20e 4000 4006 95f7 ac1a 089c E..4..@.@....... 0x0010: 4684 0784 0050 6e4c 184f b2a6 3588 0324 F....PnL.O..5..$ 0x0020: 8010 03ce 02e5 0000 0101 080a dec4 bac7 ................ 0x0030: ae99 7ef3 ..~. 15:33:39.233210 IP 172.26.8.156.80 > 70.132.7.132.28236: Flags [P.], seq 1:230, ack 325, win 974, options [nop,nop,TS val 3737434824 ecr 2929295091], length 229: HTTP: HTT P/1.1 400 Bad Request 0x0000: 4500 0119 a20f 4000 4006 9511 ac1a 089c E.....@.@....... 0x0010: 4684 0784 0050 6e4c 184f b2a6 3588 0324 F....PnL.O..5..$ 0x0020: 8018 03ce 03ca 0000 0101 080a dec4 bac8 ................ 0x0030: ae99 7ef3 4854 5450 2f31 2e31 2034 3030 ..~.HTTP/1.1.400 0x0040: 2042 6164 2052 6571 7565 7374 0d0a 5365 .Bad.Request..Se 0x0050: 7276 6572 3a20 6e67 696e 782f 312e 3138 rver:.nginx/1.18 0x0060: 2e30 2028 5562 756e 7475 290d 0a44 6174 .0.(Ubuntu)..Dat 0x0070: 653a 2054 6875 2c20 3234 2044 6563 2032 e:.Thu,.24.Dec.2 0x0080: 3032 3020 3135 3a33 333a 3339 2047 4d54 020.15:33:39.GMT 0x0090: 0d0a 436f 6e74 656e 742d 5479 7065 3a20 ..Content-Type:. 0x00a0: 7465 7874 2f70 6c61 696e 0d0a 5472 616e text/plain..Tran 0x00b0: 7366 6572 2d45 6e63 6f64 696e 673a 2063 sfer-Encoding:.c 0x00c0: 6875 6e6b 6564 0d0a 436f 6e6e 6563 7469 hunked..Connecti 0x00d0: 6f6e 3a20 6b65 6570 2d61 6c69 7665 0d0a on:.keep-alive.. 0x00e0: 0d0a 3263 0d0a 4f6e 6c79 2057 6562 536f ..2c..Only.WebSo 0x00f0: 636b 6574 2063 6f6e 6e65 6374 696f 6e73 cket.connections 0x0100: 2061 7265 2077 656c 636f 6d65 2068 6572 .are.welcome.here

    For whatever reason, I get a 400 Bad Request error through the CDN.

    Any ideas what could be the issue or how to debug this further?

    opened by karnal222 12
  • Skip SSL/TLS verification?

    Skip SSL/TLS verification?

    I was looking for something similar to curl -k option that lets you test a HTTPS endpoint even if you cannot verify the certificate. This is very useful for debug scenarios. Unfortunately I can't seem to find such an option if it exists.

    opened by plombardi89 12
  • version v1.0.0-alpha have problems when parsing the args

    version v1.0.0-alpha have problems when parsing the args

    Hi, First I want to thank you for this gem. thank you very much.

    The new version v1.0.0-alpha can't parse the args well, the old version 0.4 works well!. I m using cygwin in windows 7.

    using this exemple : https://stackoverflow.com/questions/48912184/wscat-commands-from-script-how-to-pass/48914019#48914019

    #!/usr/bin/env bash
    
    runscript() {
      commands=( "first command" "second command" "third command" )
    
      for command in "${commands[@]}"; do
        echo "Writing command to server" >&2
        echo "$command"
        echo "Reading response from server (assuming exactly one line)" >&2
        read -r line
        echo "Received response: $line" >&2
      done
    
      # kill websocat, even if the websocket doesn't get closed
      kill "$PPID"
    }
    
    export -f runscript
    

    the new version gaves this error

    $ ./websocat_nossl_1.0_i686-pc-windows-gnu.exe ws://echo.websocket.org sh-c:'exec bash -c runscript'
    'exec' is not recognized as an internal or external command,
    operable program or batch file.
    

    using the old version 0.4 everything works fine:

    $ ./websocat_nossl_0.4_i686-pc-windows-gnu.exe ws://echo.websocket.org sh-c:'exec bash -c runscript'
    INFO:websocat: Connecting to ws://echo.websocket.org/
    INFO:websocat: Validating response...
    INFO:websocat: Successfully connected
    Writing command to server
    Reading response from server (assuming exactly one line)
    Received response: first command
    Writing command to server
    Reading response from server (assuming exactly one line)
    Received response: second command
    Writing command to server
    Reading response from server (assuming exactly one line)
    Received response: third command
    environment: line 9: kill: (1) - No such process
    The pipe is being closed. (os error 232)
    
    

    the version 0.5 too have problems, but seems a different error:

    $ ./websocat-0.5.1--windows.exe ws://echo.websocket.org sh-c:'exec bash -c runscript'
    websocat: WebSocketError: WebSocket URL failure
    

    thank you.

    opened by alkorsan 12
  • Proposal: make it a stress test tool

    Proposal: make it a stress test tool

    Hi @vi

    first of all, congrats and thanks for this project, it's interesting and I see a lot of potential. Namely, the are not many options to stress test a websocket service (at least my searches did not lead to many options). websocat can be automated with some scripting but it's a bit impractical. I think that it could deliver better with some additional features. For example, make it behave a little bit like ab:

    $ websocat -n 5000 -c 200 -t 60 ws://localhost:1234

    -n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make at a time
    -t timelimit    Seconds to max. to spend on benchmarking
    

    What do you think?

    opened by apiraino 11
  • Feature request: overlay to split stream on upon custom tokens

    Feature request: overlay to split stream on upon custom tokens

    At the moment I have the need to forward XML documents from a TCP stream to a WebSocket port (unidirectionally). Each document shall result in a separate WebSocket packet. Unfortunately this currently doesn't work with websocat, as it basically converts each TCP packet into a WebSocket packet. But as TCP is stream-based and WebSocket in contrast packet-based, for example these two cases can (and do) happen here:

    • a TCP packet only consists of a part of an XML document (happens when documents are larger than the IP packet size, which is the case here)
    • a TCP packet consists of more than one XML document

    This requires to somehow buffer/split the received stream, in order to forward distinct XML documents.

    It seems to me that a generalized version of the line2packet overlay would be great for that. In the case of such an overlay, one would e.g. need to specifiy a token (instead of having CR/LF hardcoded) that would correspond to the end of the document. So the stream is splitted always when that token is found in the stream. In the XML case this would be the closing root element, e.g. </test>. Note that in contrast to the line2packet overlay, the token would not be discarded, but forwarded as well (an additional option could be added to toggle that).

    However as in XML namespaces are important, one token to match would not be sufficient here. In theory it would have to be considered, which prefix the namespace of the root element uses - but of course this would be way to complex/out of scope here. However in the present case it would be sufficient to simply assume that either no namespace prefix (e.g. </test>) or a specific namespace prefix (e.g. </abc:test/>) is used. Hence it would be necessary to be able to match against more than one token here.

    To initially solve this, I extended copy<R, W> myself, but this is only a custom quick and dirty hardcoded solution (as I'm not yet that familiar with Rust). So it would be great if there would be a generalized way to do such splitting in websocat itself.

    opened by spoeschel 10
  • Broken when running against solana-test-validator

    Broken when running against solana-test-validator

    Seems to fail when using localhost versus a direct ip

    # localhost fails
    ➜  ~ websocat -v ws://localhost:8900/
    [INFO  websocat::lints] Auto-inserting the line mode
    [INFO  websocat::stdio_threaded_peer] get_stdio_peer (threaded)
    [INFO  websocat::ws_client_peer] get_ws_client_peer
    websocat: WebSocketError: I/O failure
    websocat: error running
    
    
    # ip works
    ➜  ~ websocat -v ws://127.0.0.1:8900/
    [INFO  websocat::lints] Auto-inserting the line mode
    [INFO  websocat::stdio_threaded_peer] get_stdio_peer (threaded)
    [INFO  websocat::ws_client_peer] get_ws_client_peer
    [INFO  websocat::ws_client_peer] Connected to ws
    

    Platform

    Arch linux
    5.15.82-1-lts
    websocat 1.11.0
    solana-test-validator 1.14.10 (src:df128573; feat:3036606309)
    
    
    opened by esemeniuc 2
  • Support HTTP Redirection at Handshake

    Support HTTP Redirection at Handshake

    Hi!

    I like to request that the server can send a http redirect (3xx) and websocat allows to handle this.

    It seems WebSocket allows this: https://www.rfc-editor.org/rfc/rfc6455

    1.  If the status code received from the server is not 101, the
           client handles the response per HTTP [[RFC2616](https://www.rfc-editor.org/rfc/rfc2616)] procedures.  In
           particular, the client might perform authentication if it
           receives a 401 status code; the server might redirect the client
           using a 3xx status code (but clients are not required to follow
           them), etc.  Otherwise, proceed as follows.
    
    opened by misery 1
  • fix: correct a few typos, mostly in user facing strings

    fix: correct a few typos, mostly in user facing strings

    Hi Vitaly

    While skimming through the codebase, looking to discover how hard it would be to implement Socket.io support as you mentioned in https://github.com/vi/websocat/issues/21#issuecomment-439129842, I stumbled upon a few typos.

    So here's a quick PR with the ones I found.

    Thanks for this great tool.

    opened by Delapouite 1
  • Websocat server with base64 encoded file

    Websocat server with base64 encoded file

    My issue is that I cannot serve a base64 file created with websocat, so that I can receive it as binary again.

    After creating a file with the command

    $ websocat_win64.exe --base64 --binary ws://127.0.0.1:8080 > my.b64

    I try to serve the file:

    $ websocat_win64.exe --base64 --binary ws-listen:127.0.0.1:8081 readfile:my.b64
    websocat: Unfortunately, serving multiple clients without --exit-on-eof (-E) or with -U option is prone to socket leak in this websocat version
    [ERROR websocat::ws_peer] Failed to decode user-supplised base64 buffer. Sending message as is.
    [ERROR websocat::ws_peer] Failed to decode user-supplised base64 buffer. Sending message as is.
    

    (The last error is repeated numerous times)

    I was expecting to receive the data in the file after base64 decoding, in binary served to my own client program but am receiving the base 64 text.

    The line length of the base 64 file is between 50 and 800KB.

    opened by LatentLag 4
  • handshake with text and then pipe binary output to ffmpeg

    handshake with text and then pipe binary output to ffmpeg

    Hello! Thanx for the great tool!

    I have a question. I have following scenario to do:

    1. open wss connection
    2. send 'hello' text to socket
    3. receive some text from socket
    4. send 'start' text to socket
    5. start receiving binary data from socket and need to pipe this to FFmpeg

    I tried all possible combinations ) but no luck. one message to socket work ok, but two is not working (

    is it possible to achieve at all?

    opened by cleoag 1
Releases(v1.11.0)
Owner
Vitaly Shukela
Vitaly Shukela
Lightweight, event-driven WebSockets for Rust.

WS-RS Lightweight, event-driven WebSockets for Rust. /// A WebSocket echo server listen("127.0.0.1:3012", |out| { move |msg| { out.send(ms

Jason Housley 1.3k Jan 8, 2023
Synchronized state machines for Rust over WebSockets.

Aper is a framework for real-time sharing of application state over WebSockets.

null 191 Dec 20, 2022
Rust + wasm + websockets

This is a template repo for eframe, a framework for writing apps using egui.

Emil Ernerfeldt 12 Oct 3, 2022
Clearly a repo about websockets and their comparison...

Tags Go vs Typescript: Video 1 of the series is tag go-vs-ts-video-1 Current Project Video 2 and 3 are going to be likely Go vs Rust vs Typescript, bu

ThePrimeagen 344 Dec 31, 2022
Composable WebSockets made easy, for Rust 🦀

ezsockets Have you ever struggle with creating a WebSocket server or a client in Rust? This crate is for you. High level abstraction of WebSocket, han

Grzegorz Baranski 55 Dec 30, 2022
😎 A custom invoke system for Tauri that leverages WebSockets

?? tauri-awesome-rpc This is a crate provides a custom invoke system for Tauri using a localhost JSON RPC WebSocket. Each message is delivered through

Victor Aremu 20 Dec 2, 2022
Rust API connector for Bybit's WebSockets APIs.

rust-bybit English | 简体中文 Unofficial Rust API connector for Bybit's WebSockets APIs. Disclaimer This is an unofficial Rust API connector for Bybit's A

yufuquant 12 Nov 12, 2022
A MITM Proxy Written in Rust 🦀! Toolkit for HTTP/1, HTTP/2, and WebSockets with SSL/TLS Capabilities. Learning Project.

Man In The Middle Proxy Description Rust-based Man in the Middle proxy, an early-stage project aimed at providing visibility into network traffic. Cur

null 158 Mar 9, 2023
notiflux - subscribe over WebSockets, publish over REST

notiflux notiflux is a pub/sub server where clients subscribe over a WebSocket and messages are broadcast over a POST request How does it work? Client

Axel Örn Sigurðsson 3 Apr 9, 2024
A simple toy websocket client to connect to Bitstamp.net and print the live order book written in Rust.

A simple toy websocket client to connect to Bitstamp.net and print the live order book written in Rust.

Nate Houk 1 Feb 14, 2022
websocket client

#websocket client async fn test_websocket()->anyhow::Result<()> { wasm_logger::init(wasm_logger::Config::default()); let (tx, rx) = futures_c

null 1 Feb 11, 2022
"Last Mile" streaming server and client

TSLM - Terminal Stream Last Mile This is an asynchronous WebSocket server written in Rust using tokio-tungstenite. It allows a WebSocket client to per

null 4 Nov 9, 2023
Custom implementation of Curl - Build Your Own curl

Build Your Own curl We are going to build curl from scratch by accepting the coding challenge posted on Coding Challenges FYI. Before moving ahead, yo

Praveen Chaudhary 15 Jun 7, 2024
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
MPNC: Multipath single-Player NetCat

MPNC: Multipath single-Player NetCat TL;DR: A PoC to make your link aggregation works. Background We all know NC is useful in real world: # on server

Silver Bullet 1 Feb 6, 2022
Convert curl command to a ParsedRequest

CURL Parser Nowadays, most of the APIs provide CURL examples to allow users to try out the APIs without any entry barriers, but it takes time to diges

Tyr Chen 14 Apr 14, 2023
rurl is like curl but with a json configuration file per request

rurl rurl is a curl-like cli tool made in rust, the difference is that it takes its params from a json file so you can have all different requests sav

Bruno Ribeiro da Silva 6 Sep 10, 2022
A command-line tool for exposing a wrapped program's standard IO using WebSockets/SSE

cmdpiped cmdpiped is a command-line tool for exposing a wrapped cli program's standard IO to WebSockets/SSE Installation Ready to use Binaries are ava

Geoffrey Mureithi 10 Nov 11, 2022
A curl(libcurl) mod for rust.

curl Master Dev A lightweight Curl-wrapper for using (mostly) HTTP from Rust. While there are a couple of Rust HTTP libraries like rust-http and its s

Valerii Hiora 2 Sep 14, 2016