goto try_to_reuse;
}
- if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
- return 1;
- if (lws_add_http_header_by_token(wsi,
- WSI_TOKEN_HTTP_CONTENT_TYPE,
- (unsigned char *) "text/html",
- 9, &p, end))
- return 1;
- if (lws_add_http_header_content_length(wsi, (unsigned long) index_html_len, &p, end))
- return 1;
- if (lws_finalize_http_header(wsi, &p, end))
- return 1;
- if (lws_write(wsi, buffer + LWS_PRE, p - (buffer + LWS_PRE), LWS_WRITE_HTTP_HEADERS) < 0) {
- return 1;
- }
+ const char* content_type = "text/html";
+ if (server->index != NULL) {
+ int n = lws_serve_http_file(wsi, server->index, content_type, NULL, 0);
+ if (n < 0 || (n > 0 && lws_http_transaction_completed(wsi)))
+ return 1;
+ } else {
+ if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
+ return 1;
+ if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (const unsigned char *) content_type, 9, &p, end))
+ return 1;
+ if (lws_add_http_header_content_length(wsi, (unsigned long) index_html_len, &p, end))
+ return 1;
+ if (lws_finalize_http_header(wsi, &p, end))
+ return 1;
+ if (lws_write(wsi, buffer + LWS_PRE, p - (buffer + LWS_PRE), LWS_WRITE_HTTP_HEADERS) < 0)
+ return 1;
- if (lws_write_http(wsi, index_html, index_html_len) < 0)
- return 1;
+ if (lws_write_http(wsi, index_html, index_html_len) < 0)
+ return 1;
+ }
goto try_to_reuse;
+
case LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION:
if (!len || (SSL_get_verify_result((SSL *) in) != X509_V_OK)) {
int err = X509_STORE_CTX_get_error((X509_STORE_CTX *) user);
return 1;
}
break;
+
default:
break;
}
{"gid", required_argument, NULL, 'g'},
{"signal", required_argument, NULL, 's'},
{"reconnect", required_argument, NULL, 'r'},
+ {"index", required_argument, NULL, 'I'},
{"ssl", no_argument, NULL, 'S'},
{"ssl-cert", required_argument, NULL, 'C'},
{"ssl-key", required_argument, NULL, 'K'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, 0, 0}
};
-static const char *opt_string = "p:i:c:u:g:s:r:aSC:K:A:Rt:Ood:vh";
+static const char *opt_string = "p:i:c:u:g:s:r:I:aSC:K:A:Rt:Ood:vh";
void print_help() {
fprintf(stderr, "ttyd is a tool for sharing terminal over the web\n\n"
" --client-option, -t Send option to client (format: key=value), repeat to add more options\n"
" --check-origin, -O Do not allow websocket connection from different origin\n"
" --once, -o Accept only one client and exit on disconnection\n"
+ " --index, -I Custom index.html path\n"
" --ssl, -S Enable SSL\n"
" --ssl-cert, -C SSL certificate file path\n"
" --ssl-key, -K SSL key file path\n"
return ts;
}
+void
+tty_server_free(struct tty_server *ts) {
+ if (ts == NULL)
+ return;
+ if (ts->credential != NULL)
+ free(ts->credential);
+ if (ts->index != NULL)
+ free(ts->index);
+ free(ts->command);
+ free(ts->prefs_json);
+ int i = 0;
+ do {
+ free(ts->argv[i++]);
+ } while (ts->argv[i] != NULL);
+ free(ts->argv);
+ free(ts->sig_name);
+ free(ts);
+}
+
void
sig_handler(int sig) {
if (force_exit)
return -1;
}
break;
+ case 'I':
+ if (!strncmp(optarg, "~/", 2)) {
+ const char* home = getenv("HOME");
+ server->index = malloc(strlen(home) + strlen(optarg) - 1);
+ sprintf(server->index, "%s%s", home, optarg + 1);
+ } else {
+ server->index = strdup(optarg);
+ }
+ struct stat st;
+ if (stat(server->index, &st) == -1) {
+ fprintf(stderr, "Can not stat index.html: %s, error: %s\n", server->index, strerror(errno));
+ return -1;
+ }
+ if (S_ISDIR(st.st_mode)) {
+ fprintf(stderr, "Invalid index.html path: %s, is it a dir?\n", server->index);
+ return -1;
+ }
+ break;
case 'S':
ssl = true;
break;
lwsl_notice(" readonly: true\n");
if (server->once)
lwsl_notice(" once: true\n");
+ if (server->index != NULL) {
+ lwsl_notice(" custom index.html: %s\n", server->index);
+ }
// libwebsockets main loop
while (!force_exit) {
lws_context_destroy(context);
// cleanup
- if (server->credential != NULL)
- free(server->credential);
- free(server->command);
- free(server->prefs_json);
- int i = 0;
- do {
- free(server->argv[i++]);
- } while (server->argv[i] != NULL);
- free(server->argv);
- free(server->sig_name);
- free(server);
+ tty_server_free(server);
return 0;
}