summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@netdata.cloud>2023-04-20 20:49:06 +0300
committerGitHub <noreply@github.com>2023-04-20 20:49:06 +0300
commitc3d70ffcb43b62c95d71334ed49ad345ddf4360d (patch)
tree1f6645b504eae7801c8867d3af4d614135aa7602 /web
parent5b676d5f912fc27a126ff4ff6ba5b35da9cf930c (diff)
WEBRTC for communication between agents and browsers (#14874)
* initial webrtc setup * missing files * rewrite of webrtc integration * initialization and cleanup of webrtc connections * make it compile without libdatachannel * add missing webrtc_initialize() function when webrtc is not enabled * make c++17 optional * add build/m4/ax_compiler_vendor.m4 * add ax_cxx_compile_stdcxx.m4 * added new m4 files to makefile.am * id all webrtc connections * show warning when webrtc is disabled * fixed message * moved all webrtc error checking inside webrtc.cpp * working webrtc connection establishment and cleanup * remove obsolete code * rewrote webrtc code in C to remove dependency for c++17 * fixed left-over reference * detect binary and text messages * minor fix * naming of webrtc threads * added webrtc configuration * fix for thread_get_name_np() * smaller web_client memory footprint * universal web clients cache * free web clients every 100 uses * webrtc is now enabled by default only when compiled with internal checks * webrtc responses to /api/ requests, including LZ4 compression * fix for binary and text messages * web_client_cache is now global * unification of the internal web server API, for web requests, aclk request, webrtc requests * more cleanup and unification of web client timings * fixed compiler warnings * update sent and received bytes * eliminated of almost all big buffers in web client * registry now uses the new json generation * cookies are now an array; fixed redirects * fix redirects, again * write cookies directly to the header buffer, eliminating the need for cookie structures in web client * reset the has_cookies flag * gathered all web client cleanup to one function * fixes redirects * added summary.globals in /api/v2/data response * ars to arc in /api/v2/data * properly handle host impersonation * set the context of mem.numa_nodes
Diffstat (limited to 'web')
-rw-r--r--web/Makefile.am1
-rw-r--r--web/api/badges/web_buffer_svg.c4
-rw-r--r--web/api/exporters/allmetrics.c4
-rw-r--r--web/api/formatters/json_wrapper.c11
-rw-r--r--web/api/health/health_cmdapi.c4
-rw-r--r--web/api/queries/query.c5
-rw-r--r--web/api/web_api.c29
-rw-r--r--web/api/web_api.h2
-rw-r--r--web/api/web_api_v1.c95
-rw-r--r--web/api/web_api_v1.h2
-rw-r--r--web/api/web_api_v2.c50
-rw-r--r--web/api/web_api_v2.h2
-rw-r--r--web/rtc/Makefile.am11
-rw-r--r--web/rtc/README.md0
-rw-r--r--web/rtc/webrtc.c740
-rw-r--r--web/rtc/webrtc.h12
-rw-r--r--web/server/static/static-threaded.c29
-rw-r--r--web/server/web_client.c722
-rw-r--r--web/server/web_client.h134
-rw-r--r--web/server/web_client_cache.c309
-rw-r--r--web/server/web_client_cache.h20
-rw-r--r--web/server/web_server.c25
-rw-r--r--web/server/web_server.h1
23 files changed, 1542 insertions, 670 deletions
diff --git a/web/Makefile.am b/web/Makefile.am
index ccaccd764c..be2c545c35 100644
--- a/web/Makefile.am
+++ b/web/Makefile.am
@@ -7,6 +7,7 @@ SUBDIRS = \
api \
gui \
server \
+ rtc \
$(NULL)
usersslconfigdir=$(configdir)/ssl
diff --git a/web/api/badges/web_buffer_svg.c b/web/api/badges/web_buffer_svg.c
index 5a2a16c657..b69f35afac 100644
--- a/web/api/badges/web_buffer_svg.c
+++ b/web/api/badges/web_buffer_svg.c
@@ -898,10 +898,10 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
RRDSET *st = NULL;
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if(!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
diff --git a/web/api/exporters/allmetrics.c b/web/api/exporters/allmetrics.c
index 43a3dd78f3..cad52a7d57 100644
--- a/web/api/exporters/allmetrics.c
+++ b/web/api/exporters/allmetrics.c
@@ -39,10 +39,10 @@ inline int web_client_api_request_v1_allmetrics(RRDHOST *host, struct web_client
prometheus_prefix = global_exporting_prefix;
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if (!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
diff --git a/web/api/formatters/json_wrapper.c b/web/api/formatters/json_wrapper.c
index d94ef047d8..6bcbb8d5a5 100644
--- a/web/api/formatters/json_wrapper.c
+++ b/web/api/formatters/json_wrapper.c
@@ -226,7 +226,7 @@ static inline void query_target_points_statistics(BUFFER *wb, QUERY_TARGET *qt,
}
if(sp->anomaly_count != 0)
- buffer_json_member_add_double(wb, "ars", storage_point_anomaly_rate(*sp));
+ buffer_json_member_add_uint64(wb, "arc", sp->anomaly_count);
}
else {
NETDATA_DOUBLE avg = (sp->count) ? sp->sum / (NETDATA_DOUBLE)sp->count : 0.0;
@@ -804,12 +804,12 @@ static inline void rrdr_dimension_query_points_statistics(BUFFER *wb, const char
}
buffer_json_array_close(wb);
- buffer_json_member_add_array(wb, "ars");
+ buffer_json_member_add_array(wb, "arc");
for(size_t c = 0; c < r->d ; c++) {
if (!rrdr_dimension_should_be_exposed(r->od[c], options))
continue;
- buffer_json_add_array_item_uint64(wb, sp[c].anomaly_count * 100 / anomaly_rate_multiplier);
+ buffer_json_add_array_item_uint64(wb, storage_point_anomaly_rate(sp[c]) / anomaly_rate_multiplier / 100.0 * sp[c].count);
}
buffer_json_array_close(wb);
}
@@ -1384,6 +1384,11 @@ void rrdr_json_wrapper_begin2(RRDR *r, BUFFER *wb) {
query_target_summary_labels_v12(wb, qt, "labels", true, &label_key_totals, &label_key_value_totals);
query_target_summary_alerts_v2(wb, qt, "alerts");
}
+ if(query_target_aggregatable(qt)) {
+ buffer_json_member_add_object(wb, "globals");
+ query_target_points_statistics(wb, qt, &qt->query_points);
+ buffer_json_object_close(wb); // globals
+ }
buffer_json_object_close(wb); // summary
buffer_json_member_add_object(wb, "totals");
diff --git a/web/api/health/health_cmdapi.c b/web/api/health/health_cmdapi.c
index 54208e2b94..7c4869bd39 100644
--- a/web/api/health/health_cmdapi.c
+++ b/web/api/health/health_cmdapi.c
@@ -139,10 +139,10 @@ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, c
ret = HTTP_RESP_FORBIDDEN;
} else {
while (url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if (!value || !*value) continue;
- char *key = mystrsep(&value, "=");
+ char *key = strsep_skip_consecutive_separators(&value, "=");
if (!key || !*key) continue;
if (!value || !*value) continue;
diff --git a/web/api/queries/query.c b/web/api/queries/query.c
index e4fced812c..3223c1dc61 100644
--- a/web/api/queries/query.c
+++ b/web/api/queries/query.c
@@ -798,7 +798,7 @@ RRDR_GROUP_BY group_by_parse(char *s) {
RRDR_GROUP_BY group_by = RRDR_GROUP_BY_NONE;
while(s) {
- char *key = mystrsep(&s, ",| ");
+ char *key = strsep_skip_consecutive_separators(&s, ",| ");
if (!key || !*key) continue;
if (strcmp(key, "selected") == 0)
@@ -2720,6 +2720,7 @@ struct rrdr_group_by_entry {
};
static RRDR *rrd2rrdr_group_by_initialize(ONEWAYALLOC *owa, QUERY_TARGET *qt) {
+ RRDR *r_tmp = NULL;
RRDR_OPTIONS options = qt->window.options;
if(qt->request.version < 2) {
@@ -3013,7 +3014,7 @@ static RRDR *rrd2rrdr_group_by_initialize(ONEWAYALLOC *owa, QUERY_TARGET *qt) {
if(!first_r || !last_r)
goto cleanup;
- RRDR *r_tmp = rrdr_create(owa, qt, 1, qt->window.points);
+ r_tmp = rrdr_create(owa, qt, 1, qt->window.points);
if (!r_tmp) {
internal_error(true,
"QUERY: cannot create group by temporary RRDR for %s, after=%ld, before=%ld, dimensions=%d, points=%zu",
diff --git a/web/api/web_api.c b/web/api/web_api.c
index 7dd35717d4..7c1d0fa09d 100644
--- a/web/api/web_api.c
+++ b/web/api/web_api.c
@@ -2,27 +2,32 @@
#include "web_api.h"
-int web_client_api_request_vX(RRDHOST *host, struct web_client *w, char *url, struct web_api_command *api_commands) {
- if(unlikely(!url || !*url)) {
+int web_client_api_request_vX(RRDHOST *host, struct web_client *w, char *url_path_endpoint, struct web_api_command *api_commands) {
+ if(unlikely(!url_path_endpoint || !*url_path_endpoint)) {
buffer_flush(w->response.data);
buffer_sprintf(w->response.data, "Which API command?");
return HTTP_RESP_BAD_REQUEST;
}
- uint32_t hash = simple_hash(url);
+ uint32_t hash = simple_hash(url_path_endpoint);
for(int i = 0; api_commands[i].command ; i++) {
- if(unlikely(hash == api_commands[i].hash && !strcmp(url, api_commands[i].command))) {
+ if(unlikely(hash == api_commands[i].hash && !strcmp(url_path_endpoint, api_commands[i].command))) {
if(unlikely(api_commands[i].acl != WEB_CLIENT_ACL_NOCHECK) && !(w->acl & api_commands[i].acl))
return web_client_permission_denied(w);
- return api_commands[i].callback(host, w, (w->decoded_query_string + 1));
+ char *query_string = (char *)buffer_tostring(w->url_query_string_decoded);
+
+ if(*query_string == '?')
+ query_string = &query_string[1];
+
+ return api_commands[i].callback(host, w, query_string);
}
}
buffer_flush(w->response.data);
buffer_strcat(w->response.data, "Unsupported API command: ");
- buffer_strcat_htmlescape(w->response.data, url);
+ buffer_strcat_htmlescape(w->response.data, url_path_endpoint);
return HTTP_RESP_NOT_FOUND;
}
@@ -30,7 +35,7 @@ RRDCONTEXT_TO_JSON_OPTIONS rrdcontext_to_json_parse_options(char *o) {
RRDCONTEXT_TO_JSON_OPTIONS options = RRDCONTEXT_OPTION_NONE;
char *tok;
- while(o && *o && (tok = mystrsep(&o, ", |"))) {
+ while(o && *o && (tok = strsep_skip_consecutive_separators(&o, ", |"))) {
if(!*tok) continue;
if(!strcmp(tok, "full") || !strcmp(tok, "all"))
@@ -78,11 +83,11 @@ int web_client_api_request_weights(RRDHOST *host, struct web_client *w, char *ur
};
while (url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if (!value || !*value)
continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if (!name || !*name)
continue;
if (!value || !*value)
@@ -203,5 +208,9 @@ int web_client_api_request_weights(RRDHOST *host, struct web_client *w, char *ur
bool web_client_interrupt_callback(void *data) {
struct web_client *w = data;
+
+ if(w->interrupt.callback)
+ return w->interrupt.callback(w, w->interrupt.callback_data);
+
return sock_has_output_error(w->ofd);
-} \ No newline at end of file
+}
diff --git a/web/api/web_api.h b/web/api/web_api.h
index cc8f0ad6aa..0ca91841f0 100644
--- a/web/api/web_api.h
+++ b/web/api/web_api.h
@@ -18,7 +18,7 @@ struct web_api_command {
struct web_client;
-int web_client_api_request_vX(RRDHOST *host, struct web_client *w, char *url, struct web_api_command *api_commands);
+int web_client_api_request_vX(RRDHOST *host, struct web_client *w, char *url_path_endpoint, struct web_api_command *api_commands);
static inline void fix_google_param(char *s) {
if(unlikely(!s || !*s)) return;
diff --git a/web/api/web_api_v1.c b/web/api/web_api_v1.c
index 96657db4fe..3e4100aa8c 100644
--- a/web/api/web_api_v1.c
+++ b/web/api/web_api_v1.c
@@ -178,7 +178,7 @@ inline RRDR_OPTIONS web_client_api_request_v1_data_options(char *o) {
RRDR_OPTIONS ret = 0x00000000;
char *tok;
- while(o && *o && (tok = mystrsep(&o, ", |"))) {
+ while(o && *o && (tok = strsep_skip_consecutive_separators(&o, ", |"))) {
if(!*tok) continue;
uint32_t hash = simple_hash(tok);
@@ -262,7 +262,7 @@ inline uint32_t web_client_api_request_v1_data_google_format(char *name) {
int web_client_api_request_v1_alarms_select (char *url) {
int all = 0;
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if (!value || !*value) continue;
if(!strcmp(value, "all") || !strcmp(value, "all=true")) all = 1;
@@ -300,10 +300,10 @@ inline int web_client_api_request_v1_alarm_count(RRDHOST *host, struct web_clien
buffer_sprintf(w->response.data, "[");
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if(!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
@@ -341,10 +341,10 @@ inline int web_client_api_request_v1_alarm_log(RRDHOST *host, struct web_client
char *chart = NULL;
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if (!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
@@ -365,10 +365,10 @@ inline int web_client_api_request_single_chart(RRDHOST *host, struct web_client
buffer_flush(w->response.data);
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if(!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
@@ -419,10 +419,10 @@ static int web_client_api_request_v1_context(RRDHOST *host, struct web_client *w
buffer_flush(w->response.data);
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if(!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
@@ -483,10 +483,10 @@ static int web_client_api_request_v1_contexts(RRDHOST *host, struct web_client *
buffer_flush(w->response.data);
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if(!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
@@ -579,10 +579,10 @@ static inline int web_client_api_request_v1_data(RRDHOST *host, struct web_clien
RRDR_OPTIONS options = 0;
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if(!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
@@ -628,10 +628,10 @@ static inline int web_client_api_request_v1_data(RRDHOST *host, struct web_clien
char *tqx_name, *tqx_value;
while(value) {
- tqx_value = mystrsep(&value, ";");
+ tqx_value = strsep_skip_consecutive_separators(&value, ";");
if(!tqx_value || !*tqx_value) continue;
- tqx_name = mystrsep(&tqx_value, ":");
+ tqx_name = strsep_skip_consecutive_separators(&tqx_value, ":");
if(!tqx_name || !*tqx_name) continue;
if(!tqx_value || !*tqx_value) continue;
@@ -722,17 +722,10 @@ static inline int web_client_api_request_v1_data(RRDHOST *host, struct web_clien
goto cleanup;
}
- if (timeout) {
- struct timeval now;
- now_realtime_timeval(&now);
- int inqueue = (int)dt_usec(&w->tv_in, &now) / 1000;
- timeout -= inqueue;
- if (timeout <= 0) {
- buffer_flush(w->response.data);
- buffer_strcat(w->response.data, "Query timeout exceeded");
- ret = HTTP_RESP_BACKEND_FETCH_FAILED;
- goto cleanup;
- }
+ web_client_timeout_checkpoint_set(w, timeout);
+ if(web_client_timeout_checkpoint_and_check(w, NULL)) {
+ ret = w->response.code;
+ goto cleanup;
}
if(outFileName && *outFileName) {
@@ -851,10 +844,10 @@ inline int web_client_api_request_v1_registry(RRDHOST *host, struct web_client *
buffer_no_cacheable(w->response.data);
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if (!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if (!name || !*name) continue;
if (!value || !*value) continue;
@@ -1287,11 +1280,11 @@ int web_client_api_request_v1_function(RRDHOST *host, struct web_client *w, char
const char *function = NULL;
while (url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if (!value || !*value)
continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if (!name || !*name)
continue;
@@ -1426,46 +1419,46 @@ int web_client_api_request_v1_dbengine_stats(RRDHOST *host __maybe_unused, struc
#endif
static struct web_api_command api_commands_v1[] = {
- { "info", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_info },
- { "data", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_data },
- { "chart", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_chart },
- { "charts", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_charts },
- { "context", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_context },
- { "contexts", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_contexts },
+ { "info", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_info },
+ { "data", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_data },
+ { "chart", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_chart },
+ { "charts", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_charts },
+ { "context", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_context },
+ { "contexts", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_contexts },
// registry checks the ACL by itself, so we allow everything
{ "registry", 0, WEB_CLIENT_ACL_NOCHECK, web_client_api_request_v1_registry },
// badges can be fetched with both dashboard and badge permissions
- { "badge.svg", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_badge },
+ { "badge.svg", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC | WEB_CLIENT_ACL_BADGE, web_client_api_request_v1_badge },
- { "alarms", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_alarms },
- { "alarms_values", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_alarms_values },
- { "alarm_log", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_alarm_log },
- { "alarm_variables", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_alarm_variables },
- { "alarm_count", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_alarm_count },
- { "allmetrics", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_allmetrics },
+ { "alarms", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_alarms },
+ { "alarms_values", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_alarms_values },
+ { "alarm_log", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_alarm_log },
+ { "alarm_variables", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_alarm_variables },
+ { "alarm_count", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_alarm_count },
+ { "allmetrics", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_allmetrics },
#if defined(ENABLE_ML)
- { "ml_info", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_ml_info },
+ { "ml_info", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_ml_info },
{ "ml_models", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_ml_models },
#endif
{ "manage/health", 0, WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_mgmt_health },
- { "aclk", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_aclk_state },
- { "metric_correlations", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_metric_correlations },
- { "weights", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_weights },
+ { "aclk", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_aclk_state },
+ { "metric_correlations", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_metric_correlations },
+ { "weights", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_weights },
{ "function", 0, WEB_CLIENT_ACL_ACLK | ACL_DEV_OPEN_ACCESS, web_client_api_request_v1_function },
{ "functions", 0, WEB_CLIENT_ACL_ACLK | ACL_DEV_OPEN_ACCESS, web_client_api_request_v1_functions },
- { "dbengine_stats", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v1_dbengine_stats },
+ { "dbengine_stats", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v1_dbengine_stats },
// terminator
{ NULL, 0, WEB_CLIENT_ACL_NONE, NULL },
};
-inline int web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *url) {
+inline int web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *url_path_endpoint) {
static int initialized = 0;
if(unlikely(initialized == 0)) {
@@ -1475,5 +1468,5 @@ inline int web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *
api_commands_v1[i].hash = simple_hash(api_commands_v1[i].command);
}
- return web_client_api_request_vX(host, w, url, api_commands_v1);
+ return web_client_api_request_vX(host, w, url_path_endpoint, api_commands_v1);
}
diff --git a/web/api/web_api_v1.h b/web/api/web_api_v1.h
index 4ac36f610e..6fa8de017f 100644
--- a/web/api/web_api_v1.h
+++ b/web/api/web_api_v1.h
@@ -24,7 +24,7 @@ int web_client_api_request_v1_charts(RRDHOST *host, struct web_client *w, char *
int web_client_api_request_v1_chart(RRDHOST *host, struct web_client *w, char *url);
int web_client_api_request_v1_registry(RRDHOST *host, struct web_client *w, char *url);
int web_client_api_request_v1_info(RRDHOST *host, struct web_client *w, char *url);
-int web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *url);
+int web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *url_path_endpoint);
int web_client_api_request_v1_info_fill_buffer(RRDHOST *host, BUFFER *wb);
void web_client_api_v1_init(void);
diff --git a/web/api/web_api_v2.c b/web/api/web_api_v2.c
index f05132e3d9..7280c04270 100644
--- a/web/api/web_api_v2.c
+++ b/web/api/web_api_v2.c
@@ -1,15 +1,16 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "web_api_v2.h"
+#include "../rtc/webrtc.h"
static int web_client_api_request_v2_contexts_internal(RRDHOST *host __maybe_unused, struct web_client *w, char *url, CONTEXTS_V2_OPTIONS options) {
struct api_v2_contexts_request req = { 0 };
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if(!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
@@ -110,10 +111,10 @@ static int web_client_api_request_v2_data(RRDHOST *host __maybe_unused, struct w
size_t group_by_idx = 0, group_by_label_idx = 0, aggregation_idx = 0;
while(url) {
- char *value = mystrsep(&url, "&");
+ char *value = strsep_skip_consecutive_separators(&url, "&");
if(!value || !*value) continue;
- char *name = mystrsep(&value, "=");
+ char *name = strsep_skip_consecutive_separators(&value, "=");
if(!name || !*name) continue;
if(!value || !*value) continue;
@@ -161,10 +162,10 @@ static int web_client_api_request_v2_data(RRDHOST *host __maybe_unused, struct w
char *tqx_name, *tqx_value;
while(value) {
- tqx_value = mystrsep(&value, ";");
+ tqx_value = strsep_skip_consecutive_separators(&value, ";");
if(!tqx_value || !*tqx_value) continue;
- tqx_name = mystrsep(&tqx_value, ":");
+ tqx_name = strsep_skip_consecutive_separators(&tqx_value, ":");
if(!tqx_name || !*tqx_name) continue;
if(!tqx_value || !*tqx_value) continue;
@@ -235,7 +236,7 @@ static int web_client_api_request_v2_data(RRDHOST *host __maybe_unused, struct w
time_t before = (before_str && *before_str)?str2l(before_str):0;
time_t after = (after_str && *after_str) ?str2l(after_str):-600;
size_t points = (points_str && *points_str)?str2u(points_str):0;
- time_t timeout = (timeout_str && *timeout_str)?str2l(timeout_str): 0;
+ int timeout = (timeout_str && *timeout_str)?str2i(timeout_str): 0;
time_t resampling_time = (resampling_time_str && *resampling_time_str) ? str2l(resampling_time_str) : 0;
QUERY_TARGET_REQUEST qtr = {
@@ -281,17 +282,10 @@ static int web_client_api_request_v2_data(RRDHOST *host __maybe_unused, struct w
goto cleanup;
}
- if (timeout) {
- struct timeval now;
- now_realtime_timeval(&now);
- int inqueue = (int)dt_usec(&w->tv_in, &now) / 1000;
- timeout -= inqueue;
- if (timeout <= 0) {
- buffer_flush(w->response.data);
- buffer_strcat(w->response.data, "Query timeout exceeded");
- ret = HTTP_RESP_BACKEND_FETCH_FAILED;
- goto cleanup;
- }
+ web_client_timeout_checkpoint_set(w, timeout);
+ if(web_client_timeout_checkpoint_and_check(w, NULL)) {
+ ret = w->response.code;
+ goto cleanup;
}
if(outFileName && *outFileName) {
@@ -347,20 +341,24 @@ cleanup:
return ret;
}
-
+static int web_client_api_request_v2_webrtc(RRDHOST *host __maybe_unused, struct web_client *w, char *url __maybe_unused) {
+ return webrtc_new_connection(w->post_payload, w->response.data);
+}
static struct web_api_command api_commands_v2[] = {
- {"data", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v2_data},
- {"nodes", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v2_nodes},
- {"contexts", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v2_contexts},
- {"weights", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v2_weights},
- {"q", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v2_q},
+ {"data", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v2_data},
+ {"nodes", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v2_nodes},
+ {"contexts", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v2_contexts},
+ {"weights", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v2_weights},
+ {"q", 0, WEB_CLIENT_ACL_DASHBOARD_ACLK_WEBRTC, web_client_api_request_v2_q},
+
+ {"rtc_offer", 0, WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_ACLK, web_client_api_request_v2_webrtc},
// terminator
{NULL, 0, WEB_CLIENT_ACL_NONE, NULL},
};
-inline int web_client_api_request_v2(RRDHOST *host, struct web_client *w, char *url) {
+inline int web_client_api_request_v2(RRDHOST *host, struct web_client *w, char *url_path_endpoint) {
static int initialized = 0;
if(unlikely(initialized == 0)) {
@@ -370,5 +368,5 @@ inline int web_client_api_request_v2(RRDHOST *host, struct web_client *w, char *
api_commands_v2[i].hash = simple_hash(api_commands_v2[i].command);
}
- return web_client_api_request_vX(host, w, url, api_commands_v2);
+ return web_client_api_request_vX(host, w, url_path_endpoint, api_commands_v2);
}
diff --git a/web/api/web_api_v2.h b/web/api/web_api_v2.h
index 4097026bf8..4a1893bd85 100644
--- a/web/api/web_api_v2.h
+++ b/