server: add support for cli args via url

This commit is contained in:
Shuanglei Tao
2019-04-14 22:21:21 +08:00
parent bd8d2cfc32
commit 74e091f954
7 changed files with 54 additions and 8 deletions

View File

@@ -172,7 +172,7 @@ function handleReceive(zsession) {
var terminalContainer = document.getElementById('terminal-container'),
httpsEnabled = window.location.protocol === 'https:',
url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname
+ (window.location.pathname.endsWith('/') ? '' : '/') + 'ws',
+ (window.location.pathname.endsWith('/') ? '' : '/') + 'ws' + window.location.search,
textDecoder = new TextDecoder(),
textEncoder = new TextEncoder(),
authToken = (typeof tty_auth_token !== 'undefined') ? tty_auth_token : null,

View File

@@ -58,6 +58,11 @@ Cross platform: macOS, Linux, FreeBSD/OpenBSD, OpenWrt/LEDE, Windows
\-r, \-\-reconnect <seconds>
Time to reconnect for the client in seconds (default: 10)
.PP
\-a, \-\-url\-arg
Allow client to send command line arguments in URL (eg:
\[la]http://localhost:7681?arg=foo&arg=bar\[ra])
.PP
\-R, \-\-readonly
Do not allow clients to write to the TTY

View File

@@ -40,6 +40,9 @@ ttyd 1 "September 2016" ttyd "User Manual"
-r, --reconnect <seconds>
Time to reconnect for the client in seconds (default: 10)
-a, --url-arg
Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar)
-R, --readonly
Do not allow clients to write to the TTY

2
src/index.html vendored

File diff suppressed because one or more lines are too long

View File

@@ -158,6 +158,10 @@ cleanup:
if (client->buffer != NULL)
free(client->buffer);
for (int i = 0; i < client->argc; i++) {
free(client->args[i]);
}
pthread_mutex_destroy(&client->mutex);
// remove from client list
@@ -166,11 +170,21 @@ cleanup:
void *
thread_run_command(void *args) {
struct tty_client *client;
struct tty_client *client = (struct tty_client *) args;
// append url args to arguments
char *argv[server->argc + client->argc + 1];
int i, n = 0;
for (i = 0; i < server->argc; i++) {
argv[n++] = server->argv[i];
}
for (i = 0; i < client->argc; i++) {
argv[n++] = client->args[i];
}
argv[n] = NULL;
int pty;
fd_set des_set;
client = (struct tty_client *) args;
pid_t pid = forkpty(&pty, NULL, NULL, NULL);
switch (pid) {
@@ -184,7 +198,7 @@ thread_run_command(void *args) {
}
// Don't pass the web socket onto child processes
close(lws_get_socket_fd(client->wsi));
if (execvp(server->argv[0], server->argv) < 0) {
if (execvp(argv[0], argv) < 0) {
perror("execvp");
pthread_exit((void *) 1);
}
@@ -264,6 +278,18 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
client->buffer = NULL;
client->state = STATE_INIT;
client->pty_len = 0;
client->argc = 0;
if (server->url_arg) {
while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) {
if (strncmp(buf, "arg=", 4) == 0) {
client->args = xrealloc(client->args, (client->argc + 1) * sizeof(char *));
client->args[client->argc] = strdup(&buf[4]);
client->argc++;
}
}
}
pthread_mutex_init(&client->mutex, NULL);
pthread_cond_init(&client->cond, NULL);
lws_get_peer_addresses(wsi, lws_get_socket_fd(wsi),
@@ -274,8 +300,8 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
LIST_INSERT_HEAD(&server->clients, client, list);
server->client_count++;
pthread_mutex_unlock(&server->mutex);
lws_hdr_copy(wsi, buf, sizeof(buf), WSI_TOKEN_GET_URI);
lws_hdr_copy(wsi, buf, sizeof(buf), WSI_TOKEN_GET_URI);
lwsl_notice("WS %s - %s (%s), clients: %d\n", buf, client->address, client->hostname, server->client_count);
break;

View File

@@ -51,6 +51,7 @@ static const struct option options[] = {
{"ssl-cert", required_argument, NULL, 'C'},
{"ssl-key", required_argument, NULL, 'K'},
{"ssl-ca", required_argument, NULL, 'A'},
{"url-arg", no_argument, NULL, 'a'},
{"readonly", no_argument, NULL, 'R'},
{"check-origin", no_argument, NULL, 'O'},
{"max-clients", required_argument, NULL, 'm'},
@@ -77,6 +78,7 @@ void print_help() {
" -g, --gid Group id to run with\n"
" -s, --signal Signal to send to the command when exit it (default: 1, SIGHUP)\n"
" -r, --reconnect Time to reconnect for the client in seconds (default: 10)\n"
" -a, --url-arg Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar)\n"
" -R, --readonly Do not allow clients to write to the TTY\n"
" -t, --client-option Send option to client (format: key=value), repeat to add more options\n"
" -T, --terminal-type Terminal type to report, default: xterm-256color\n"
@@ -126,6 +128,7 @@ tty_server_new(int argc, char **argv, int start) {
}
}
ts->argv[cmd_argc] = NULL;
ts->argc = cmd_argc;
ts->command = xmalloc(cmd_len + 1);
char *ptr = ts->command;
@@ -264,6 +267,9 @@ main(int argc, char **argv) {
case 'd':
debug_level = atoi(optarg);
break;
case 'a':
server->url_arg = true;
break;
case 'R':
server->readonly = true;
break;
@@ -436,6 +442,8 @@ main(int argc, char **argv) {
lwsl_notice(" reconnect timeout: %ds\n", server->reconnect);
if (server->check_origin)
lwsl_notice(" check origin: true\n");
if (server->url_arg)
lwsl_notice(" allow url arg: true\n");
if (server->readonly)
lwsl_notice(" readonly: true\n");
if (server->max_clients > 0)

View File

@@ -33,6 +33,8 @@ struct tty_client {
bool authenticated;
char hostname[100];
char address[50];
char **args;
int argc;
struct lws *wsi;
struct winsize size;
@@ -67,8 +69,10 @@ struct tty_server {
char *index; // custom index.html
char *command; // full command line
char **argv; // command with arguments
int argc; // command + arguments count
int sig_code; // close signal
char sig_name[20]; // human readable signal string
bool url_arg; // allow client to send cli arguments in URL
bool readonly; // whether not allow clients to write to the TTY
bool check_origin; // whether allow websocket connection from different origin
int max_clients; // maximum clients to support