diff --git a/README.md b/README.md index 47839b9..9613087 100644 --- a/README.md +++ b/README.md @@ -89,10 +89,10 @@ There are multiple options for installing WebSocat. From easy to hard: * Install the [Rust toolchain](https://rustup.rs/) 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. -## Usage +## `--help=long` output ``` -websocat 1.5.0 +websocat 1.7.0 Vitaly "_Vi" Shukela Command-line client for web sockets, like netcat/curl/socat for ws://. @@ -102,7 +102,10 @@ USAGE: websocat [FLAGS] [OPTIONS] (advanced mode) FLAGS: - (some flags are hidden, see --help=long) + --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) @@ -111,29 +114,67 @@ FLAGS: --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: - (some options are hidden, see --help=long) --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 + [A] Delay before reconnect attempt for `autoreconnect:` overlay. [default: 20] - -B, --buffer-size Maximum message size, in bytes [default: 65536] + --queue-len + [A] Number of pending queued messages for broadcast reuser [default: 16] + + -B, --buffer-size Maximum message size, in bytes [default: 65536] -H, --header ... 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 @@ -142,21 +183,43 @@ OPTIONS: 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 ... + [A] Arguments for the `exec:` specifier. Must be the last option, everything after it gets into the exec + args list. --header-to-env ... Forward specified incoming request header to H_* environment variable for `exec:`-like specifiers. + -h, --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. - --conncap Maximum number of simultaneous connections for listening mode - --origin Add Origin HTTP header to websocket client request + --just-generate-accept + [A] Just a Sec-WebSocket-Accept value based on supplied Sec-WebSocket-Key value without running main + Websocat + --max-messages + Maximum number of messages to copy in one direction. + + --max-messages-rev + Maximum number of messages to copy in the other direction. + + --conncap + Maximum number of simultaneous connections for listening mode + + --origin Add Origin HTTP header to websocket client request --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 Password for --pkcs12-der pkcs12 archive. Required on Mac. + --pkcs12-passwd + Password for --pkcs12-der pkcs12 archive. Required on Mac. + + --request-header ... + [A] Specify HTTP request headers for `http-request:` specifier. + + -X, --request-method [A] Method to use for `http-request:` specifier + --request-uri [A] URI to use for `http-request:` specifier --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. @@ -167,17 +230,45 @@ OPTIONS: 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 + [A] Execute specified script in `socks5-bind:` mode when remote port number becomes known. + + --socks5-destination + [A] Examples: 1.2.3.4:5678 2600:::80 hostname:5678 + + --tls-domain + [A] Specify domain for SNI or certificate verification when using tls-connect: overlay + + --udp-multicast ... + [A] Issue IP[V6]_ADD_MEMBERSHIP for specified multicast address. Can be specified multiple times. + --udp-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 ... + [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 [A] Set IP_TTL, also IP_MULTICAST_TTL if applicable + --protocol + Specify this Sec-WebSocket-Protocol: header when connecting - --protocol Specify this Sec-WebSocket-Protocol: header when connecting --server-protocol Force this Sec-WebSocket-Protocol: header when accepting a connection - --websocket-version Override the Sec-WebSocket-Version value - --ping-interval Send WebSocket pings each this number of seconds + --websocket-version Override the Sec-WebSocket-Version value + --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 + [A] URI to use for ws-c: overlay [default: ws://0.0.0.0/] + + --ping-interval Send WebSocket pings each this number of seconds --ping-timeout Drop WebSocket connection if Pong message not received for this number of seconds + --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: In simple mode, WebSocket URL to connect. In advanced mode first address (there are many kinds of @@ -198,37 +289,69 @@ Basic examples: websocat --binary ws-l:127.0.0.1:8080 tcp:127.0.0.1:5678 -Partial list of address types: +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 - stdio: Same as `-`. Read input from console, print to console. + 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. -Partial list of overlays: + 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](https://github.com/vi/websocat/releases). -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. Building from source code --- @@ -255,15 +378,17 @@ There is a work-in-progress [reference document](doc.md) that contains more opti Some notes --- -* It runs singlethreaded, but can serve multiple connections simultaneously. There is old non-async threaded version in `legacy` branch of releases prior to 0.5. * 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. -Planned features +Limitations --- -There are also checkboxes on issues [#1](https://github.com/vi/websocat/issues/1) and [#5](https://github.com/vi/websocat/issues/5). +* 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`](https://linux.die.net/man/1/rlwrap) tool for more convenient CLI. +* Build process of current version of Websocat is not properly automated and is fragile. See also --- diff --git a/doc.md b/doc.md index 6b2a302..ff0ade9 100644 --- a/doc.md +++ b/doc.md @@ -29,7 +29,7 @@ Some address types may be "aliases" to other address types or combinations of ov ``` -websocat 2.0.0-alpha0 +websocat 1.7.0 Vitaly "_Vi" Shukela Command-line client for web sockets, like netcat/curl/socat for ws://. @@ -39,6 +39,9 @@ USAGE: websocat [FLAGS] [OPTIONS] (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 @@ -53,12 +56,13 @@ FLAGS: 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 + --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 @@ -89,11 +93,21 @@ FLAGS: 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 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 + [A] Delay before reconnect attempt for `autoreconnect:` overlay. [default: 20] + --queue-len [A] Number of pending queued messages for broadcast reuser [default: 16] @@ -139,13 +153,10 @@ OPTIONS: Password for --pkcs12-der pkcs12 archive. Required on Mac. --request-header ... - Specify HTTP request headers TODO: add short option, remove existing -H - Note: this is option for not-yet-finished websocat 2.0. Beware of confusion. + [A] Specify HTTP request headers for `http-request:` specifier. -X, --request-method [A] Method to use for `http-request:` specifier - Note: this is option for not-yet-finished websocat 2.0. Beware of confusion. --request-uri [A] URI to use for `http-request:` specifier - Note: this is option for not-yet-finished websocat 2.0. Beware of confusion. --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. @@ -182,6 +193,9 @@ OPTIONS: Force this Sec-WebSocket-Protocol: header when accepting a connection --websocket-version Override the Sec-WebSocket-Version value + --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 [A] URI to use for ws-c: overlay [default: ws://0.0.0.0/] @@ -189,6 +203,9 @@ OPTIONS: --ping-timeout Drop WebSocket connection if Pong message not received for this number of seconds + --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: In simple mode, WebSocket URL to connect. In advanced mode first address (there are many kinds of @@ -290,7 +307,6 @@ Internal name for --dump-spec: WsLlClient [A] Low-level HTTP-independent WebSocket client connection without associated HTTP upgrade. -Note: this is option for not-yet-finished websocat 2.0. Beware of confusion. Example: TODO @@ -302,7 +318,6 @@ Internal name for --dump-spec: WsLlServer [A] Low-level HTTP-independent WebSocket server connection without associated HTTP upgrade. -Note: this is option for not-yet-finished websocat 2.0. Beware of confusion. Example: TODO @@ -335,22 +350,20 @@ Content you write becomes body, content you read is body that server has sent. URI is specified inline. -Note: this is option for not-yet-finished websocat 2.0. Beware of confusion. - Example: websocat -b - http://example.com < /dev/null -### `stdio:` +### `asyncstdio:` -Aliases: `-` -Internal name for --dump-spec: Stdio +Internal name for --dump-spec: AsyncStdio -Same as `-`. Read input from console, print to console. +[A] Set stdin and stdout to nonblocking mode, then use it as a communication counterpart. UNIX-only. +May cause problems with programs running at the same terminal. This specifier backs the `--async-stdio` CLI option. -This specifier can be specified only one time. +Typically this specifier can be specified only one time. Example: simulate `cat(1)`. This is an exception from "only one time" rule above: @@ -358,7 +371,7 @@ Example: simulate `cat(1)`. This is an exception from "only one time" rule above Example: SSH transport - ssh -c ProxyCommand='websocat - ws://myserver/mywebsocket' user@myserver + ssh -c ProxyCommand='websocat asyncstdio: ws://myserver/mywebsocket' user@myserver ### `inetd:` @@ -366,7 +379,7 @@ Example: SSH transport Internal name for --dump-spec: Inetd -Like `stdio:`, but intented for inetd(8) usage. [A] +Like `asyncstdio:`, but intented for inetd(8) usage. [A] Automatically enables `-q` (`--quiet`) mode. @@ -571,13 +584,32 @@ Example: Serve random data to clients v2 Internal name for --dump-spec: ThreadedStdio -Stdin/stdout, spawning a thread. [A] +[A] Stdin/stdout, spawning a thread (threaded version). Like `-`, but forces threaded mode instead of async mode Use when standard input is not `epoll(7)`-able or you want to avoid setting it to nonblocking mode. +### `-` + +Aliases: `stdio:` +Internal name for --dump-spec: Stdio + + +Read input from console, print to console. Uses threaded implementation even on UNIX unless requested by `--async-stdio` CLI option. + +Typically this specifier can be specified only one time. + +Example: simulate `cat(1)`. This is an exception from "only one time" rule above: + + websocat - - + +Example: SSH transport + + ssh -c ProxyCommand='websocat - ws://myserver/mywebsocket' user@myserver + + ### `unix:` Aliases: `unix-connect:`, `connect-unix:`, `unix-c:`, `c-unix:` @@ -833,13 +865,29 @@ Content you write becomes body, content you read is body that server has sent. URI is specified using a separate command-line parameter -Note: this is option for not-yet-finished websocat 2.0. Beware of confusion. - Example: websocat -Ub - http-request:tcp:example.com:80 --request-uri=http://example.com/ --request-header 'Connection: close' +### `http-post-sse:` + +Internal name for --dump-spec: HttpPostSse + + +[A] Accept HTTP/1 request. Then, if it is GET, +unidirectionally return incoming messages as server-sent events (SSE). + +If it is POST then, also unidirectionally, write body upstream. + +Example - turn SSE+POST pair into a client WebSocket connection: + + websocat -E -t http-post-sse:tcp-l:127.0.0.1:8080 reuse:ws://127.0.0.1:80/websock + +`curl -dQQQ http://127.0.0.1:8080/` would send into it and +`curl -N http://127.0.0.1:8080/` would recv from it. + + ### `ssl-connect:` Aliases: `ssl-c`, `ssl:`, `tls:`, `tls-connect:`, `c-ssl:`, `connect-ssl:`, `c-tls:`, `connect-tls:` @@ -1002,6 +1050,21 @@ Example: This keeps only recent incoming message in file and discards earlier messages. +### `log:` + +Internal name for --dump-spec: Log + + +Log each buffer as it pass though the underlying connector. + +If you increase the logging level, you will also see hex buffers. + +Example: view WebSocket handshake and traffic on the way to echo.websocket.org + + websocat -t - ws-c:log:tcp:127.0.0.1:1080 --ws-c-uri ws://echo.websocket.org + + + ### `jsonrpc:` Internal name for --dump-spec: JsonRpc diff --git a/moreexamples.md b/moreexamples.md index 9555f7f..0673e96 100644 --- a/moreexamples.md +++ b/moreexamples.md @@ -183,3 +183,75 @@ location /mywebsocket { proxy_set_header Connection \"upgrade\"; } ``` + +# Debugging connection issues by dumping traffic. + +If you want to log information that is passing though Websocat to console, you can use `log:` filter (overlay). + +This allows inspecting traffic at various levels. For Websocat versions earlier than 1.7, you can use `ws-c:cmd:` trick instead. + +Example sessions: + +## At message level + +``` +$ websocat -t - --ws-c-uri=wss://echo.websocket.org log:ws-c:ssl:tcp:echo.websocket.org:443 +[WARN websocat::ssl_peer] Connected to TLS without proper verification of certificate. Use --tls-domain option. +asdf +WRITE 5 "asdf\n" +READ 5 "asdf\n" +asdf +12345 +WRITE 6 "12345\n" +READ 6 "12345\n" +12345 +``` + +## At HTTP and Websocket protocol level + +``` +$ websocat -t - --ws-c-uri=wss://echo.websocket.org ws-c:log:ssl:tcp:echo.websocket.org:443 +[WARN websocat::ssl_peer] Connected to TLS without proper verification of certificate. Use --tls-domain option. +WRITE 157 "GET / HTTP/1.1\r\nHost: echo.websocket.org\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: lnQ/ReYmkEBvBVajdASTHg==\r\n\r\n" +READ 201 "HTTP/1.1 101 Web Socket Protocol Handshake\r\nConnection: Upgrade\r\nDate: Sun, 21 Feb 2021 20:59:59 GMT\r\nSec-WebSocket-Accept: uZ5OAMgIFtQE5WRsqRRlA+DM0UI=\r\nServer: Kaazing Gateway\r\nUpgrade: websocket\r\n\r\n" +ABCDE +WRITE 12 "\x81\x86\xd6\xa90\x97\x97\xebs\xd3\x93\xa3" +READ 8 "\x81\x06ABCDE\n" +ABCDE +56789 +WRITE 12 "\x81\x86\x8aH\xe8b\xbf~\xdfZ\xb3B" +READ 8 "\x81\x0656789\n" +56789 +WRITE 6 "\x88\x80u\xbfoz" +READ 2 "\x88\x00" +``` + +## At TCP stream level + +``` +$ websocat -t - --ws-c-uri=wss://echo.websocket.org --tls-domain=echo.websocket.org ws-c:ssl:log:tcp:echo.websocket.org:443 +WRITE 517 "\x16\x03\x01\x02\x00\x01\x00\x01\xfc\x03\x03\x0e(r\xec\xbbXr\xacb\xe2\x0b+\x0f\xdc\xfa\x17\xb7R`\x1e\xda\xb42e\xd7\xf2\xdd\xd24O;\xd9 Y\t2\xe9kI\xa5I\xd4\xee)p6\xd6\xbf\x8dE:`\xe8]\x7fVN\x9e\x10\xe4\x7f8\xa2:\x98\x00>\x13\x02\x13\x03\x13\x01\xc0,\xc00\x00\x9f\xcc\xa9\xcc\xa8\xcc\xaa\xc0+\xc0/\x00\x9e\xc0$\xc0(\x00k\xc0#\xc0\'\x00g\xc0\n\xc0\x14\x009\xc0\t\xc0\x13\x003\x00\x9d\x00\x9c\x00=\x00<\x005\x00/\x00\xff\x01\x00\x01u\x00\x00\x00\x17\x00\x15\x00\x00\x12echo.websocket.org\x00\x0b\x00\x04\x03\x00\x01\x02\x00\n\x00\x0c\x00\n\x00\x1d\x00\x17\x00\x1e\x00\x19\x00\x18\x00#\x00\x00\x00\x16\x00\x00\x00\x17\x00\x00\x00\r\x000\x00.\x04\x03\x05\x03\x06\x03\x08\x07\x08\x08\x08\t\x08\n\x08\x0b\x08\x04\x08\x05\x08\x06\x04\x01\x05\x01\x06\x01\x03\x03\x02\x03\x03\x01\x02\x01\x03\x02\x02\x02\x04\x02\x05\x02\x06\x02\x00+\x00\t\x08\x03\x04\x03\x03\x03\x02\x03\x01\x00-\x00\x02\x01\x01\x003\x00&\x00$\x00\x1d\x00 \xa0t\xa8\x9d\xd8t\x06E\x94\xba+\xa7\xcf\x90**W\x8dS\xd1\xf4\xd4\xf7\x06\xda\xa4B\x9e\xeb\xa4\xf3\x10\x00\x15\x00\xc1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +READ 5 "\x16\x03\x03\n\x00" +READ 2560 "\x02\x00\x00M\x03\x03`2\xca\x95\x17H\xaa\x9f\x7fz[O>\x0e\xc8x\xd9\x8d\xe71\xac\xffJ\xb8\xd8\x8d\xe4LB2\xee\x80 `2\xca\x95\x93;2\xdc\x04@;T\xc23Ei\x8ax\xfa\xb8y\x12\'\x05(\xce8|^Fv\x97\x00/\x00\x00\x05\xff\x01\x00\x01\x00\x0b\x00\t\xa7\x00\t\xa4\x00\x0550\x82\x0510\x82\x04\x19\xa0\x03\x02\x01\x02\x02\x12\x04\x00\xd5\xa4Naq\xe3S\xeb\xc7\xc8\x82\xb3g\xc5\xdeq0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00021\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x160\x14\x06\x03U\x04\n\x13\rLet\'s Encrypt1\x0b0\t\x06\x03U\x04\x03\x13\x02R30\x1e\x17\r210104172430Z\x17\r210404172430Z0\x181\x160\x14\x06\x03U\x04\x03\x13\rwebsocket.org0\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xa56O\xbfj\xb6\'\x8a<#\xcf\xce=\x1d\xb4\x1d\x0fI\xffW\\\xd9\xdb\xack\xd3\xed;\xc4?7\x8d)\x1bOf\xf4\xfd\xefw\xdb\xbb\xf6\x9cN\xf4-\x1a.8Th\xa0q\xfe\xf5\xb0\xcf\x9f/\x14\xb4\xbb \xb8\xfd\xd24Yg?}\xd5L\xde\x07\x00\x04i0\x82\x04e0\x82\x03M\xa0\x03\x02\x01\x02\x02\x10@\x01u\x04\x83\x14\xa4\xc8!\x8c\x84\xa9\x0c\x16\xcd\xdf0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000?1$0\"\x06\x03U\x04\n\x13\x1bDigital Signature Trust Co.1\x170\x15\x06\x03U\x04\x03\x13\x0eDST Root CA X30\x1e\x17\r201007192140Z\x17\r210929192140Z021\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x160\x14\x06\x03U\x04\n\x13\rLet\'s Encrypt1\x0b0\t\x06\x03U\x04\x03\x13\x02R30\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xbb\x02\x15(\xcc\xf6\xa0\x94\xd3\x0f\x12\xec\x8dU\x92\xc3\xf8\x82\xf1\x99\xa6zB\x88\xa7]&\xaa\xb5+\xb9\xc5L\xb1\xaf\x8ek\xf9u\xc8\xa3\xd7\x0fG\x94\x14U5W\x8c\x9e\xa8\xa29\x19\xf5\x820P\xd067\xdfBM\xf0\xd7r\x13`\x8e\x88=\xd0\x9a\xf8\xfe\x0c\x01~\xb8\x87I\xa5\xcc\x15s\x95\"\xa1\xdb>3m4\x92j&\xa6_r\x96\xa0v\xfa\x12\x14WH\xfd\xa6\xa5\x8dY\xfa\xd6(\xa3\xafT\x18\xca8\xb8E\xc2a\xb7l\x1e\xd75\x80_\xb3\x14}S\xa2\x1d\x98\xc4y\x80W\xf6\xb3&\xdf9\x84O9~\xbfd\xd2\xd7/\xb7U\xe1~\xcb6\x8a\xf2\x07\x07\xc1\xb3\xf1L\x14\xa3\x0c\xb2\xf0(\x99\xa3;\xff[\x1d\xa3p\xe2\xe9\x9cZ5\xaa\xe3\xf0\xa4\xb28\xac\x82e\xb9\x82\xfcz\xbf0\x1f\xce\x9f\x9d\xcb\x94\x7f\xc7\xb8\x8fH$\xdcj+\xfe\xb7z\x9b\xe0\xf0\xd4\xdct\xa7\xe7W\x92A\xa1e8\xc7\x14\x03\x03\x00\x01\x01\x16\x03\x03\x00@\xbb\x00\xba\x14\xcc\xa1\xa2@w mP=\xd3T\xaf\"\xe6M!\xa8\xe8A\xbb[\xafx\xbeDU}\xe1/\x8b\x0e\x8b\x8a\xe6\x82\x06\xe5bHy\xbcq{ \xdb\xb3o\xae\xb1\x03\x9e\xa6\xcf\x19\xee\xf9\x9b\xb3@0" +READ 5 "\x14\x03\x03\x00\x01" +READ 1 "\x01" +READ 5 "\x16\x03\x03\x00@" +READ 64 "\\0\xa6\xfb\x9fcks\xe2o\xd7L\xc2\xf7@\x0f\xaf\xc8\xb3\xd9F\xb0\x1b\xa3\xe7\xc6\xfb\xb4\x12\xf1\xac8\x9d0\x89\x96\x89H\xde\xda\n\xaaN\x90@\xa9<#\xe9_\xa1\xcex\x11\xe2\x0f\x87\x1c\x87 \xbf\'9\xa4" +WRITE 213 "\x17\x03\x03\x00\xd0\x8b\xf1G\xdcB\x83\xbf\x0f\xb0\xf4\x97YXk\xe7ow\xd3\x81\x89\xa0\xa1\x8bG\x99\xeb\xe3\xfa\xda\xd4QW=\x1d\x06\xadn#)L\x08\xa6\x10\xa4\x03O\xdf\xd5\xe2a\xda\xce\x9b\xe9f\xdf\xf4\x14UzW\xd8\xc8\x1c\xa2\xbf\x00\xc5\x9c}\x7fW;\x9b\xe8\x9f\xb0\xaa\x8c\xd0\xf9\xe0\xf7\xf4\"\xb6\xb0\nY\xff\x05\x0bz\xbc\x9c\x81\xd0\xf5\xee\x0bK\xd4Q\xd5l\x81E\xfb\xdcW\x12\xe4\xaa\xe7\xaf\x1c\x7f.\xb1\xd78\x11\xe6\xfd\xb6\xb9\xc5\xd1\xec\x83\xe5\x16\xb2P\xbd\x97\xb5E\x95\'\xf2\xf8B\xee\x01S\xf61&@-\xa0\x95e,H\x07\xb1\x9c\xba`\xd9\xf3\x9b\xe8\xba\x8c\xaaqt_\xe2t&f\xd3\xba\xc3W\xcc\xb7;\xa7\xc9A\x16\x11$e\xfd\x1e\x8eKF\x0cO+\x84\x1e\xc7\x85\x1b\xf2\"Pou\xda" +READ 5 "\x17\x03\x03\x00\xf0" +READ 240 "3\x14\xe7g\x12\xc2I4\x96\x8f\r$\xb4\xa2(\xf2b\xf5]\x82\xa77\x88wJy\x84\xf4\x8e\xaf\xa6\x04\x8d\xed\x7f\xd6q\x80o\'0\x1e\x85\xa1\xf8\x9buk\xc2\x9bx>\xb4S\xe3\xa4\xa2\x88\x8a\xff\xac\x06\x81\xc4\x98g,\xb2\xa9\'\xe2C=\x90\x9b\xc4\xd4\x7f\xa3\xcffneE\xee\x86\xae\xd3\x17\xf3 (\xb7\xf8W\xcd(\x16\x82s2\xe7\x03y81\xe0r\xa0C\x82\xedK\x93u\x87x,\xf3\xca\xc7\x84\xa1\xf5x \x06Q5\xe7\x00%\xb4\x84\xfaw\x1f^R\xc9o\xb4\x96\xf0\xa7\x01\xc5h\x04.\xc8Q\xcfw\t\x8e\xa8\xf9\x98\x9a~q\xb9/\x9f.u\x023Q8\x95\x8b\x7f~\xccx\xa9_,\xc7*<.\x0e\'jH\x05\x8b\xe8\xc2\xee\xd8\xa4\x12\xe1\xb6\xd7FL\xe7\r\xc1\x07*\xcb+\xf0\xc2Pq\xed7\t\x1e\xa4,\x05\xd0\x0e\xba\xf1ABtL*\xba\xbb\xe7~\x1e\xefO\x85\xbd\xe6\x84S" +qwert +WRITE 69 "\x17\x03\x03\x00@\n\x8c\\\xa8b\xae\x05N\xb9O\x81\xaej\x9eM\xf7$\xf9\x8f\xc8\xefz!\x89.\xfe\x19\x12`\xbf{fJS\xd5\x15\x84\x0e\xa5\xf7\"4\xa1\xda[\x95\xe2#&\xe8\xd3\x96\xb8]\xa4+~\xb2Cc\xfc6\xb2|" +READ 5 "\x17\x03\x03\x000" +READ 48 "\xb8uj&\xda\xed\xf9\xbc\xbfn\x9eS`\xa3\x10q\x10[\x05}\xef\xd6\xbf\t\xea\x14f\xf9c\xe6$\xd1R:\xdc\xcc\x88[\x97\xca\x12\x9f\xc1pk\x0e\xf6o" +qwert +zxcvbn +WRITE 69 "\x17\x03\x03\x00@\xe5\xf4\x99xS\xf6\xad\xf4\x89?\xbd\x99=`a\xab\x8e\xed\xd83\xa9-\xabU{\xfa~\xd9h\xf8\x1a\xfaS\xfdD-\xc4\x84=:\xae;\x0b\xccRHT\xef\x04E\x927\xbf~\x0e:\xb0\x16\x01\xf5\xd1\x0f\x1e\xc9" +READ 5 "\x17\x03\x03\x000" +READ 48 "\xa4\x9b=\x85\xe3\x8c\x0c-*\x08(Qu\xd8\x93\xbde,c\x1a\x9c\"\xc9o\xa7\xb5\xe9eH6\xa1\xed\xb9\xcb+\x13>nu^\x1c\x9d\x1b2\xc0\x98\x1d(" +zxcvbn +WRITE 53 "\x17\x03\x03\x000\x17\x19\xf4>\xddSG8\xdd\xcd\x00\xf2\xf58\x15n\xbaY\xbaU\xf0H\x8b\t}\xa5\xaa\xfbXy\xc7f\xc2r\x9e\x94dO\xdc\xaf\xad\xcc\xcd\x16\x87\xdd\x19\xb9" +READ 5 "\x17\x03\x03\x000" +READ 48 "j#\x9d\x17B\x89\xee\x92\x90\xcaH6\xf7PQe|p\xed\xf8,=\x0f+\x8a\x10)\xcf\x06\xb1\x06\xde\x9eA>B\xb7g\xde\xce\xcc\xfd\x88\x1c\xf1-\x96\x00" +``` diff --git a/src/main.rs b/src/main.rs index 03a2c0a..6f7149a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -422,8 +422,7 @@ struct Opt { #[structopt(long = "request-method", short="X")] request_method: Option, - /// Specify HTTP request headers - /// TODO: add short option, remove existing -H + /// [A] Specify HTTP request headers for `http-request:` specifier. #[structopt( long = "request-header", parse(try_from_str = "interpret_custom_header2"),