From 58b7d95a7ec9c576f8a06bbab07f755846b5349a Mon Sep 17 00:00:00 2001 From: thiagoftsm <49162938+thiagoftsm@users.noreply.github.com> Date: Thu, 6 Jun 2019 17:01:39 +0000 Subject: New URL parser (#6070) * URL_parser 3 * URL_parser rebase 2! * URL_parameter parsing 3 * URL_parameter parsing 4 * URL_parameter parsing 5 * URL_parser alarms * URL_parser finish the basic structure * URL_parser codacity fixes! * URL_parser scripts! * URL_parser codacy! * URL_parser rebase 3! * URL_parser host fixes! * URL_parser host fixes 2! * URL_parser fix spaces! * URL_parser error message! * URL_parser Christopher requests! * URL_parser alarms fixed! * URL_parser health fixed! * URL_parser rebase 4! * URL_parser C fix write format! * URL_parser fix bugs due cache! --- libnetdata/inlined.h | 28 +++++++++++++++++ libnetdata/url/url.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libnetdata/url/url.h | 22 ++++++++++++++ 3 files changed, 135 insertions(+) (limited to 'libnetdata') 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 */ -- cgit v1.2.3