]> arthur.barton.de Git - netdata.git/commitdiff
Merge remote-tracking branch 'fredericopissarra/changes' into registry
authorCosta Tsaousis <costa@tsaousis.gr>
Fri, 13 May 2016 17:08:47 +0000 (20:08 +0300)
committerCosta Tsaousis <costa@tsaousis.gr>
Fri, 13 May 2016 17:08:47 +0000 (20:08 +0300)
Conflicts:
src/common.c
src/web_client.c

1  2 
src/apps_plugin.c
src/common.c
src/common.h
src/main.c
src/plugin_tc.c
src/proc_interrupts.c
src/proc_softirqs.c
src/rrd.c
src/sys_fs_cgroup.c
src/web_client.c

Simple merge
diff --cc src/common.c
index ca4b8753d23373931c75d7983b58155a8e9e970f,460c8d284f57f5819cd2a205871858cbeeb056fa..ea94ecc33baead4af53305c687ee01749dc96e45
@@@ -762,23 -776,31 +776,51 @@@ pid_t gettid(void
        return syscall(SYS_gettid);
  }
  
 +char *fgets_trim_len(char *buf, size_t buf_size, FILE *fp, size_t *len) {
 +      char *s = fgets(buf, buf_size, fp);
 +      if(!s) return NULL;
 +
 +      char *t = s;
 +      if(*t != '\0') {
 +              // find the string end
 +              while (*++t != '\0');
 +
 +              // trim trailing spaces/newlines/tabs
 +              while (--t > s && *t == '\n')
 +                      *t = '\0';
 +      }
 +
 +      if(len)
 +              *len = t - s + 1;
 +
 +      return s;
 +}
 +
+ char *strncpyz(char *dest, const char *src, size_t n)
+ {
+   char *p = dest;
+       while (*src && n--)
+               *dest++ = *src++;
+   *dest = '\0';
+       return p;
+ }
+ int vsnprintfz(char *sout, size_t n, const char *fmt, va_list args)
+ {
+       int size;
+   size = vsnprintf(sout, n, fmt, args);
+   sout[size] = '\0';
+   return size;
+ }
+ int snprintfz(char *sout, size_t n, const char *fmt, ...)
+ {
+       va_list args;
+       va_start(args, fmt);
+       return vsnprintfz(sout, n, fmt, args);
+   // args will vanish!
+ }
diff --cc src/common.h
index cc276560413859dfa14fa1df53bd980d2b93441f,f2a861f7f2277436dabf7d4fb8df916eb104306f..1460d922314f9ce7a46be88298392296f3601680
@@@ -1,6 -1,6 +1,7 @@@
+ #include <stdarg.h>
  #include <sys/time.h>
  #include <sys/resource.h>
 +#include <stdio.h>
  
  #ifndef NETDATA_COMMON_H
  #define NETDATA_COMMON_H 1
diff --cc src/main.c
Simple merge
diff --cc src/plugin_tc.c
Simple merge
Simple merge
Simple merge
diff --cc src/rrd.c
index 379b1c8b8d642b203b20a7760550e5aed6c4b0a7,d502e52a67516339ded57b37b242a30f11f40c9c..5971afb2f71d8daf3da497d3c42b6dc856ac3ca1
+++ b/src/rrd.c
@@@ -60,11 -67,10 +60,10 @@@ avl_tree_lock rrdset_root_index = 
  
  static RRDSET *rrdset_index_find(const char *id, uint32_t hash) {
        RRDSET *result = NULL, tmp;
-       strncpy(tmp.id, id, RRD_ID_LENGTH_MAX);
-       tmp.id[RRD_ID_LENGTH_MAX] = '\0';
+       strncpyz(tmp.id, id, RRD_ID_LENGTH_MAX);
        tmp.hash = (hash)?hash:simple_hash(tmp.id);
  
 -      avl_search(&(rrdset_root_index), (avl *)&tmp, rrdset_iterator, (avl **)&result);
 +      avl_search_lock(&(rrdset_root_index), (avl *) &tmp, rrdset_iterator, (avl **) &result);
        return result;
  }
  
@@@ -135,11 -148,10 +134,10 @@@ static int rrddim_compare(void* a, void
  
  static RRDDIM *rrddim_index_find(RRDSET *st, const char *id, uint32_t hash) {
        RRDDIM *result = NULL, tmp;
-       strncpy(tmp.id, id, RRD_ID_LENGTH_MAX);
-       tmp.id[RRD_ID_LENGTH_MAX] = '\0';
+       strncpyz(tmp.id, id, RRD_ID_LENGTH_MAX);
        tmp.hash = (hash)?hash:simple_hash(tmp.id);
  
 -      avl_search(&(st->dimensions_index), (avl *)&tmp, rrddim_iterator, (avl **)&result);
 +      avl_search_lock(&(st->dimensions_index), (avl *) &tmp, rrddim_iterator, (avl **) &result);
        return result;
  }
  
Simple merge
index 6e2e639c145c6478e6aa6f8c7e53c4d88ba60f64,2c07e9876acb2dd025d2dfc4662eb88146a3b683..f1e368ff6923337ef38f1ccb806b9645f0db7847
@@@ -1183,172 -1043,66 +1183,177 @@@ cleanup
  }
  */
  
 -void web_client_process(struct web_client *w) {
 -      int code = 500;
 -      ssize_t bytes;
 -      int enable_gzip = 0;
  
 -      w->wait_receive = 0;
 +static inline char *http_header_parse(struct web_client *w, char *s) {
 +      char *e = s;
  
 -      // check if we have an empty line (end of HTTP header)
 -      if(strstr(w->response.data->buffer, "\r\n\r\n")) {
 -              global_statistics_lock();
 -              global_statistics.web_requests++;
 -              global_statistics_unlock();
 +      // find the :
 +      while(*e && *e != ':') e++;
 +      if(!*e || e[1] != ' ') return e;
  
 -              gettimeofday(&w->tv_in, NULL);
 -              debug(D_WEB_DATA, "%llu: Processing data buffer of %d bytes: '%s'.", w->id, w->response.data->len, w->response.data->buffer);
 +      // get the name
 +      *e = '\0';
  
 -              // check if the client requested keep-alive HTTP
 -              if(strcasestr(w->response.data->buffer, "Connection: keep-alive")) w->keepalive = 1;
 -              else w->keepalive = 0;
 +      // find the value
 +      char *v, *ve;
 +      v = ve = e + 2;
  
 +      // find the \r
 +      while(*ve && *ve != '\r') ve++;
 +      if(!*ve || ve[1] != '\n') {
 +              *e = ':';
 +              return ve;
 +      }
 +
 +      // terminate the value
 +      *ve = '\0';
 +
 +      // fprintf(stderr, "HEADER: '%s' = '%s'\n", s, v);
 +
 +      if(!strcasecmp(s, "Origin")) {
 +              strncpy(w->origin, v, ORIGIN_MAX);
 +      }
 +      else if(!strcasecmp(s, "Connection")) {
 +              if(strcasestr(v, "keep-alive"))
 +                      w->keepalive = 1;
 +      }
  #ifdef NETDATA_WITH_ZLIB
 -              // check if the client accepts deflate
 -              if(web_enable_gzip && strstr(w->response.data->buffer, "gzip"))
 -                      enable_gzip = 1;
 -#endif // NETDATA_WITH_ZLIB
 +      else if(!strcasecmp(s, "Accept-Encoding")) {
 +              if(web_enable_gzip && strcasestr(v, "gzip")) {
 +                      w->enable_gzip = 1;
 +              }
 +      }
 +#endif /* NETDATA_WITH_ZLIB */
 +
 +      *e = ':';
 +      *ve = '\r';
 +      return ve;
 +}
  
 -              int datasource_type = DATASOURCE_DATATABLE_JSONP;
 -              //if(strstr(w->response.data->buffer, "X-DataSource-Auth"))
 -              //      datasource_type = DATASOURCE_GOOGLE_JSON;
 +// http_request_validate()
 +// returns:
 +// = 0 : all good, process the request
 +// > 0 : request is complete, but is not supported
 +// < 0 : request is incomplete - wait for more data
  
 -              char *buf = (char *)buffer_tostring(w->response.data);
 -              char *tok = strsep(&buf, " \r\n");
 -              char *url = NULL;
 -              char *pointer_to_free = NULL; // keep url_decode() allocated buffer
 +static inline int http_request_validate(struct web_client *w) {
 +      char *s = w->response.data->buffer, *encoded_url = NULL;
  
 +      // is is a valid request?
 +      if(!strncmp(s, "GET ", 4)) {
 +              encoded_url = s = &s[4];
                w->mode = WEB_CLIENT_MODE_NORMAL;
 +      }
 +      else if(!strncmp(s, "OPTIONS ", 8)) {
 +              encoded_url = s = &s[8];
 +              w->mode = WEB_CLIENT_MODE_OPTIONS;
 +      }
 +      else {
 +              w->wait_receive = 0;
 +              return 1;
 +      }
 +
 +      // find the SPACE + "HTTP/"
 +      while(*s) {
 +              // find the space
 +              while (*s && *s != ' ') s++;
 +
 +              // is it SPACE + "HTTP/" ?
 +              if(*s && !strncmp(s, " HTTP/", 6)) break;
 +              else s++;
 +      }
 +
 +      // incomplete requests
 +      if(!*s) {
 +              w->wait_receive = 1;
 +              return -2;
 +      }
 +
 +      // we have the end of encoded_url - remember it
 +      char *ue = s;
 +
 +      while(*s) {
 +              // find a line feed
 +              while (*s && *s != '\r') s++;
 +
 +              // did we reach the end?
 +              if(unlikely(!*s)) break;
 +
 +              // is it \r\n ?
 +              if (likely(s[1] == '\n')) {
 +
 +                      // is it again \r\n ? (header end)
 +                      if(unlikely(s[2] == '\r' && s[3] == '\n')) {
 +                              // a valid complete HTTP request found
  
 -              if(buf && strcmp(tok, "GET") == 0) {
 -                      tok = strsep(&buf, " \r\n");
 -                      pointer_to_free = url = url_decode(tok);
 -                      debug(D_WEB_CLIENT, "%llu: Processing HTTP GET on url '%s'.", w->id, url);
 +                              *ue = '\0';
 +                              w->decoded_url = url_decode(encoded_url);
 +                              *ue = ' ';
 +
 +                              w->wait_receive = 0;
 +                              return 0;
 +                      }
 +
 +                      // another header line
 +                      s = http_header_parse(w, &s[2]);
                }
 -              else if(buf && strcmp(tok, "OPTIONS") == 0) {
 -                      tok = strsep(&buf, " \r\n");
 -                      pointer_to_free = url = url_decode(tok);
 -                      debug(D_WEB_CLIENT, "%llu: Processing HTTP OPTIONS on url '%s'.", w->id, url);
 -                      w->mode = WEB_CLIENT_MODE_OPTIONS;
 +              else s++;
 +      }
 +
 +      // incomplete request
 +      w->wait_receive = 1;
 +      return -3;
 +}
 +
 +void web_client_process(struct web_client *w) {
 +      int code = 500;
 +      ssize_t bytes;
 +
 +      int what_to_do = http_request_validate(w);
 +
 +      // wait for more data
 +      if(what_to_do < 0) {
 +              if(w->response.data->len > TOO_BIG_REQUEST) {
 +                      strcpy(w->last_url, "too big request");
 +
 +                      debug(D_WEB_CLIENT_ACCESS, "%llu: Received request is too big (%zd bytes).", w->id, w->response.data->len);
 +
 +                      code = 400;
 +                      buffer_flush(w->response.data);
 +                      buffer_sprintf(w->response.data, "Received request is too big  (%zd bytes).\r\n", w->response.data->len);
                }
 -              else if (buf && strcmp(tok, "POST") == 0) {
 -                      w->keepalive = 0;
 -                      tok = strsep(&buf, " \r\n");
 -                      pointer_to_free = url = url_decode(tok);
 -                      debug(D_WEB_CLIENT, "%llu: I don't know how to handle POST with form data. Assuming it is a GET on url '%s'.", w->id, url);
 +              else {
 +                      // wait for more data
 +                      return;
                }
 +      }
 +      else if(what_to_do > 0) {
 +              strcpy(w->last_url, "not a valid response");
  
 -              w->last_url[0] = '\0';
 +              debug(D_WEB_CLIENT_ACCESS, "%llu: Cannot understand '%s'.", w->id, w->response.data->buffer);
  
++<<<<<<< HEAD
 +              code = 500;
 +              buffer_flush(w->response.data);
 +              buffer_strcat(w->response.data, "I don't understand you...\r\n");
 +      }
 +      else { // what_to_do == 0
 +              gettimeofday(&w->tv_in, NULL);
 +
 +              global_statistics_lock();
 +              global_statistics.web_requests++;
 +              global_statistics_unlock();
++=======
+               if(w->mode == WEB_CLIENT_MODE_OPTIONS) {
+                       strncpyz(w->last_url, url, URL_MAX);
++>>>>>>> fredericopissarra/changes
  
 +              // copy the URL - we are going to overwrite parts of it
 +              // FIXME -- we should avoid it
 +              strncpy(w->last_url, w->decoded_url, URL_MAX);
 +              w->last_url[URL_MAX] = '\0';
 +
 +              if(w->mode == WEB_CLIENT_MODE_OPTIONS) {
                        code = 200;
                        w->response.data->contenttype = CT_TEXT_PLAIN;
                        buffer_flush(w->response.data);
                                web_client_enable_deflate(w);
  #endif
  
++<<<<<<< HEAD
 +                      char *url = w->decoded_url;
 +                      char *tok = mystrsep(&url, "/?");
++=======
+                       strncpyz(w->last_url, url, URL_MAX);
+                       tok = mystrsep(&url, "/?");
++>>>>>>> fredericopissarra/changes
                        if(tok && *tok) {
                                debug(D_WEB_CLIENT, "%llu: Processing command '%s'.", w->id, tok);