Initial implementation of the http sessions ##web (#23272)

This commit is contained in:
pancake 2024-09-03 01:15:00 +02:00 committed by GitHub
parent c90a0dcf8c
commit 2952926a96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 96 additions and 17 deletions

View File

@ -236,6 +236,8 @@ static const RCoreHelpMessage help_msg_equal = {
"!=!", "", "enable remote cmd mode",
"\nservers:", "", "",
// ".:", "9000", "start the tcp server (echo x|nc ::1 9090 or curl ::1:9090/cmd/x)",
"=l", "", "listen daemon",
"=L", "", "List daemon sessions",
"=t", "port", "start the tcp server (echo x|nc ::1 9090 or curl ::1:9090/cmd/x)",
"=r", "port", "start the rap server (o rap://9999)",
"=g", "[?]", "start the gdbserver",
@ -1059,6 +1061,64 @@ static void cmd_tcp_server(RCore *core, const char *input) {
}
}
#define MINPORT 2000
#define MAXPORT 3000
static void session_listen(RCore *core) {
if (core->http_up) {
R_LOG_ERROR ("Daemon already running");
return;
}
int port = MINPORT + r_num_rand (MAXPORT - MINPORT);
r_strf_var (sport, 80, "%d", port);
r_config_set (core->config, "http.port", sport);
r_config_set_b (core->config, "http.sandbox", false);
int pid = r_sys_getpid ();
char *tmpdir = r_file_tmpdir ();
char *tmpdir_r2 = r_str_newf ("%s/r2", tmpdir);
r_sys_mkdir (tmpdir_r2);
char *fn = r_str_newf ("%s/%d.pid", tmpdir_r2, pid);
char *s = r_str_newf ("r2web://127.0.0.1:%d/cmd", port);
if (r_file_dump (fn, (const ut8*)s, strlen (s), false)) {
r_core_cmd0 (core, "=h&");
} else {
R_LOG_ERROR ("Cannot create socket file %s", s);
}
free (s);
free (tmpdir_r2);
free (tmpdir);
// set random port
}
static void session_list(RCore *core) {
char *tmpdir = r_file_tmpdir ();
char *tmpdir_r2 = r_str_newf ("%s/r2", tmpdir);
char *file;
RListIter *iter;
RList *files = r_sys_dir (tmpdir_r2);
r_list_foreach (files, iter, file) {
if (r_str_endswith (file, ".pid")) {
char *ffn = r_str_newf ("%s/%s", tmpdir_r2, file);
// TODO: curl to get filename or session name via "/cmd/k%20name"
char *data = r_file_slurp (ffn, NULL);
int fpid = atoi (file);
if (data) {
#if R2__UNIX__ && !__wasi__
if (0 == kill (fpid, 0)) {
r_cons_printf ("r2 %s # pid %d\n", data, fpid);
} else {
r_file_rm (ffn);
}
#else
r_cons_printf ("r2 %s # pid %d\n", data, fpid);
#endif
}
free (ffn);
}
}
r_list_free (files);
}
static int cmd_rap(void *data, const char *input) {
RCore *core = (RCore *)data;
switch (*input) {
@ -1074,6 +1134,16 @@ static int cmd_rap(void *data, const char *input) {
case 'R': // "=R"
cmd_remote (core, r_str_trim_head_ro (input + 1), true);
break;
case 'l': // "=l"
if (input[1] == ' ') {
// set session name here
r_core_cmdf (core, "k name=%s", r_str_trim_head_ro (input + 2));
}
session_listen (core);
break;
case 'L': // "=L"
session_list (core);
break;
case 'j': // "=j"
R_LOG_ERROR ("TODO: list connections in json");
break;

View File

@ -48,6 +48,11 @@ typedef struct {
R_API void r_core_wait(RCore *core) {
r_cons_context ()->breaked = true;
#if R2__UNIX__
if (core->http_up) {
r_core_rtr_http_stop (core);
}
#endif
r_th_kill (httpthread, true);
r_th_kill (rapthread, true);
r_th_wait (httpthread);
@ -176,18 +181,19 @@ beach:
R_API int r_core_rtr_http_stop(RCore *u) {
RCore *core = (RCore*)u;
const int timeout = 1; // 1 second
const char *port;
RSocket* sock;
#if R2__WINDOWS__
r_socket_http_server_set_breaked (&r_cons_context ()->breaked);
#endif
core->http_up = false;
if (((size_t)u) > 0xff) {
port = listenport? listenport: r_config_get (
core->config, "http.port");
sock = r_socket_new (0);
(void)r_socket_connect (sock, "localhost",
port, R_SOCKET_PROTO_TCP, timeout);
const char *port = listenport? listenport: r_config_get (core->config, "http.port");
char *sport = r_str_startswith (port, "0x")
? r_str_newf ("%d", (int)r_num_get (NULL, port))
: strdup (port);
RSocket* sock = r_socket_new (0);
(void)r_socket_connect (sock, "127.0.0.1", sport, R_SOCKET_PROTO_TCP, timeout);
free (sport);
r_socket_free (sock);
}
r_socket_free (s);

View File

@ -95,7 +95,7 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
}
s = r_socket_new (false);
{
if (host && *host) {
if (R_STR_ISNOTEMPTY (host)) {
if (!strcmp (host, "::1")) {
s->local = true;
} else if (!strcmp (host, "localhost")) {
@ -138,9 +138,7 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
R_LOG_ERROR ("No user list set for HTTP Authentication");
return 1;
}
pfile = r_file_slurp (httpauthfile, NULL);
if (pfile) {
so.authtokens = r_str_split_list (pfile, "\n", 0);
} else {
@ -148,7 +146,6 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
R_LOG_ERROR ("Empty list of HTTP users");
return 1;
}
so.timeout = r_config_get_i (core->config, "http.timeout");
so.accept_timeout = 1;
}
@ -172,8 +169,9 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
restoreSandbox = true;
}
eprintf ("Starting http server...\n");
eprintf ("open http://%s:%d/\n", host, atoi (port));
eprintf ("r2 -C http://%s:%d/cmd/\n", host, atoi (port));
eprintf ("open http://%s:%s/\n", host, port);
eprintf ("r2 -C http://%s:%s/cmd/\n", host, port);
eprintf ("r2 r2web://%s:%s/cmd/\n", host, port);
core->http_up = true;
ut64 newoff, origoff = core->offset;
@ -192,7 +190,7 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
core->block = newblk;
// TODO: handle mutex lock/unlock here
r_cons_break_push ((RConsBreak)r_core_rtr_http_stop, core);
while (!r_cons_is_breaked ()) {
while (!r_cons_is_breaked () && core->http_up) {
/* restore environment */
core->config = origcfg;
#if WEBCONFIG
@ -200,7 +198,6 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
r_config_set_i (origcfg, "scr.color", r_config_get_i (origcfg, "scr.color"));
r_config_set_b (origcfg, "scr.interactive", r_config_get_b (origcfg, "scr.interactive"));
#endif
core->http_up = 0; // DAT IS NOT TRUE AT ALL.. but its the way to enable visual
newoff = core->offset;
newblk = core->block;
@ -216,6 +213,10 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
void *bed = r_cons_sleep_begin ();
rs = r_socket_http_accept (s, &so);
if (!core->http_up) {
eprintf ("^C\n");
break;
}
r_cons_sleep_end (bed);
if (!rs) {
bed = r_cons_sleep_begin ();
@ -591,6 +592,7 @@ static RThreadFunctionRet r_core_rtr_http_thread(RThread *th) {
R_LOG_WARN ("Background webserver requires http.sandbox=false to run properly");
int ret = r_core_rtr_http_run (ht->core, ht->launch, ht->browse, ht->path);
R_FREE (ht->path);
#if 0
if (ret) {
int p = r_config_get_i (ht->core->config, "http.port");
r_config_set_i (ht->core->config, "http.port", p + 1);
@ -598,6 +600,7 @@ static RThreadFunctionRet r_core_rtr_http_thread(RThread *th) {
return R_TH_STOP;
}
}
#endif
return ret ? R_TH_REPEAT : R_TH_STOP;
}
#endif

View File

@ -421,7 +421,7 @@ R_API bool r_socket_connect(RSocket *s, const char *host, const char *port, int
}
freeaddrinfo (res);
if (!rp) {
R_LOG_ERROR ("Could not resolve address '%s' or failed to connect", host);
// R_LOG_ERROR ("Could not resolve address '%s' or failed to connect", host);
return false;
}
}

View File

@ -724,7 +724,7 @@ R_API int r_sys_cmd_str_full(const char *cmd, const char *input, int ilen, char
}
close (sh_err[1]);
close (sh_in[0]);
if (!inputptr || !*inputptr) {
if (R_STR_ISEMPTY (inputptr)) {
close (sh_in[1]);
}
// we should handle broken pipes somehow better