diff options
author | Pavlos Emm. Katsoulakis <paul@netdata.rocks> | 2019-06-07 18:14:44 +0300 |
---|---|---|
committer | Pavlos Emm. Katsoulakis <paul@netdata.rocks> | 2019-06-07 18:14:44 +0300 |
commit | 0fca36fd596e49395141561bc42c168a240f51b8 (patch) | |
tree | 7c47ac793a7937015e4fb3c557ecbb3de5940456 | |
parent | d6f3937b4d4bffedb8a8cc61f80affde7f17b180 (diff) |
Revert "New URL parser (#6070)"
This reverts commit 58b7d95a7ec9c576f8a06bbab07f755846b5349a.
---
As agreed with @thiago and @cakrit we revert URL parser changes,
to buy the time on a more detailed investigation
---
-rw-r--r-- | libnetdata/inlined.h | 28 | ||||
-rw-r--r-- | libnetdata/url/url.c | 85 | ||||
-rw-r--r-- | libnetdata/url/url.h | 22 | ||||
-rw-r--r-- | tests/urls/requests.sh | 207 | ||||
-rw-r--r-- | web/api/badges/web_buffer_svg.c | 97 | ||||
-rw-r--r-- | web/api/exporters/allmetrics.c | 79 | ||||
-rw-r--r-- | web/api/health/health_cmdapi.c | 145 | ||||
-rw-r--r-- | web/api/web_api_v1.c | 312 | ||||
-rw-r--r-- | web/server/web_client.c | 513 | ||||
-rw-r--r-- | web/server/web_client.h | 12 |
10 files changed, 444 insertions, 1056 deletions
diff --git a/libnetdata/inlined.h b/libnetdata/inlined.h index a9c3e472e4..6a5994c12a 100644 --- a/libnetdata/inlined.h +++ b/libnetdata/inlined.h @@ -31,19 +31,6 @@ 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; @@ -55,21 +42,6 @@ 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 fb1fb7f07a..07a9f8069e 100644 --- a/libnetdata/url/url.c +++ b/libnetdata/url/url.c @@ -79,88 +79,3 @@ 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 9e86c20cfd..6cef6d7a84 100644 --- a/libnetdata/url/url.h +++ b/libnetdata/url/url.h @@ -25,26 +25,4 @@ 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 deleted file mode 100644 index 2e1a957a88..0000000000 --- a/tests/urls/requests.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/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>ime=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 d24e2820ef..b24fddedf5 100644 --- a/web/api/badges/web_buffer_svg.c +++ b/web/api/badges/web_buffer_svg.c @@ -889,7 +889,6 @@ 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); @@ -913,54 +912,46 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u int group = RRDR_GROUPING_AVERAGE; uint32_t options = 0x00000000; - 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 ); + 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; } if(!chart || !*chart) { @@ -1146,14 +1137,6 @@ 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 17e5e077eb..88ff78e7e4 100644 --- a/web/api/exporters/allmetrics.c +++ b/web/api/exporters/allmetrics.c @@ -18,57 +18,54 @@ 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; - 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; + while(url) { + char *value = mystrsep(&url, "&"); + if (!value || !*value) continue; - 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; + 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; - 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 eac3daf06b..ec177751b9 100644 --- a/web/api/health/health_cmdapi.c +++ b/web/api/health/health_cmdapi.c @@ -31,10 +31,13 @@ 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); @@ -70,86 +73,75 @@ 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 { - 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); - } - } 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(); - } - } - - 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); + 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(); } } - key[lkey] = ksave ; - value[lvalue] = vsave ; - } while( ++i < end ); + 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); + } + } } - if (likely(silencer)) { // Add the created instance to the linked list in silencers silencer->next = silencers->silencers; @@ -168,7 +160,6 @@ 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 590c025632..7c0d728bf8 100644 --- a/web/api/web_api_v1.c +++ b/web/api/web_api_v1.c @@ -195,18 +195,14 @@ 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; - uint32_t end = w->total_params; - if(end) { - uint32_t i = 0; - do { - char *value = w->param_values[i].body; + while(url) { + char *value = mystrsep(&url, "&"); + if (!value || !*value) continue; - if(!strncmp(value, "all",3)) all = 1; - else if(!strncmp(value, "active",6)) all = 0; - } while(++i < end); + if(!strcmp(value, "all")) all = 1; + else if(!strcmp(value, "active")) all = 0; } buffer_flush(w->response.data); @@ -217,24 +213,17 @@ 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; - 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[l |