### Start Rttys Server with Minimal Configuration Source: https://context7.com/zhaojh329/rttys/llms.txt Starts the Rttys server using default ports for device and user connections. No additional configuration is required for basic operation. ```bash ./rttys ``` -------------------------------- ### Start Rttys Server with Production Configuration Source: https://context7.com/zhaojh329/rttys/llms.txt Starts the Rttys server with a comprehensive set of production-ready flags, including custom ports, authentication tokens, SSL certificates, and webhook URLs. Ensure all specified paths for certificates are correct. ```bash ./rttys \ --addr-dev :5912 \ --addr-user :5913 \ --token a1d4cdb1a3cd6a0e94aa3599afcddcf5 \ --password mysecret \ --sslcert /etc/rttys/server.crt \ --sslkey /etc/rttys/server.key \ --cacert /etc/rttys/ca.crt \ --dev-hook-url http://127.0.0.1:8080/rttys-dev-hook \ --user-hook-url http://127.0.0.1:8080/rttys-user-hook \ --log-level info \ --verbose ``` -------------------------------- ### Start Rttys Server with Configuration File Source: https://context7.com/zhaojh329/rttys/llms.txt Launches the Rttys server using a specified YAML configuration file. This method is recommended for managing complex configurations. ```bash ./rttys -c /etc/rttys/rttys.conf ``` -------------------------------- ### GET /devs?group= Source: https://context7.com/zhaojh329/rttys/llms.txt Lists all devices within a specified group along with their metadata. ```APIDOC ## GET /devs?group= ### Description List all devices in a group with their metadata. ### Method GET ### Endpoint `http://localhost:5913/devs?group=` ### Parameters #### Query Parameters - **group** (string) - Optional - The name of the group to list devices from. If omitted, lists devices from the default group. ### Response #### Success Response (200) - **devices** (array of objects) - A list of devices in the specified group, each with metadata. - **group** (string) - The group the device belongs to. - **id** (string) - The unique identifier of the device. - **description** (string) - A description of the device. - **connected** (integer) - The duration in seconds the device has been connected. - **uptime** (integer) - The uptime of the device in seconds. - **proto** (integer) - The protocol version used by the device. - **ipaddr** (string) - The IP address of the device. #### Response Example ```json [ { "group": "factory", "id": "device001", "description": "Raspberry Pi 4", "connected": 3721, "uptime": 86400, "proto": 5, "ipaddr": "192.168.1.50" } ] ``` ``` -------------------------------- ### Rttys Server Configuration File Example Source: https://context7.com/zhaojh329/rttys/llms.txt A sample YAML configuration file for Rttys, demonstrating how to set various parameters such as network addresses, authentication tokens, passwords, webhook URLs, and SSL certificates. CLI flags will override these settings. ```yaml # rttys.conf addr-dev: :5912 addr-user: :5913 # Token that every rtty client must present on registration token: a1d4cdb1a3cd6a0e94aa3599afcddcf5 # Web UI password (empty = no auth required) password: rttys # Disable auth for requests originating on loopback local-auth: false # Allow cross-origin requests allow-origins: true # HTTP proxy redirect URL (leave empty for auto-detect) http-proxy-redir-url: http-proxy-redir-domain: # Webhook URLs dev-hook-url: http://127.0.0.1:8080/rttys-dev-hook user-hook-url: http://127.0.0.1:8080/rttys-user-hook # TLS for the device listener sslcert: /etc/rttys/server.crt sslkey: /etc/rttys/server.key cacert: /etc/rttys/ca.crt # enables mTLS ``` -------------------------------- ### List Devices in a Group (GET /devs) Source: https://context7.com/zhaojh329/rttys/llms.txt Retrieves a list of devices within a specified group, including their metadata such as connection status, uptime, and IP address. If no group is specified, it defaults to the empty-string group. This endpoint requires authentication. ```bash # All devices in default group curl -s -b cookies.txt "http://localhost:5913/devs" ``` ```bash # Devices in the "factory" group curl -s -b cookies.txt "http://localhost:5913/devs?group=factory" # [ # { # "group": "factory", # "id": "device001", # "description": "Raspberry Pi 4", # "connected": 3721, # "uptime": 86400, # "proto": 5, # "ipaddr": "192.168.1.50" # } # ] ``` -------------------------------- ### GET /groups Source: https://context7.com/zhaojh329/rttys/llms.txt Lists all active device groups. The default empty-string group is always included. ```APIDOC ## GET /groups ### Description List all active device groups (always includes the default empty-string group). ### Method GET ### Endpoint `http://localhost:5913/groups` ### Response #### Success Response (200) - **groups** (array of strings) - A list of active device group names. #### Response Example ```json ["","factory","warehouse","datacenter"] ``` ``` -------------------------------- ### Check Rttys Server Version Source: https://context7.com/zhaojh329/rttys/llms.txt Retrieves the currently installed version of the Rttys server binary. This is useful for verifying the deployment or troubleshooting compatibility issues. ```bash ./rttys --version ``` -------------------------------- ### Create a New Branch Source: https://github.com/zhaojh329/rttys/blob/master/CONTRIBUTING.md Create a new branch for your changes. The branch name 'rttys-1-fix' is an example; you can choose any descriptive name. ```bash git checkout -b "rttys-1-fix" ``` -------------------------------- ### GET /counts Source: https://context7.com/zhaojh329/rttys/llms.txt Retrieves the total number of currently connected devices across all groups. ```APIDOC ## GET /counts ### Description Return the total number of currently connected devices across all groups. ### Method GET ### Endpoint `http://localhost:5913/counts` ### Response #### Success Response (200) - **count** (integer) - The total number of connected devices. #### Response Example ```json { "count": 3 } ``` ``` -------------------------------- ### Sign Out from Rttys API (GET /signout) Source: https://context7.com/zhaojh329/rttys/llms.txt Invalidates the current user session by sending a GET request to the /signout endpoint. This requires an active session cookie. ```bash curl -s -b cookies.txt http://localhost:5913/signout # HTTP 200 ``` -------------------------------- ### Get Total Connected Device Count (GET /counts) Source: https://context7.com/zhaojh329/rttys/llms.txt Retrieves the total number of currently connected Rttys devices across all configured groups. This endpoint requires authentication. ```bash curl -s -b cookies.txt http://localhost:5913/counts # {"count":3} ``` -------------------------------- ### GET /signout Source: https://context7.com/zhaojh329/rttys/llms.txt Invalidates the current user session. ```APIDOC ## GET /signout ### Description Invalidate the current session. ### Method GET ### Endpoint `http://localhost:5913/signout` ### Response #### Success Response (200) - **Success** #### Response Example ``` HTTP 200 ``` ``` -------------------------------- ### List All Active Device Groups (GET /groups) Source: https://context7.com/zhaojh329/rttys/llms.txt Retrieves a list of all active device groups managed by the Rttys server. The default empty-string group is always included. This endpoint requires authentication. ```bash curl -s -b cookies.txt http://localhost:5913/groups # ["","factory","warehouse","datacenter"] ``` -------------------------------- ### GET /alive Source: https://context7.com/zhaojh329/rttys/llms.txt Checks if the current session is still valid. Useful for frontend polling. ```APIDOC ## GET /alive ### Description Check if the current session is still valid (useful for frontend polling). ### Method GET ### Endpoint `http://localhost:5913/alive` ### Response #### Success Response (200) - **Authenticated** #### Response Example ``` 200 = authenticated ``` #### Error Response (401) - **Session expired or missing** #### Error Example ``` 401 ``` ``` -------------------------------- ### Check Rttys API Session Status (GET /alive) Source: https://context7.com/zhaojh329/rttys/llms.txt Checks if the current session is still valid by polling the /alive endpoint. This is useful for frontend applications to maintain user authentication status. ```bash curl -s -o /dev/null -w "%{http_code}" -b cookies.txt http://localhost:5913/alive # 200 = authenticated, 401 = session expired or missing ``` -------------------------------- ### Performance Profiling with pprof (Bash) Source: https://context7.com/zhaojh329/rttys/llms.txt Enable and use the Go pprof HTTP endpoint for live performance profiling of RTTYS. ```bash ./rttys --pprof localhost:6060 # CPU profile (30 seconds) go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30 # Heap snapshot go tool pprof http://localhost:6060/debug/pprof/heap # Goroutine dump curl http://localhost:6060/debug/pprof/goroutine?debug=1 # All available endpoints curl http://localhost:6060/debug/pprof/ ``` -------------------------------- ### User Hook Integration Source: https://context7.com/zhaojh329/rttys/llms.txt Set up a webhook that is invoked when a user attempts to access a device via `/connect/:devid`, `/cmd/:devid`, `/web/`, or `/web2/`. Returning HTTP 200 permits access. ```APIDOC ## User Hook (`user-hook-url`) — `GET` ### Description Called when a user accesses `/connect/:devid`, `/cmd/:devid`, `/web/`, or `/web2/`. Rttys forwards all original request headers plus three extra headers. Return HTTP 200 to allow access. ### Method GET ### Endpoint `/rttys-user-hook` ### Headers RTTYS forwards original headers and adds the following: - **X-Rttys-Hook** (string) - Indicates if this is a hook request (e.g., "true"). - **X-Original-Method** (string) - The original HTTP method of the user's request (e.g., "GET", "POST"). - **X-Original-URL** (string) - The original URL path requested by the user (e.g., "/connect/device001"). - **Authorization** (string) - The original authorization header from the user's request. ### Response #### Success Response (200) Returns an empty body to allow access. #### Error Response (403) Returns an empty body to block access if the provided token is invalid. ``` -------------------------------- ### TLS/mTLS for Device Connections (Bash) Source: https://context7.com/zhaojh329/rttys/llms.txt Secure RTTYS device listener with TLS. Use `--cacert` to enforce client certificate authentication (mTLS). ```bash # Generate CA + server cert (self-signed example) openssl genrsa -out ca.key 4096 openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \ -out ca.crt -subj "/CN=rttys-ca" openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr -subj "/CN=rttys-server" openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 365 -sha256 # Start rttys with mTLS (devices must present a cert signed by ca.crt) ./rttys \ --sslcert server.crt \ --sslkey server.key \ --cacert ca.crt # Without cacert = TLS-only (server auth, no client cert required) ./rttys --sslcert server.crt --sslkey server.key ``` -------------------------------- ### Fetch Device Metadata with cURL Source: https://context7.com/zhaojh329/rttys/llms.txt Use this endpoint to retrieve metadata for a specific device. A 404 error is returned if the device is not connected. ```bash curl -s -b cookies.txt "http://localhost:5913/dev/device001?group=factory" # { # "id": "device001", # "description": "Raspberry Pi 4", # "connected": 120, # "uptime": 86400, # "proto": 5, # "ipaddr": "10.0.0.5" # } # 404 if device is not connected curl -s -o /dev/null -w "%{http_code}" -b cookies.txt \ "http://localhost:5913/dev/nonexistent" # 404 ``` -------------------------------- ### Commit and Push Changes Source: https://github.com/zhaojh329/rttys/blob/master/CONTRIBUTING.md Commit your changes with a signoff and push them to your origin branch. Ensure your branch name matches the one you created. ```bash git commit --signoff git push origin rttys-1-fix ``` -------------------------------- ### Performance Profiling (pprof) Source: https://context7.com/zhaojh329/rttys/llms.txt Enable and access the Go pprof HTTP endpoint for live performance profiling of the RTTYS application. ```APIDOC ## Performance Profiling (pprof) Enable the Go pprof HTTP endpoint for live profiling. ### Starting RTTYS with pprof enabled Use the `--pprof` flag to specify the address and port for the pprof endpoint. ```bash ./rttys --pprof localhost:6060 ``` ### Accessing Profiles - **CPU Profile**: Get a CPU profile for a specified duration (e.g., 30 seconds). ```bash go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30 ``` - **Heap Snapshot**: Retrieve a heap profile. ```bash go tool pprof http://localhost:6060/debug/pprof/heap ``` - **Goroutine Dump**: Get a detailed dump of all goroutines. ```bash curl http://localhost:6060/debug/pprof/goroutine?debug=1 ``` - **List All Endpoints**: View all available pprof endpoints. ```bash curl http://localhost:6060/debug/pprof/ ``` ``` -------------------------------- ### Device Registration Webhook (Python Flask) Source: https://context7.com/zhaojh329/rttys/llms.txt Implement a Flask application to handle device registration requests. Return HTTP 200 to allow registration; otherwise, return a non-200 status code. ```python from flask import Flask, request, jsonify app = Flask(__name__) ALLOWED_DEVICES = {"device001", "device002", "sensor-rpi"} @app.route("/rttys-dev-hook", methods=["POST"]) def dev_hook(): data = request.get_json() # data = {"group": "factory", "devid": "device001", "token": "abc123"} devid = data.get("devid", "") group = data.get("group", "") token = data.get("token", "") if devid not in ALLOWED_DEVICES: return jsonify({"error": "unknown device"}), 403 print(f"Device {devid} (group={group}) connected with token={token}") return "", 200 # Allow registration if __name__ == "__main__": app.run(port=8080) ``` -------------------------------- ### Execute Command on Device Source: https://context7.com/zhaojh329/rttys/llms.txt Executes a command on a specified device and returns its output. Supports a timeout and fire-and-forget execution. ```APIDOC ## POST /cmd/:devid?group=&wait= ### Description Execute a command on a device and return its output. The `wait` query parameter sets timeout in seconds (default: 30, max: 30, `0` = fire-and-forget). ### Method POST ### Endpoint /cmd/:devid #### Query Parameters - **group** (string) - Optional - Device group name - **wait** (integer) - Optional - Timeout in seconds for command execution (default: 30, max: 30, 0 for fire-and-forget) #### Request Body - **username** (string) - Required - The username to execute the command as - **cmd** (string) - Required - The command to execute - **params** (array) - Optional - An array of parameters for the command ### Request Example ```bash # Run 'uptime' as root, wait up to 10 seconds curl -s -b cookies.txt -X POST \ "http://localhost:5913/cmd/device001?wait=10" \ -H "Content-Type: application/json" \ -d '{ "username": "root", "cmd": "uptime", "params": [] }' ``` ### Response #### Success Response (200) - **devid** (string) - The device ID - **code** (integer) - The exit code of the command - **stdout** (string) - Standard output of the command - **stderr** (string) - Standard error of the command #### Error Responses (HTTP 200 with error code in body) - `{"err":1001,"msg":"invalid format"}` - Missing command or username. - `{"err":1002,"msg":"device offline"}` - Device is not connected. - `{"err":1003,"msg":"timeout"}` - Command execution exceeded the timeout. ### Response Example ```json { "devid": "device001", "code": 0, "stdout": " 10:22:14 up 1 day, 0:04, load average: 0.01, 0.05, 0.01", "stderr": "" } ``` ``` -------------------------------- ### Run Rttys Docker Container with Configuration File Source: https://context7.com/zhaojh329/rttys/llms.txt Deploys the Rttys server in a Docker container, mounting a configuration file for persistent settings. Ports 5912 and 5913 are exposed for device and user access. ```bash docker run -d \ --name rttys \ -p 5912:5912 \ -p 5913:5913 \ -v /etc/rttys/rttys.conf:/etc/rttys/rttys.conf:ro \ rttys:latest -c /etc/rttys/rttys.conf ``` -------------------------------- ### POST /signin Source: https://context7.com/zhaojh329/rttys/llms.txt Authenticates a user and returns a session cookie (`sid`). This endpoint is required if a password is set for the server. ```APIDOC ## POST /signin ### Description Authenticate and receive a session cookie (`sid`). Required if `--password` is set. ### Method POST ### Endpoint `http://localhost:5913/signin` ### Request Body - **password** (string) - Required - The password for authentication. ### Request Example ```json { "password": "rttys" } ``` ### Response #### Success Response (200) - **sid** (string) - The session cookie. #### Response Example ``` HTTP 200 on success; sets cookie: sid=<32-char hex> ``` #### Error Response (401) - **Unauthorized** #### Error Example ``` 401 ``` ``` -------------------------------- ### Build Rttys Docker Image Source: https://context7.com/zhaojh329/rttys/llms.txt Builds the Docker image for the Rttys server. This command assumes the Dockerfile is in the current directory. ```bash docker build -t rttys:latest . ``` -------------------------------- ### Run Rttys Docker Container with CLI Flags Source: https://context7.com/zhaojh329/rttys/llms.txt Deploys the Rttys server in a Docker container using command-line flags for configuration. This is suitable for simpler deployments or testing. ```bash docker run -d \ --name rttys \ -p 5912:5912 \ -p 5913:5913 \ rttys:latest --token mytoken --password secret ``` -------------------------------- ### HTTP Proxy to Device Services Source: https://context7.com/zhaojh329/rttys/llms.txt Establishes a proxied HTTP/HTTPS connection to a TCP service running on a device. This redirects the browser and uses a session cookie for routing. ```APIDOC ## GET /web/:devid/:proto/:addr/*path ## GET /web2/:group/:devid/:proto/:addr/*path ### Description Establish a proxied HTTP/HTTPS connection to a TCP service on the device. This redirects the browser with a session cookie (`rtty-http-sid`) that the separate HTTP proxy listener uses to route traffic through the device. ### Method GET ### Endpoint /web/:devid/:proto/:addr/*path /web2/:group/:devid/:proto/:addr/*path #### Path Parameters - **devid** (string) - Required - The device ID - **group** (string) - Required (for /web2) - The device group name - **proto** (string) - Required - The protocol (e.g., http, https) - **addr** (string) - Required - The device's IP address and port (e.g., 192.168.1.1:80) - **path** (string) - Optional - The path on the target service ### Request Example ```bash # Access a web service running on device001 at 192.168.1.1:80 # Browser navigates to: # http://localhost:5913/web/device001/http/192.168.1.1:80/ # Access an HTTPS service on port 443 # http://localhost:5913/web/device001/https/192.168.1.1:443/ # With group (web2 variant) # http://localhost:5913/web2/factory/device001/http/10.0.0.1:8080/dashboard # curl example (follows redirect, uses cookie jar) curl -s -b cookies.txt -c cookies.txt -L \ "http://localhost:5913/web/device001/http/192.168.1.1/index.html" ``` ### Response The server sets a `rtty-http-sid` cookie, redirects to the HTTP proxy port, and all subsequent requests are tunneled to the device automatically for 15 minutes of inactivity timeout. ``` -------------------------------- ### Device Hook Integration Source: https://context7.com/zhaojh329/rttys/llms.txt Configure a webhook to be called when a device registers with RTTYS. The system expects an HTTP 200 response to allow registration, and any other status code to reject it. ```APIDOC ## Device Hook (`dev-hook-url`) — `POST` ### Description Called when a device registers. Return HTTP 200 to allow, any other code to reject. ### Method POST ### Endpoint `/rttys-dev-hook` ### Request Body - **group** (string) - Optional - The group the device belongs to. - **devid** (string) - Required - The unique identifier of the device. - **token** (string) - Optional - The token associated with the device. ### Response #### Success Response (200) Returns an empty body to allow registration. #### Error Response (403) Returns a JSON object with an error message if the device is not allowed. ``` -------------------------------- ### Execute Remote Command with cURL Source: https://context7.com/zhaojh329/rttys/llms.txt Execute a command on a device and receive its output. The `wait` parameter controls the timeout. Error responses are returned in the JSON body with an HTTP 200 status. ```bash # Run 'uptime' as root, wait up to 10 seconds curl -s -b cookies.txt -X POST \ "http://localhost:5913/cmd/device001?wait=10" \ -H "Content-Type: application/json" \ -d '{ "username": "root", "cmd": "uptime", "params": [] }' # Success response: # { # "devid": "device001", # "code": 0, # "stdout": " 10:22:14 up 1 day, 0:04, load average: 0.01, 0.05, 0.01", # "stderr": "" # } # Run command with parameters curl -s -b cookies.txt -X POST \ "http://localhost:5913/cmd/device001?group=factory" \ -H "Content-Type: application/json" \ -d '{ "username": "root", "cmd": "ls", "params": ["-la", "/tmp"] }' # Error responses (all return HTTP 200 with error code in body): # {"err":1001,"msg":"invalid format"} -- missing cmd or username # {"err":1002,"msg":"device offline"} -- device not connected # {"err":1003,"msg":"timeout"} -- command took too long # Fire-and-forget (wait=0): returns HTTP 200 immediately, no output curl -s -o /dev/null -w "%{http_code}" -b cookies.txt -X POST \ "http://localhost:5913/cmd/device001?wait=0" \ -H "Content-Type: application/json" \ -d '{"username":"root","cmd":"reboot","params":[]}' # 200 ``` -------------------------------- ### User Access Webhook (Python Flask) Source: https://context7.com/zhaojh329/rttys/llms.txt Create a Flask endpoint to validate user access requests. Rttys forwards original headers plus X-Rttys-Hook, X-Original-Method, and X-Original-URL. Return HTTP 200 to allow access. ```python @app.route("/rttys-user-hook", methods=["GET"]) def user_hook(): # Extra headers added by rttys: is_hook = request.headers.get("X-Rttys-Hook") # "true" method = request.headers.get("X-Original-Method") # "GET" / "POST" orig_url = request.headers.get("X-Original-URL") # "/connect/device001" # Original auth headers are forwarded too auth_token = request.headers.get("Authorization", "") if not is_valid_token(auth_token): return "", 403 # Block access print(f"User hook: method={method}, url={orig_url}") return "", 200 # Allow access def is_valid_token(token): return token == "Bearer myapitoken" ``` -------------------------------- ### Authenticate with Rttys API (POST /signin) Source: https://context7.com/zhaojh329/rttys/llms.txt Authenticates a user with the Rttys API by sending a JSON payload containing the password. A successful request returns an HTTP 200 status and sets a session cookie (`sid`). ```bash # Sign in curl -s -c cookies.txt -X POST http://localhost:5913/signin \ -H "Content-Type: application/json" \ -d '{"password":"rttys"}' # HTTP 200 on success; sets cookie: sid=<32-char hex> ``` ```bash # 401 Unauthorized on wrong password curl -s -o /dev/null -w "%{http_code}" -X POST http://localhost:5913/signin \ -H "Content-Type: application/json" \ -d '{"password":"wrong"}' # 401 ``` -------------------------------- ### Clone rttys Repository Source: https://github.com/zhaojh329/rttys/blob/master/CONTRIBUTING.md Clone the rttys repository from your GitHub account after forking it. Replace 'your_github_username' with your actual GitHub username. ```bash git clone https://github.com/your_github_username/rttys.git ``` -------------------------------- ### Open WebSocket Terminal Session Source: https://context7.com/zhaojh329/rttys/llms.txt Establishes a WebSocket connection for a terminal session to a device. Can also redirect to a UI or proxy the WebSocket connection. ```APIDOC ## GET /connect/:devid (WebSocket upgrade) ### Description Open a WebSocket terminal session to a device. The browser navigates to this URL; if the request is a plain GET it redirects to the Vue UI route `/rtty/:devid`. If the `Upgrade: websocket` header is present, the connection is proxied directly to the device. ### Method GET ### Endpoint /connect/:devid #### Query Parameters - **group** (string) - Optional - Device group name ### Request Example ```javascript // Browser WebSocket client example const ws = new WebSocket(`ws://localhost:5913/connect/device001`); // With group: // const ws = new WebSocket(`ws://localhost:5913/connect/device001?group=factory`); ws.onopen = () => console.log('WebSocket opened'); ws.onmessage = (event) => { if (typeof event.data === 'string') { const msg = JSON.parse(event.data); if (msg.type === 'login') { console.log('Terminal session established'); // Resize terminal ws.send(JSON.stringify({ type: 'winsize', cols: 220, rows: 50 })); } } else { // Binary: first byte is padding; rest is terminal output const termData = event.data.slice(1); term.write(termData); // xterm.js write } }; // Send keystrokes as binary (first byte = 0 for term data, 1 for file) ws.send(new Uint8Array([0, ...new TextEncoder().encode('ls -la\n')])); // Send terminal resize ws.send(JSON.stringify({ type: 'winsize', cols: 220, rows: 50 })); // Flow-control ack ws.send(JSON.stringify({ type: 'ack', ack: 1024 })); ``` ### WebSocket Close Codes | Code | Meaning | |---|---| | 4000 | Device offline | | 4001 | Device busy (another session active) | | 4002 | Login timeout (5 s) | ``` -------------------------------- ### TLS / mTLS for Device Connections Source: https://context7.com/zhaojh329/rttys/llms.txt Secure device connections using TLS. For mutual TLS (mTLS), provide a CA certificate to verify client certificates. ```APIDOC ## TLS / mTLS for Device Connections Secure the device listener with TLS; add `--cacert` to require client certificates (mTLS). ### Starting RTTYS with TLS Use the `--sslcert` and `--sslkey` flags to specify the server certificate and private key. ```bash ./rttys --sslcert server.crt --sslkey server.key ``` ### Starting RTTYS with mTLS In addition to server certificate and key, use the `--cacert` flag to specify the Certificate Authority certificate. This requires devices to present a certificate signed by the provided CA. ```bash ./rttys \ --sslcert server.crt \ --sslkey server.key \ --cacert ca.crt ``` ``` -------------------------------- ### Establish WebSocket Terminal Session Source: https://context7.com/zhaojh329/rttys/llms.txt Open a WebSocket connection for a terminal session to a device. The `Upgrade: websocket` header is required for direct proxying. Browser clients can use the `WebSocket` API. ```javascript // Browser WebSocket client example const ws = new WebSocket(`ws://localhost:5913/connect/device001`); // With group: // const ws = new WebSocket(`ws://localhost:5913/connect/device001?group=factory`); ws.onopen = () => console.log('WebSocket opened'); ws.onmessage = (event) => { if (typeof event.data === 'string') { const msg = JSON.parse(event.data); if (msg.type === 'login') { console.log('Terminal session established'); // Resize terminal ws.send(JSON.stringify({ type: 'winsize', cols: 220, rows: 50 })); } } else { // Binary: first byte is padding; rest is terminal output const termData = event.data.slice(1); term.write(termData); // xterm.js write } }; // Send keystrokes as binary (first byte = 0 for term data, 1 for file) ws.send(new Uint8Array([0, ...new TextEncoder().encode('ls -la\n')])); // Send terminal resize ws.send(JSON.stringify({ type: 'winsize', cols: 220, rows: 50 })); // Flow-control ack ws.send(JSON.stringify({ type: 'ack', ack: 1024 })); ``` -------------------------------- ### Fetch Device Metadata Source: https://context7.com/zhaojh329/rttys/llms.txt Retrieves metadata for a specific device. Supports filtering by group. ```APIDOC ## GET /dev/:devid?group= ### Description Fetch metadata for a single device. ### Method GET ### Endpoint /dev/:devid #### Query Parameters - **group** (string) - Optional - Device group name ### Response #### Success Response (200) - **id** (string) - Device unique ID - **description** (string) - Human-readable device description - **connected** (uint32) - Seconds since device connected to rttys - **uptime** (uint32) - Device uptime in seconds (from heartbeat) - **proto** (uint8) - RTTY protocol version - **ipaddr** (string) - Device's TCP remote IP address ### Request Example ```bash curl -s -b cookies.txt "http://localhost:5913/dev/device001?group=factory" ``` ### Response Example ```json { "id": "device001", "description": "Raspberry Pi 4", "connected": 120, "uptime": 86400, "proto": 5, "ipaddr": "10.0.0.5" } ``` ``` -------------------------------- ### Proxy HTTP/HTTPS to Device Services with cURL Source: https://context7.com/zhaojh329/rttys/llms.txt Establish a proxied HTTP/HTTPS connection to a TCP service on the device. This redirects the browser with a session cookie. The `web2` variant includes the group name. ```bash # Access a web service running on device001 at 192.168.1.1:80 # Browser navigates to: # http://localhost:5913/web/device001/http/192.168.1.1:80/ # Access an HTTPS service on port 443 # http://localhost:5913/web/device001/https/192.168.1.1:443/ # With group (web2 variant) # http://localhost:5913/web2/factory/device001/http/10.0.0.1:8080/dashboard # curl example (follows redirect, uses cookie jar) curl -s -b cookies.txt -c cookies.txt -L \ "http://localhost:5913/web/device001/http/192.168.1.1/index.html" ``` -------------------------------- ### File Transfer via WebSocket (JavaScript) Source: https://context7.com/zhaojh329/rttys/llms.txt Manage file uploads and downloads over a WebSocket connection. The first byte of binary messages indicates the channel (0 for terminal, 1 for file). ```javascript // Upload a file to the device async function uploadFile(ws, file) { // Step 1: Send file metadata ws.send(JSON.stringify({ type: 'fileInfo', size: file.size, name: file.name })); // Step 2: Wait for device ready signal {"type":"recvfile"} // (handled in ws.onmessage) // Step 3: Send file data in chunks (first byte = 1 for file channel) const CHUNK = 4096; const reader = file.stream().getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; const buf = new Uint8Array(1 + value.length); buf[0] = 1; // file channel buf.set(value, 1); ws.send(buf); } } // Handle incoming file messages ws.onmessage = (event) => { if (typeof event.data === 'string') { const msg = JSON.parse(event.data); switch (msg.type) { case 'sendfile': // Device is pushing a file named msg.name — prepare to receive console.log(`Receiving file: ${msg.name}`); break; case 'recvfile': // Device is ready to receive — start sending chunks break; case 'fileAck': console.log('File transfer acknowledged by device'); break; } } else { const data = new Uint8Array(await event.data.arrayBuffer()); if (data[0] === 1) { // File data chunk: data.slice(1) fileChunks.push(data.slice(1)); } else { term.write(data.slice(1)); // terminal output } } }; // Cancel an in-progress file transfer ws.send(JSON.stringify({ type: 'fileCanceled' })); // Acknowledge receipt of a file chunk ws.send(JSON.stringify({ type: 'fileAck' })); ``` -------------------------------- ### File Transfer via WebSocket Source: https://context7.com/zhaojh329/rttys/llms.txt Manage file transfers over the same WebSocket connection used for terminal sessions. This involves sending file metadata, data chunks, and acknowledgments. ```APIDOC ## File Transfer via WebSocket File transfers share the same `/connect/:devid` WebSocket. The first byte of every binary message indicates the channel (`0` = terminal, `1` = file). ### Sending a File 1. Send file metadata using `JSON.stringify({ type: 'fileInfo', size: file.size, name: file.name })`. 2. Wait for a `{"type":"recvfile"}` signal from the device. 3. Send file data in chunks, prefixing each chunk with a byte `1` to indicate the file channel. ### Receiving a File - When the device initiates a file transfer, it sends `JSON.stringify({ type: 'sendfile', name: msg.name })`. - The client should respond with `JSON.stringify({ type: 'recvfile' })` to signal readiness. - File data chunks are received as binary messages, with the first byte indicating the channel (`1` for file). ### File Transfer Control - **Cancel Transfer**: Send `JSON.stringify({ type: 'fileCanceled' })`. - **Acknowledge Chunk**: Send `JSON.stringify({ type: 'fileAck' })`. ``` -------------------------------- ### Handle RTTY HTTP Proxy Errors Source: https://github.com/zhaojh329/rttys/blob/master/assets/http-proxy-err.html This JavaScript code dynamically updates the error message and page title based on the error type (offline or unauthorized) and the user's language. It uses a translation map for multi-language support. Initialize this script on page load. ```javascript const translations = { en: { 'Device Unavailable': 'Device Unavailable', 'Unauthorized Access': 'Unauthorized Access', 'Device offline message': 'The device is currently offline. Please check the device status and try again.', 'Unauthorized request message': 'You are not authorized to access this resource. Please check your session and try again.' }, 'zh-CN': { 'Device Unavailable': '设备不可用', 'Unauthorized Access': '未授权访问', 'Device offline message': '设备当前离线,请检查设备状态后重试。', 'Unauthorized request message': '您无权访问此资源。请检查您的会话并重试。' } }; function t(key, lang) { return translations[lang][key] || translations.en[key] || key; } function updateContent() { const errorType = '{{.}}'; const lang = navigator.language === 'zh-CN' ? 'zh-CN' : 'en'; let title = '', message = ''; switch (errorType) { case 'offline': title = t('Device Unavailable', lang); message = t('Device offline message', lang); break; case 'unauthorized': title = t('Unauthorized Access', lang); message = t('Unauthorized request message', lang); break; } document.getElementById('errorTitle').textContent = title; document.getElementById('errorMessage').textContent = message; // Update page title if (title) { document.title = title + ' - RTTY'; } else { document.title = 'Error - RTTY'; } } // Initialize page on load document.addEventListener('DOMContentLoaded', updateContent); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.