diff options
author | Costa Tsaousis <costa@netdata.cloud> | 2023-04-20 20:49:06 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-20 20:49:06 +0300 |
commit | c3d70ffcb43b62c95d71334ed49ad345ddf4360d (patch) | |
tree | 1f6645b504eae7801c8867d3af4d614135aa7602 /web | |
parent | 5b676d5f912fc27a126ff4ff6ba5b35da9cf930c (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.am | 1 | ||||
-rw-r--r-- | web/api/badges/web_buffer_svg.c | 4 | ||||
-rw-r--r-- | web/api/exporters/allmetrics.c | 4 | ||||
-rw-r--r-- | web/api/formatters/json_wrapper.c | 11 | ||||
-rw-r--r-- | web/api/health/health_cmdapi.c | 4 | ||||
-rw-r--r-- | web/api/queries/query.c | 5 | ||||
-rw-r--r-- | web/api/web_api.c | 29 | ||||
-rw-r--r-- | web/api/web_api.h | 2 | ||||
-rw-r--r-- | web/api/web_api_v1.c | 95 | ||||
-rw-r--r-- | web/api/web_api_v1.h | 2 | ||||
-rw-r--r-- | web/api/web_api_v2.c | 50 | ||||
-rw-r--r-- | web/api/web_api_v2.h | 2 | ||||
-rw-r--r-- | web/rtc/Makefile.am | 11 | ||||
-rw-r--r-- | web/rtc/README.md | 0 | ||||
-rw-r--r-- | web/rtc/webrtc.c | 740 | ||||
-rw-r--r-- | web/rtc/webrtc.h | 12 | ||||
-rw-r--r-- | web/server/static/static-threaded.c | 29 | ||||
-rw-r--r-- | web/server/web_client.c | 722 | ||||
-rw-r--r-- | web/server/web_client.h | 134 | ||||
-rw-r--r-- | web/server/web_client_cache.c | 309 | ||||
-rw-r--r-- | web/server/web_client_cache.h | 20 | ||||
-rw-r--r-- | web/server/web_server.c | 25 | ||||
-rw-r--r-- | web/server/web_server.h | 1 |
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/ |