summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libnetdata/inlined.h28
-rw-r--r--libnetdata/url/url.c85
-rw-r--r--libnetdata/url/url.h22
-rw-r--r--tests/urls/requests.sh207
-rw-r--r--web/api/badges/web_buffer_svg.c97
-rw-r--r--web/api/exporters/allmetrics.c79
-rw-r--r--web/api/health/health_cmdapi.c145
-rw-r--r--web/api/web_api_v1.c312
-rw-r--r--web/server/web_client.c513
-rw-r--r--web/server/web_client.h12
10 files changed, 1056 insertions, 444 deletions
diff --git a/libnetdata/inlined.h b/libnetdata/inlined.h
index 6a5994c12a..a9c3e472e4 100644
--- a/libnetdata/inlined.h
+++ b/libnetdata/inlined.h
@@ -31,6 +31,19 @@ static inline uint32_t simple_hash(const char *name) {
return hval;
}
+static inline uint32_t simple_nhash(const char *name,size_t len) {
+ unsigned char *s = (unsigned char *) name;
+ size_t i;
+ uint32_t hval = 0x811c9dc5;
+ i = 0;
+ do {
+ hval *= 16777619;
+ hval ^= (uint32_t) *s++;
+ } while (++i < len);
+
+ return hval;
+}
+
static inline uint32_t simple_uhash(const char *name) {
unsigned char *s = (unsigned char *) name;
uint32_t hval = 0x811c9dc5, c;
@@ -42,6 +55,21 @@ static inline uint32_t simple_uhash(const char *name) {
return hval;
}
+static inline uint32_t simple_nuhash(const char *name,size_t len) {
+ unsigned char *s = (unsigned char *) name;
+ size_t i;
+ uint32_t hval = 0x811c9dc5, c;
+
+ i = 0;
+ do {
+ c = *s++;
+ if (unlikely(c >= 'A' && c <= 'Z')) c += 'a' - 'A';
+ hval *= 16777619;
+ hval ^= c;
+ } while ( ++i < len);
+ return hval;
+}
+
static inline int simple_hash_strcmp(const char *name, const char *b, uint32_t *hash) {
unsigned char *s = (unsigned char *) name;
uint32_t hval = 0x811c9dc5;
diff --git a/libnetdata/url/url.c b/libnetdata/url/url.c
index 07a9f8069e..fb1fb7f07a 100644
--- a/libnetdata/url/url.c
+++ b/libnetdata/url/url.c
@@ -79,3 +79,88 @@ char *url_decode_r(char *to, char *url, size_t size) {
return to;
}
+
+inline HTTP_VALIDATION url_is_request_complete(char *begin,char *end,size_t length) {
+ if ( begin == end) {
+ return HTTP_VALIDATION_INCOMPLETE;
+ }
+
+ if ( length > 3 ) {
+ begin = end - 4;
+ }
+
+ uint32_t counter = 0;
+ do {
+ if (*begin == '\r') {
+ begin++;
+ if ( begin == end )
+ {
+ break;
+ }
+
+ if (*begin == '\n')
+ {
+ counter++;
+ }
+ } else if (*begin == '\n') {
+ begin++;
+ counter++;
+ }
+
+ if ( counter == 2) {
+ break;
+ }
+ }
+ while (begin != end);
+
+ return (counter == 2)?HTTP_VALIDATION_OK:HTTP_VALIDATION_INCOMPLETE;
+}
+
+inline char *url_find_protocol(char *s) {
+ while(*s) {
+ // find the next space
+ while (*s && *s != ' ') s++;
+
+ // is it SPACE + "HTTP/" ?
+ if(*s && !strncmp(s, " HTTP/", 6)) break;
+ else s++;
+ }
+
+ return s;
+}
+
+int url_parse_query_string(struct web_fields *names,struct web_fields *values,char *moveme,char *divisor) {
+ uint32_t i = 0;
+ uint32_t max = WEB_FIELDS_MAX;
+
+ do {
+ if ( i == max) {
+ error("We are exceeding the maximum number of elements possible(%u) in this query string(%s)",max,moveme);
+ break;
+ }
+ if (divisor) {
+ names[i].body = moveme;
+ names[i].length = divisor - moveme;//= - begin
+
+ moveme = ++divisor; //value
+ values[i].body = moveme;
+
+ (void)divisor;
+ divisor = strchr(moveme,'&'); //end of value
+ if (divisor) {
+ values[i].length = (size_t )(divisor - moveme);
+ } else{
+ values[i].length = strlen(moveme);
+ break;
+ }
+
+ moveme = divisor;
+ divisor = strchr(++moveme,'='); //end of value
+ i++;
+ } else {
+ break;
+ }
+ } while (moveme);
+
+ return ++i;
+}
diff --git a/libnetdata/url/url.h b/libnetdata/url/url.h
index 6cef6d7a84..9e86c20cfd 100644
--- a/libnetdata/url/url.h
+++ b/libnetdata/url/url.h
@@ -25,4 +25,26 @@ extern char *url_decode(char *str);
extern char *url_decode_r(char *to, char *url, size_t size);
+#define WEB_FIELDS_MAX 200
+struct web_fields{
+ char *body;
+ size_t length;
+};
+// http_request_validate()
+// returns:
+// = 0 : all good, process the request
+// > 0 : request is not supported
+// < 0 : request is incomplete - wait for more data
+
+typedef enum {
+ HTTP_VALIDATION_OK,
+ HTTP_VALIDATION_NOT_SUPPORTED,
+ HTTP_VALIDATION_INCOMPLETE,
+ HTTP_VALIDATION_REDIRECT
+} HTTP_VALIDATION;
+
+extern HTTP_VALIDATION url_is_request_complete(char *begin,char *end,size_t length);
+extern char *url_find_protocol(char *s);
+extern int url_parse_query_string(struct web_fields *names,struct web_fields *values,char *moveme,char *divisor);
+
#endif /* NETDATA_URL_H */
diff --git a/tests/urls/requests.sh b/tests/urls/requests.sh
new file mode 100644
index 0000000000..2e1a957a88
--- /dev/null
+++ b/tests/urls/requests.sh
@@ -0,0 +1,207 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+################################################################################################
+#### ####
+#### GLOBAL VARIABLES ####
+#### ####
+################################################################################################
+
+NETDATA_VARLIB_DIR="@varlibdir_POST@"
+
+#CT=`date +'%s%N' |cut -b1-13`
+# The current time
+CT=`date +'%s'`
+
+# The previous time
+PT=$(( $CT - 100))
+
+# The curl options used to do download
+CURLOPTS="-v --create-dirs -o"
+
+# The output directory where we will store the results and error
+OUTDIR="tests"
+
+################################################################################################
+#### ####
+#### FUNCTIONS ####
+#### ####
+################################################################################################
+
+# Print error message and close script
+netdata_print_error(){
+ echo "Closing due error \"$1\" code \"$2\""
+ exit 1
+}
+
+# Print the header message of the function
+netdata_print_header() {
+ echo "$1"
+}
+
+# Create the main directory where the results will be stored
+netdata_create_directory() {
+ netdata_print_header "Creating directory $1"
+ if [ ! -d $1 ]; then
+ mkdir $1
+ if [ $? -ne 0 ]; then
+ netdata_print_error "Cannot create directory" $?
+ fi
+ else
+ echo "Working with directory $OUTDIR"
+ fi
+}
+
+netdata_test_download(){
+ grep "HTTP/1.1 200 OK" $1 2>/dev/null 1>/dev/null
+ if [ $? -ne 0 ]; then
+ netdata_print_error "Cannot do download of the page $2" $?
+ fi
+}
+
+# Download information from Netdata
+netdata_download_various() {
+ netdata_print_header "Getting $2"
+ curl $CURLOPTS $OUTDIR/$3.out "$1/$2" 2> $OUTDIR/$3.err
+ netdata_test_download $OUTDIR/$3.err "$1/$2"
+}
+
+# Download charts from Netdata
+netdata_download_charts() {
+ curl $CURLOPTS $OUTDIR/charts.out "$1/$2/charts" 2> $OUTDIR/charts.err
+ netdata_test_download $OUTDIR/charts.err "$1/$2/charts"
+
+ #Rewrite the next
+ cat tests/charts.out | grep -w "id"| cut -d: -f2 | grep "\"," | sed s/,//g | sort
+}
+
+#Test options for a specific chart
+netdata_download_chart() {
+ NAME=`echo $3| sed s/\"//g`
+ netdata_print_header "Getting data for $NAME using $4"
+
+ LDIR=$OUTDIR"/"$4
+
+ LURL=$1/$2=$NAME
+
+ NAME=$NAME"_$4"
+
+ curl $CURLOPTS $LDIR/$NAME.out "$LURL" 2> $LDIR/$NAME.err
+ netdata_test_download $LDIR/$NAME.err $LURL
+
+ UFILES=( "points" "before" "after" )
+ COUNTER=0
+ for OPT in "&points=100" "&before=$PT" "&after=$CT" ;
+ do
+ LURL="$LURL$OPT"
+ LFILE=$NAME"_${UFILES[$COUNTER]}";
+
+ curl $CURLOPTS "$LDIR/$LFILE.out" "$LURL" 2> "$LDIR/$LFILE.err"
+ netdata_test_download $LDIR/$LFILE.err $LURL
+
+ COUNTER=$(($COUNTER + 1))
+ done
+
+ LURL="$LURL&group="
+ for OPT in "min" "max" "sum" "median" "stddev" "cv" "ses" "des" "incremental_sum" "average";
+ do
+ TURL=$LURL$OPT
+ TFILE=$NAME"_$OPT";
+ curl $CURLOPTS "$LDIR/$TFILE.out" "$TURL" 2> "$LDIR/$TFILE.err"
+ netdata_test_download $LDIR/$TFILE.err $TURL
+ for MORE in "jsonp" "json" "ssv" "csv" "datatable" "datasource" "tsv" "ssvcomma" "html" "array";
+ do
+ TURL=$TURL"&format="$MORE
+ TFILE=$NAME"_$OPT""_$MORE";
+ curl $CURLOPTS "$LDIR/$TFILE.out" "$TURL" 2> "$LDIR/$TFILE.err"
+ netdata_test_download $LDIR/$TFILE.err $TURL
+ done
+
+ done
+
+ LURL="$LURL$OPT&gtime=60"
+ NFILE=$NAME"_gtime"
+ curl $CURLOPTS "$LDIR/$NFILE.out" "$TURL" 2> "$LDIR/$NFILE.err"
+ netdata_test_download $LDIR/$NFILE.err $LURL
+
+ LURL="$LURL$OPT&options=percentage"
+ NFILE=$NAME"_percentage"
+ curl $CURLOPTS "$LDIR/$NFILE.out" "$TURL" 2> "$LDIR/$NFILE.err"
+ netdata_test_download $LDIR/$NFILE.err $LURL
+
+ LURL="$LURL$OPT&options=percentage"
+ NFILE=$NAME"_percentage"
+ curl $CURLOPTS "$LDIR/$NFILE.out" "$TURL" 2> "$LDIR/$NFILE.err"
+ netdata_test_download $LDIR/$NFILE.err $LURL
+
+ LURL="$LURL$OPT&dimensions=system%7Cnice"
+ NFILE=$NAME"_dimension"
+ curl $CURLOPTS "$LDIR/$NFILE.out" "$TURL" 2> "$LDIR/$NFILE.err"
+ netdata_test_download $LDIR/$NFILE.err $LURL
+
+}
+
+# Download information from Netdata
+netdata_download_allmetrics() {
+ netdata_print_header "Getting All metrics"
+ curl $CURLOPTS $OUTDIR/allmetrics.out "$1/$2" 2> $OUTDIR/allmetrics.err
+ netdata_test_download $OUTDIR/allmetrics.err "$1/$2"
+}
+
+# Download charts from Netdata
+
+################################################################################################
+#### ####
+#### MAIN ROUTINE ####
+#### ####
+################################################################################################
+MURL="http://127.0.0.1:19999"
+
+wget --execute="robots = off" --mirror --convert-links --no-parent http://127.0.0.1:19999
+
+netdata_create_directory $OUTDIR
+
+netdata_download_various $MURL "netdata.conf" "netdata.conf"
+
+netdata_download_various $MURL "api/v1/info" "info"
+
+netdata_download_various $MURL "api/v1/registry?action=hello" "action"
+
+netdata_print_header "Getting all the netdata charts"
+CHARTS=$( netdata_download_charts "http://127.0.0.1:19999" "api/v1" )
+
+netdata_download_various $MURL "api/v1/allmetrics?format=json" "allmetrics"
+
+netdata_download_various $MURL "api/v1/alarms?all" "alarms_all"
+
+netdata_download_various $MURL "api/v1/alarms?active" "alarms_active"
+
+netdata_download_various $MURL "api/v1/alarm_log?after&_=$PT" "alarm_log"
+
+for I in $CHARTS ; do
+ NAME=`echo $I| sed s/\"//g`
+ netdata_download_various $MURL "api/v1/alarm_variables?chart=$NAME" "alarm_variables_$NAME"
+done
+
+netdata_create_directory "$OUTDIR/data"
+for I in $CHARTS ; do
+ netdata_download_chart $MURL "api/v1/data?chart" $I "data"
+done
+
+netdata_create_directory "$OUTDIR/badge.svg"
+for I in $CHARTS ; do
+ netdata_download_chart $MURL "api/v1/badge.svg?chart" $I "badge.svg"
+done
+
+if [ -f "${NETDATA_VARLIB_DIR}/netdata.api.key" ] ;then
+ read -r CORRECT_TOKEN < "${NETDATA_VARLIB_DIR}/netdata.api.key"
+else
+ echo "${NETDATA_VARLIB_DIR}/netdata.api.key not found"
+ echo "Token not found."
+ exit 2
+fi
+curl -H "X-Auth-Token: $TOKEN" "http://127.0.0.1:19999/api/v1/manage/health?cmd=RESET"
+
+echo "ALL the URLS got 200 as answer!"
+
+exit 0
diff --git a/web/api/badges/web_buffer_svg.c b/web/api/badges/web_buffer_svg.c
index b24fddedf5..d24e2820ef 100644
--- a/web/api/badges/web_buffer_svg.c
+++ b/web/api/badges/web_buffer_svg.c
@@ -889,6 +889,7 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
}
int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *url) {
+ (void)url;
int ret = 400;
buffer_flush(w->response.data);
@@ -912,46 +913,54 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
int group = RRDR_GROUPING_AVERAGE;
uint32_t options = 0x00000000;
- while(url) {
- char *value = mystrsep(&url, "&");
- if(!value || !*value) continue;
-
- char *name = mystrsep(&value, "=");
- if(!name || !*name) continue;
- if(!value || !*value) continue;
-
- debug(D_WEB_CLIENT, "%llu: API v1 badge.svg query param '%s' with value '%s'", w->id, name, value);
-
- // name and value are now the parameters
- // they are not null and not empty
-
- if(!strcmp(name, "chart")) chart = value;
- else if(!strcmp(name, "dimension") || !strcmp(name, "dim") || !strcmp(name, "dimensions") || !strcmp(name, "dims")) {
- if(!dimensions)
- dimensions = buffer_create(100);
-
- buffer_strcat(dimensions, "|");
- buffer_strcat(dimensions, value);
- }
- else if(!strcmp(name, "after")) after_str = value;
- else if(!strcmp(name, "before")) before_str = value;
- else if(!strcmp(name, "points")) points_str = value;
- else if(!strcmp(name, "group")) {
- group = web_client_api_request_v1_data_group(value, RRDR_GROUPING_AVERAGE);
- }
- else if(!strcmp(name, "options")) {
- options |= web_client_api_request_v1_data_options(value);
- }
- else if(!strcmp(name, "label")) label = value;
- else if(!strcmp(name, "units")) units = value;
- else if(!strcmp(name, "label_color")) label_color = value;
- else if(!strcmp(name, "value_color")) value_color = value;
- else if(!strcmp(name, "multiply")) multiply_str = value;
- else if(!strcmp(name, "divide")) divide_str = value;
- else if(!strcmp(name, "refresh")) refresh_str = value;
- else if(!strcmp(name, "precision")) precision_str = value;
- else if(!strcmp(name, "scale")) scale_str = value;
- else if(!strcmp(name, "alarm")) alarm = value;
+ uint32_t i = 0;
+ uint32_t end = w->total_params;
+ char save[WEB_FIELDS_MAX];
+ char *value;
+ size_t lvalue;
+ if(end) {
+ do {
+ value = w->param_values[i].body;
+ lvalue = w->param_values[i].length;
+ save[i] = value[lvalue];
+ value[lvalue] = 0x00;
+
+ char *name = w->param_name[i].body;
+ size_t lname = w->param_name[i].length;
+
+ debug(D_WEB_CLIENT, "%llu: API v1 badge.svg query param '%s' with value '%s'", w->id, name, value);
+
+ // name and value are now the parameters
+ // they are not null and not empty
+ if(!strncmp(name, "chart",lname)) chart = value;
+ else if(!strncmp(name, "dimension",lname) || !strncmp(name, "dim",lname) || !strncmp(name, "dimensions",lname) || !strncmp(name, "dims",lname)) {
+ if(!dimensions)
+ dimensions = buffer_create(100);
+
+ buffer_strcat(dimensions, "|");
+ buffer_strcat(dimensions, value);
+ }
+ else if(!strncmp(name, "after",lname)) after_str = value;
+ else if(!strncmp(name, "before",lname)) before_str = value;
+ else if(!strncmp(name, "points",lname)) points_str = value;
+ else if(!strncmp(name, "group",lname)) {
+ group = web_client_api_request_v1_data_group(value, RRDR_GROUPING_AVERAGE);
+ }
+ else if(!strncmp(name, "options",lname)) {
+ options |= web_client_api_request_v1_data_options(value);
+ }
+ else if(!strncmp(name, "label",lname)) label = value;
+ else if(!strncmp(name, "units",lname)) units = value;
+ else if(!strncmp(name, "label_color",lname)) label_color = value;
+ else if(!strncmp(name, "value_color",lname)) value_color = value;
+ else if(!strncmp(name, "multiply",lname)) multiply_str = value;
+ else if(!strncmp(name, "divide",lname)) divide_str = value;
+ else if(!strncmp(name, "refresh",lname)) refresh_str = value;
+ else if(!strncmp(name, "precision",lname)) precision_str = value;
+ else if(!strncmp(name, "scale",lname)) scale_str = value;
+ else if(!strncmp(name, "alarm",lname)) alarm = value;
+
+ } while (++i < end );
}
if(!chart || !*chart) {
@@ -1137,6 +1146,14 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
}
cleanup:
+ if(end) {
+ i = 0;
+ do {
+ value = w->param_values[i].body;
+ lvalue = w->param_values[i].length;
+ value[lvalue] = save[i];
+ } while(++i < end);
+ }
buffer_free(dimensions);
return ret;
}
diff --git a/web/api/exporters/allmetrics.c b/web/api/exporters/allmetrics.c
index 88ff78e7e4..17e5e077eb 100644
--- a/web/api/exporters/allmetrics.c
+++ b/web/api/exporters/allmetrics.c
@@ -18,54 +18,57 @@ struct prometheus_output_options {
};
inline int web_client_api_request_v1_allmetrics(RRDHOST *host, struct web_client *w, char *url) {
+ (void)url;
int format = ALLMETRICS_SHELL;
const char *prometheus_server = w->client_ip;
uint32_t prometheus_backend_options = global_backend_options;
PROMETHEUS_OUTPUT_OPTIONS prometheus_output_options = PROMETHEUS_OUTPUT_TIMESTAMPS | ((global_backend_options & BACKEND_OPTION_SEND_NAMES)?PROMETHEUS_OUTPUT_NAMES:0);
const char *prometheus_prefix = global_backend_prefix;
- while(url) {
- char *value = mystrsep(&url, "&");
- if (!value || !*value) continue;
+ uint32_t end = w->total_params;
+ if (end) {
+ uint32_t i = 0;
+ do {
+ char *name = w->param_name[i].body;
+ size_t lname = w->param_name[i].length;
+ char *value = w->param_values[i].body;
+ size_t lvalue = w->param_values[i].length;
- char *name = mystrsep(&value, "=");
- if(!name || !*name) continue;
- if(!value || !*value) continue;
-
- if(!strcmp(name, "format")) {
- if(!strcmp(value, ALLMETRICS_FORMAT_SHELL))
- format = ALLMETRICS_SHELL;
- else if(!strcmp(value, ALLMETRICS_FORMAT_PROMETHEUS))
- format = ALLMETRICS_PROMETHEUS;
- else if(!strcmp(value, ALLMETRICS_FORMAT_PROMETHEUS_ALL_HOSTS))
- format = ALLMETRICS_PROMETHEUS_ALL_HOSTS;
- else if(!strcmp(value, ALLMETRICS_FORMAT_JSON))
- format = ALLMETRICS_JSON;
- else
- format = 0;
- }
- else if(!strcmp(name, "server")) {
- prometheus_server = value;
- }
- else if(!strcmp(name, "prefix")) {
- prometheus_prefix = value;
- }
- else if(!strcmp(name, "data") || !strcmp(name, "source") || !strcmp(name, "data source") || !strcmp(name, "data-source") || !strcmp(name, "data_source") || !strcmp(name, "datasource")) {
- prometheus_backend_options = backend_parse_data_source(value, prometheus_backend_options);
- }
- else {
- int i;
- for(i = 0; prometheus_output_flags_root[i].name ; i++) {
- if(!strcmp(name, prometheus_output_flags_root[i].name)) {
- if(!strcmp(value, "yes") || !strcmp(value, "1") || !strcmp(value, "true"))
- prometheus_output_options |= prometheus_output_flags_root[i].flag;
- else
- prometheus_output_options &= ~prometheus_output_flags_root[i].flag;
+ if(!strncmp(name, "format",lname)) {
+ if(!strncmp(value, ALLMETRICS_FORMAT_SHELL,lvalue))
+ format = ALLMETRICS_SHELL;
+ else if(!strncmp(value, ALLMETRICS_FORMAT_PROMETHEUS,lvalue))
+ format = ALLMETRICS_PROMETHEUS;
+ else if(!strncmp(value, ALLMETRICS_FORMAT_PROMETHEUS_ALL_HOSTS,lvalue))
+ format = ALLMETRICS_PROMETHEUS_ALL_HOSTS;
+ else if(!strncmp(value, ALLMETRICS_FORMAT_JSON,lvalue))
+ format = ALLMETRICS_JSON;
+ else
+ format = 0;
+ }
+ else if(!strncmp(name, "server",lname)) {
+ prometheus_server = value;
+ }
+ else if(!strncmp(name, "prefix",lname)) {
+ prometheus_prefix = value;
+ }
+ else if(!strncmp(name, "data",lname) || !strncmp(name, "source",lname) || !strncmp(name, "data source",lname) || !strncmp(name, "data-source",lname) || !strncmp(name, "data_source",lname) || !strncmp(name, "datasource",lname)) {
+ prometheus_backend_options = backend_parse_data_source(value, prometheus_backend_options);
+ }
+ else {
+ int i;
+ for(i = 0; prometheus_output_flags_root[i].name ; i++) {
+ if(!strncmp(name, prometheus_output_flags_root[i].name,lname)) {
+ if(!strncmp(value, "yes",lvalue) || !strncmp(value, "1",lvalue) || !strncmp(value, "true",lvalue))
+ prometheus_output_options |= prometheus_output_flags_root[i].flag;
+ else
+ prometheus_output_options &= ~prometheus_output_flags_root[i].flag;
- break;
+ break;
+ }
}
}
- }
+ } while( ++i < end);
}
buffer_flush(w->response.data);
diff --git a/web/api/health/health_cmdapi.c b/web/api/health/health_cmdapi.c
index ec177751b9..eac3daf06b 100644
--- a/web/api/health/health_cmdapi.c
+++ b/web/api/health/health_cmdapi.c
@@ -31,13 +31,10 @@ void free_silencers(SILENCER *t) {
return;
}
-
-
int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, char *url) {
int ret = 400;
(void) host;
-
-
+ (void)url;
BUFFER *wb = w->response.data;
buffer_flush(wb);
@@ -73,75 +70,86 @@ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, c
buffer_strcat(wb, HEALTH_CMDAPI_MSG_AUTHERROR);
ret = 403;
} else {
- while (url) {
- char *value = mystrsep(&url, "&");
- if (!value || !*value) continue;
-
- char *key = mystrsep(&value, "=");
- if (!key || !*key) continue;
- if (!value || !*value) continue;
-
- debug(D_WEB_CLIENT, "%llu: API v1 health query param '%s' with value '%s'", w->id, key, value);
-
- // name and value are now the parameters
- if (!strcmp(key, "cmd")) {
- if (!strcmp(value, HEALTH_CMDAPI_CMD_SILENCEALL)) {
- silencers->all_alarms = 1;
- silencers->stype = STYPE_SILENCE_NOTIFICATIONS;
- buffer_strcat(wb, HEALTH_CMDAPI_MSG_SILENCEALL);
- } else if (!strcmp(value, HEALTH_CMDAPI_CMD_DISABLEALL)) {
- silencers->all_alarms = 1;
- silencers->stype = STYPE_DISABLE_ALARMS;
- buffer_strcat(wb, HEALTH_CMDAPI_MSG_DISABLEALL);
- } else if (!strcmp(value, HEALTH_CMDAPI_CMD_SILENCE)) {
- silencers->stype = STYPE_SILENCE_NOTIFICATIONS;
- buffer_strcat(wb, HEALTH_CMDAPI_MSG_SILENCE);
- } else if (!strcmp(value, HEALTH_CMDAPI_CMD_DISABLE)) {
- silencers->stype = STYPE_DISABLE_ALARMS;
- buffer_strcat(wb, HEALTH_CMDAPI_MSG_DISABLE);
- } else if (!strcmp(value, HEALTH_CMDAPI_CMD_RESET)) {
- silencers->all_alarms = 0;
- silencers->stype = STYPE_NONE;
- free_silencers(silencers->silencers);
- silencers->silencers = NULL;
- buffer_strcat(wb, HEALTH_CMDAPI_MSG_RESET);
- }
- } else {
- uint32_t hash = simple_uhash(key);
- if (unlikely(silencer == NULL)) {
- if (
- (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) ||
- (hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) ||
- (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) ||
- (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) ||
- (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) ||
- (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY))
- ) {
- silencer = create_silencer();
+ uint32_t end = w->total_params;
+ if (end) {
+ uint32_t i = 0;
+ do {
+ char *key = w->param_name[i].body;
+ size_t lkey = w->param_name[i].length;
+ char ksave = key[lkey];
+ key[lkey] = 0x00;
+
+ char *value = w->param_values[i].body;
+ size_t lvalue = w->param_values[i].length;
+ char vsave = value[lvalue];
+ value[lvalue] = 0x00;
+
+ debug(D_WEB_CLIENT, "%llu: API v1 health query param '%s' with value '%s'", w->id, key, value);
+
+ // name and value are now the parameters
+ if (!strncmp(key, "cmd",lkey)) {
+ if (!strcmp(value, HEALTH_CMDAPI_CMD_SILENCEALL)) {
+ silencers->all_alarms = 1;
+ silencers->stype = STYPE_SILENCE_NOTIFICATIONS;
+ buffer_strcat(wb, HEALTH_CMDAPI_MSG_SILENCEALL);
+ } else if (!strcmp(value, HEALTH_CMDAPI_CMD_DISABLEALL)) {
+ silencers->all_alarms = 1;
+ silencers->stype = STYPE_DISABLE_ALARMS;
+ buffer_strcat(wb, HEALTH_CMDAPI_MSG_DISABLEALL);
+ } else if (!strcmp(value, HEALTH_CMDAPI_CMD_SILENCE)) {
+ silencers->stype = STYPE_SILENCE_NOTIFICATIONS;
+ buffer_strcat(wb, HEALTH_CMDAPI_MSG_SILENCE);
+ } else if (!strcmp(value, HEALTH_CMDAPI_CMD_DISABLE)) {
+ silencers->stype = STYPE_DISABLE_ALARMS;
+ buffer_strcat(wb, HEALTH_CMDAPI_MSG_DISABLE);
+ } else if (!strcmp(value, HEALTH_CMDAPI_CMD_RESET)) {
+ silencers->all_alarms = 0;
+ silencers->stype = STYPE_NONE;
+ free_silencers(silencers->silencers);
+ silencers->silencers = NULL;
+ buffer_strcat(wb, HEALTH_CMDAPI_MSG_RESET);
}
- }
-
- if (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) {
- silencer->alarms = strdupz(value);
- silencer->alarms_pattern = simple_pattern_create(silencer->alarms, NULL, SIMPLE_PATTERN_EXACT);
- } else if (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) {
- silencer->charts = strdupz(value);
- silencer->charts_pattern = simple_pattern_create(silencer->charts, NULL, SIMPLE_PATTERN_EXACT);
- } else if (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) {
- silencer->contexts = strdupz(value);
- silencer->contexts_pattern = simple_pattern_create(silencer->contexts, NULL, SIMPLE_PATTERN_EXACT);
- } else if (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) {
- silencer->hosts = strdupz(value);
- silencer->hosts_pattern = simple_pattern_create(silencer->hosts, NULL, SIMPLE_PATTERN_EXACT);
- } else if (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY)) {
- silencer->families = strdupz(value);
- silencer->families_pattern = simple_pattern_create(silencer->families, NULL, SIMPLE_PATTERN_EXACT);
} else {
- buffer_strcat(wb, HEALTH_CMDAPI_MSG_INVALID_KEY);
+ uint32_t hash = simple_uhash(key);
+ if (unlikely(silencer == NULL)) {
+ if (
+ (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) ||
+ (hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) ||
+ (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) ||
+ (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) ||
+ (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) ||
+ (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY))
+ ) {
+ silencer = create_silencer();
+ }
+ }
+
+ if (hash == hash_alarm && !strncasecmp(key, HEALTH_ALARM_KEY,lkey)) {
+ silencer->alarms = strdupz(value);
+ silencer->alarms_pattern = simple_pattern_create(silencer->alarms, NULL, SIMPLE_PATTERN_EXACT);
+ } else if (hash == hash_chart && !strncasecmp(key, HEALTH_CHART_KEY,lkey)) {
+ silencer->charts = strdupz(value);
+ silencer->charts_pattern = simple_pattern_create(silencer->charts, NULL, SIMPLE_PATTERN_EXACT);
+ } else if (hash == hash_context && !strncasecmp(key, HEALTH_CONTEXT_KEY,lkey)) {
+ silencer->contexts = strdupz(value);
+ silencer->contexts_pattern = simple_pattern_create(silencer->contexts, NULL, SIMPLE_PATTERN_EXACT);
+ } else if (hash == hash_host && !strncasecmp(key, HEALTH_HOST_KEY,lkey)) {
+ silencer->hosts = strdupz(value);
+ silencer->hosts_pattern = simple_pattern_create(silencer->hosts, NULL, SIMPLE_PATTERN_EXACT);
+ } else if (hash == hash_families && !strncasecmp(key, HEALTH_FAMILIES_KEY,lkey)) {
+ silencer->families = strdupz(value);
+ silencer->families_pattern = simple_pattern_create(silencer->families, NULL, SIMPLE_PATTERN_EXACT);
+ } else {
+ buffer_strcat(wb, HEALTH_CMDAPI_MSG_INVALID_KEY);
+ }
}
- }
+ key[lkey] = ksave ;
+ value[lvalue] = vsave ;
+
+ } while( ++i < end );
}
+
if (likely(silencer)) {
// Add the created instance to the linked list in silencers
silencer->next = silencers->silencers;
@@ -160,6 +168,7 @@ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, c
ret = 200;
}
}
+
w->response.data = wb;
buffer_no_cacheable(w->response.data);
return ret;
diff --git a/web/api/web_api_v1.c b/web/api/web_api_v1.c
index 7c0d728bf8..590c025632 100644
--- a/web/api/web_api_v1.c
+++ b/web/api/web_api_v1.c
@@ -195,14 +195,18 @@ inline uint32_t web_client_api_request_v1_data_google_format(char *name) {
inline int web_client_api_request_v1_alarms(RRDHOST *host, struct web_client *w, char *url) {
+ (void)url;
int all = 0;
- while(url) {
- char *value = mystrsep(&url, "&");
- if (!value || !*value) continue;
+ uint32_t end = w->total_params;
+ if(end) {
+ uint32_t i = 0;
+ do {
+ char *value = w->param_values[i].body;
- if(!strcmp(value, "all")) all = 1;
- else if(!strcmp(value, "active")) all = 0;
+ if(!strncmp(value, "all",3)) all = 1;
+ else if(!strncmp(value, "active",6)) all = 0;
+ } while(++i < end);
}
buffer_flush(w->response.data);
@@ -213,17 +217,24 @@ inline int web_client_api_request_v1_alarms(RRDHOST *host, struct web_client *w,
}
inline int web_client_api_request_v1_alarm_log(RRDHOST *host, struct web_client *w, char *url) {
+ (void)url;
uint32_t after = 0;
- while(url) {
- char *value = mystrsep(&url, "&");
- if (!value || !*value) continue;
-
- char *name = mystrsep(&value, "=");
- if(!name || !*name) continue;
- if(!value || !*value) continue;
-
- if(!strcmp(name, "after")) after = (uint32_t)strtoul(value, NULL, 0);
+ uint32_t end = w->total_params;
+ if(end) {
+ uint32_t i = 0;
+ do {
+ char *value = w->param_values[i].body;
+ size_t lvalue = w->param_values[i].length;
+ char save = value[lvalue];
+ value[lvalue] = 0x00;
+
+ char *name = w->param_name[i].body;
+ size_t lname = w->param_name[i].length;
+
+ if(!strncmp(name, "after",lname)) after = (uint32_t)strtoul(value, NULL, 0);
+ value[lvalue] = save;
+ } while (++i < end);
}
buffer_flush(w->response.data);
@@ -233,27 +244,29 @@ inline int web_client_api_request_v1_alarm_log(RRDHOST *host, struct web_client
}
inline int web_client_api_request_single_chart(RRDHOST *host, struct web_client *w, char *url, void callback(RRDSET *st, BUFFER *buf)) {