code cleanup and faster mime types assignement for static files
Costa Tsaousis (ktsaou) committed
Dec 26, 2017 at 05:48 UTC
5e3fc4fff58f971800bb0611e668a158a167ebe8
4 files changed
+141
-83
.gitignore
+6
@@ -97,6 +97,8 @@ cmake_install.cmake
97
contrib/debian/changelog
98
profile/benchmark-dictionary
99
profile/benchmark-registry
100
+profile/test-eval
101
+profile/benchmark-line-parsing
102
103
*.pyc
104
*.run
@@ -111,3 +113,7 @@ netdata.cppcheck
113
profile/statsd-stress
114
src/cgroup-network
115
vgcore.*
116
+
117
+src/cppcheck-build/
118
+makeself/debug/
119
+
src/rrd.h
+18
-18
@@ -105,13 +105,13 @@ typedef enum rrddim_flags {
105
} RRDDIM_FLAGS;
106
107
#ifdef HAVE_C___ATOMIC
108
-#define rrddim_flag_check(rd, flag) (__atomic_load_n(&((rd)->flags), __ATOMIC_SEQ_CST) & flag)
109
-#define rrddim_flag_set(rd, flag) __atomic_or_fetch(&((rd)->flags), flag, __ATOMIC_SEQ_CST)
110
-#define rrddim_flag_clear(rd, flag) __atomic_and_fetch(&((rd)->flags), ~flag, __ATOMIC_SEQ_CST)
108
+#define rrddim_flag_check(rd, flag) (__atomic_load_n(&((rd)->flags), __ATOMIC_SEQ_CST) & (flag))
109
+#define rrddim_flag_set(rd, flag) __atomic_or_fetch(&((rd)->flags), (flag), __ATOMIC_SEQ_CST)
110
+#define rrddim_flag_clear(rd, flag) __atomic_and_fetch(&((rd)->flags), ~(flag), __ATOMIC_SEQ_CST)
111
#else
112
-#define rrddim_flag_check(rd, flag) ((rd)->flags & flag)
113
-#define rrddim_flag_set(rd, flag) (rd)->flags |= flag
114
-#define rrddim_flag_clear(rd, flag) (rd)->flags &= ~flag
112
+#define rrddim_flag_check(rd, flag) ((rd)->flags & (flag))
113
+#define rrddim_flag_set(rd, flag) (rd)->flags |= (flag)
114
+#define rrddim_flag_clear(rd, flag) (rd)->flags &= ~(flag)
115
#endif
116
117
@@ -205,10 +205,10 @@ typedef struct rrddim RRDDIM;
205
// these loop macros make sure the linked list is accessed with the right lock
206
207
#define rrddim_foreach_read(rd, st) \
208
- for(rd = st->dimensions, rrdset_check_rdlock(st); rd ; rd = rd->next)
208
+ for((rd) = (st)->dimensions, rrdset_check_rdlock(st); (rd) ; (rd) = (rd)->next)
209
210
#define rrddim_foreach_write(rd, st) \
211
- for(rd = st->dimensions, rrdset_check_wrlock(st); rd ; rd = rd->next)
211
+ for((rd) = (st)->dimensions, rrdset_check_wrlock(st); (rd) ; (rd) = (rd)->next)
212
213
214
// ----------------------------------------------------------------------------
@@ -237,9 +237,9 @@ typedef enum rrdset_flags {
237
#define rrdset_flag_set(st, flag) __atomic_or_fetch(&((st)->flags), flag, __ATOMIC_SEQ_CST)
238
#define rrdset_flag_clear(st, flag) __atomic_and_fetch(&((st)->flags), ~flag, __ATOMIC_SEQ_CST)
239
#else
240
-#define rrdset_flag_check(st, flag) ((st)->flags & flag)
241
-#define rrdset_flag_set(st, flag) (st)->flags |= flag
242
-#define rrdset_flag_clear(st, flag) (st)->flags &= ~flag
240
+#define rrdset_flag_check(st, flag) ((st)->flags & (flag))
241
+#define rrdset_flag_set(st, flag) (st)->flags |= (flag)
242
+#define rrdset_flag_clear(st, flag) (st)->flags &= ~(flag)
243
#endif
244
245
struct rrdset {
@@ -360,10 +360,10 @@ typedef struct rrdset RRDSET;
360
// these loop macros make sure the linked list is accessed with the right lock
361
362
#define rrdset_foreach_read(st, host) \
363
- for(st = host->rrdset_root, rrdhost_check_rdlock(host); st ; st = st->next)
363
+ for((st) = (host)->rrdset_root, rrdhost_check_rdlock(host); st ; (st) = (st)->next)
364
365
#define rrdset_foreach_write(st, host) \
366
- for(st = host->rrdset_root, rrdhost_check_wrlock(host); st ; st = st->next)
366
+ for((st) = (host)->rrdset_root, rrdhost_check_wrlock(host); st ; (st) = (st)->next)
367
368
369
// ----------------------------------------------------------------------------
@@ -383,9 +383,9 @@ typedef enum rrdhost_flags {
383
#define rrdhost_flag_set(host, flag) __atomic_or_fetch(&((host)->flags), flag, __ATOMIC_SEQ_CST)
384
#define rrdhost_flag_clear(host, flag) __atomic_and_fetch(&((host)->flags), ~flag, __ATOMIC_SEQ_CST)
385
#else
386
-#define rrdhost_flag_check(host, flag) ((host)->flags & flag)
387
-#define rrdhost_flag_set(host, flag) (host)->flags |= flag
388
-#define rrdhost_flag_clear(host, flag) (host)->flags &= ~flag
386
+#define rrdhost_flag_check(host, flag) ((host)->flags & (flag))
387
+#define rrdhost_flag_set(host, flag) (host)->flags |= (flag)
388
+#define rrdhost_flag_clear(host, flag) (host)->flags &= ~(flag)
389
#endif
390
391
#ifdef NETDATA_INTERNAL_CHECKS
@@ -520,10 +520,10 @@ extern RRDHOST *localhost;
520
// these loop macros make sure the linked list is accessed with the right lock
521
522
#define rrdhost_foreach_read(var) \
523
- for(var = localhost, rrd_check_rdlock(); var ; var = var->next)
523
+ for((var) = localhost, rrd_check_rdlock(); var ; (var) = (var)->next)
524
525
#define rrdhost_foreach_write(var) \
526
- for(var = localhost, rrd_check_wrlock(); var ; var = var->next)
526
+ for((var) = localhost, rrd_check_wrlock(); var ; (var) = (var)->next)
527
528
529
// ----------------------------------------------------------------------------
src/rrdpush.c
+4
-3
@@ -140,19 +140,20 @@ static inline void rrdpush_send_chart_definition_nolock(RRDSET *st) {
140
141
// sends the current chart dimensions
142
static inline void rrdpush_send_chart_metrics_nolock(RRDSET *st) {
143
- buffer_sprintf(st->rrdhost->rrdpush_sender_buffer, "BEGIN \"%s\" %llu\n", st->id, (st->upstream_resync_time > st->last_collected_time.tv_sec)?st->usec_since_last_update:0);
143
+ RRDHOST *host = st->rrdhost;
144
+ buffer_sprintf(host->rrdpush_sender_buffer, "BEGIN \"%s\" %llu\n", st->id, (st->upstream_resync_time > st->last_collected_time.tv_sec)?st->usec_since_last_update:0);
145
146
RRDDIM *rd;
147
rrddim_foreach_read(rd, st) {
148
if(rd->updated && rd->exposed)
148
- buffer_sprintf(st->rrdhost->rrdpush_sender_buffer
149
+ buffer_sprintf(host->rrdpush_sender_buffer
150
, "SET \"%s\" = " COLLECTED_NUMBER_FORMAT "\n"
151
, rd->id
152
, rd->collected_value
153
);
154
}
155
155
- buffer_strcat(st->rrdhost->rrdpush_sender_buffer, "END\n");
156
+ buffer_strcat(host->rrdpush_sender_buffer, "END\n");
157
}
158
159
static void rrdpush_sender_thread_spawn(RRDHOST *host);
src/web_client.c
+113
-62
@@ -344,6 +344,81 @@ gid_t web_files_gid(void) {
344
return(owner_gid);
345
}
346
347
+static struct mime_type {
348
+ const char *extension;
349
+ uint32_t hash;
350
+ uint8_t contenttype;
351
+} mime_types[] = {
352
+ { "html" , 0 , CT_TEXT_HTML}
353
+ , {"js" , 0 , CT_APPLICATION_X_JAVASCRIPT}
354
+ , {"css" , 0 , CT_TEXT_CSS}
355
+ , {"xml" , 0 , CT_TEXT_XML}
356
+ , {"xsl" , 0 , CT_TEXT_XSL}
357
+ , {"txt" , 0 , CT_TEXT_PLAIN}
358
+ , {"svg" , 0 , CT_IMAGE_SVG_XML}
359
+ , {"ttf" , 0 , CT_APPLICATION_X_FONT_TRUETYPE}
360
+ , {"otf" , 0 , CT_APPLICATION_X_FONT_OPENTYPE}
361
+ , {"woff2", 0 , CT_APPLICATION_FONT_WOFF2}
362
+ , {"woff" , 0 , CT_APPLICATION_FONT_WOFF}
363
+ , {"eot" , 0 , CT_APPLICATION_VND_MS_FONTOBJ}
364
+ , {"png" , 0 , CT_IMAGE_PNG}
365
+ , {"jpg" , 0 , CT_IMAGE_JPG}
366
+ , {"jpeg" , 0 , CT_IMAGE_JPG}
367
+ , {"gif" , 0 , CT_IMAGE_GIF}
368
+ , {"bmp" , 0 , CT_IMAGE_BMP}
369
+ , {"ico" , 0 , CT_IMAGE_XICON}
370
+ , {"icns" , 0 , CT_IMAGE_ICNS}
371
+ , { NULL, 0, 0}
372
+};
373
+
374
+static inline uint8_t contenttype_for_filename(const char *filename) {
375
+ // info("checking filename '%s'", filename);
376
+
377
+ static int initialized = 0;
378
+ int i;
379
+
380
+ if(unlikely(!initialized)) {
381
+ for (i = 0; mime_types[i].extension; i++)
382
+ mime_types[i].hash = simple_hash(mime_types[i].extension);
383
+
384
+ initialized = 1;
385
+ }
386
+
387
+ const char *s = filename, *last_dot = NULL;
388
+
389
+ // find the last dot
390
+ while(*s) {
391
+ if(unlikely(*s == '.')) last_dot = s;
392
+ s++;
393
+ }
394
+
395
+ if(unlikely(!last_dot || !*last_dot || !last_dot[1])) {
396
+ // info("no extension for filename '%s'", filename);
397
+ return CT_APPLICATION_OCTET_STREAM;
398
+ }
399
+ last_dot++;
400
+
401
+ // info("extension for filename '%s' is '%s'", filename, last_dot);
402
+
403
+ uint32_t hash = simple_hash(last_dot);
404
+ for(i = 0; mime_types[i].extension ; i++) {
405
+ if(unlikely(hash == mime_types[i].hash && !strcmp(last_dot, mime_types[i].extension))) {
406
+ // info("matched extension for filename '%s': '%s'", filename, last_dot);
407
+ return mime_types[i].contenttype;
408
+ }
409
+ }
410
+
411
+ // info("not matched extension for filename '%s': '%s'", filename, last_dot);
412
+ return CT_APPLICATION_OCTET_STREAM;
413
+}
414
+
415
+static inline int access_to_file_is_not_permitted(struct web_client *w, const char *filename) {
416
+ w->response.data->contenttype = CT_TEXT_HTML;
417
+ buffer_strcat(w->response.data, "Access to file is not permitted: ");
418
+ buffer_strcat_htmlescape(w->response.data, filename);
419
+ return 403;
420
+}
421
+
422
int mysendfile(struct web_client *w, char *filename) {
423
debug(D_WEB_CLIENT, "%llu: Looking for file '%s/%s'", w->id, netdata_configured_web_dir, filename);
424
@@ -357,6 +432,7 @@ int mysendfile(struct web_client *w, char *filename) {
432
if(strncmp(filename, WEB_PATH_FILE "/", strlen(WEB_PATH_FILE) + 1) == 0)
433
filename = &filename[strlen(WEB_PATH_FILE) + 1];
434
435
+ // if the filename contains "strange" characters, refuse to serve it
436
char *s;
437
for(s = filename; *s ;s++) {
438
if( !isalnum(*s) && *s != '/' && *s != '.' && *s != '-' && *s != '_') {
@@ -377,49 +453,45 @@ int mysendfile(struct web_client *w, char *filename) {
453
return 400;
454
}
455
380
- // access the file
456
+ // find the physical file on disk
457
char webfilename[FILENAME_MAX + 1];
458
snprintfz(webfilename, FILENAME_MAX, "%s/%s", netdata_configured_web_dir, filename);
459
384
- // check if the file exists
385
- struct stat stat;
386
- if(lstat(webfilename, &stat) != 0) {
387
- debug(D_WEB_CLIENT_ACCESS, "%llu: File '%s' is not found.", w->id, webfilename);
388
- w->response.data->contenttype = CT_TEXT_HTML;
389
- buffer_strcat(w->response.data, "File does not exist, or is not accessible: ");
390
- buffer_strcat_htmlescape(w->response.data, webfilename);
391
- return 404;
392
- }
460
+ struct stat statbuf;
461
+ int done = 0;
462
+ while(!done) {
463
+ // check if the file exists
464
+ if (lstat(webfilename, &statbuf) != 0) {
465
+ debug(D_WEB_CLIENT_ACCESS, "%llu: File '%s' is not found.", w->id, webfilename);
466
+ w->response.data->contenttype = CT_TEXT_HTML;
467
+ buffer_strcat(w->response.data, "File does not exist, or is not accessible: ");
468
+ buffer_strcat_htmlescape(w->response.data, webfilename);
469
+ return 404;
470
+ }
471
394
- // check if the file is owned by expected user
395
- if(stat.st_uid != web_files_uid()) {
396
- error("%llu: File '%s' is owned by user %u (expected user %u). Access Denied.", w->id, webfilename, stat.st_uid, web_files_uid());
397
- w->response.data->contenttype = CT_TEXT_HTML;
398
- buffer_strcat(w->response.data, "Access to file is not permitted: ");
399
- buffer_strcat_htmlescape(w->response.data, webfilename);
400
- return 403;
401
- }
472
+ if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
473
+ snprintfz(webfilename, FILENAME_MAX, "%s/%s/index.html", netdata_configured_web_dir, filename);
474
+ continue;
475
+ }
476
403
- // check if the file is owned by expected group
404
- if(stat.st_gid != web_files_gid()) {
405
- error("%llu: File '%s' is owned by group %u (expected group %u). Access Denied.", w->id, webfilename, stat.st_gid, web_files_gid());
406
- w->response.data->contenttype = CT_TEXT_HTML;
407
- buffer_strcat(w->response.data, "Access to file is not permitted: ");
408
- buffer_strcat_htmlescape(w->response.data, webfilename);
409
- return 403;
410
- }
477
+ if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
478
+ error("%llu: File '%s' is not a regular file. Access Denied.", w->id, webfilename);
479
+ return access_to_file_is_not_permitted(w, webfilename);
480
+ }
481
412
- if((stat.st_mode & S_IFMT) == S_IFDIR) {
413
- snprintfz(webfilename, FILENAME_MAX, "%s/index.html", filename);
414
- return mysendfile(w, webfilename);
415
- }
482
+ // check if the file is owned by expected user
483
+ if (statbuf.st_uid != web_files_uid()) {
484
+ error("%llu: File '%s' is owned by user %u (expected user %u). Access Denied.", w->id, webfilename, statbuf.st_uid, web_files_uid());
485
+ return access_to_file_is_not_permitted(w, webfilename);
486
+ }
487
417
- if((stat.st_mode & S_IFMT) != S_IFREG) {
418
- error("%llu: File '%s' is not a regular file. Access Denied.", w->id, webfilename);
419
- w->response.data->contenttype = CT_TEXT_HTML;
420
- buffer_strcat(w->response.data, "Access to file is not permitted: ");
421
- buffer_strcat_htmlescape(w->response.data, webfilename);
422
- return 403;
488
+ // check if the file is owned by expected group
489
+ if (statbuf.st_gid != web_files_gid()) {
490
+ error("%llu: File '%s' is owned by group %u (expected group %u). Access Denied.", w->id, webfilename, statbuf.st_gid, web_files_gid());
491
+ return access_to_file_is_not_permitted(w, webfilename);
492
+ }
493
+
494
+ done = 1;
495
}
496
497
// open the file
@@ -446,39 +518,18 @@ int mysendfile(struct web_client *w, char *filename) {
518
519
sock_setnonblock(w->ifd);
520
449
- // pick a Content-Type for the file
450
- if(strstr(filename, ".html") != NULL) w->response.data->contenttype = CT_TEXT_HTML;
451
- else if(strstr(filename, ".js") != NULL) w->response.data->contenttype = CT_APPLICATION_X_JAVASCRIPT;
452
- else if(strstr(filename, ".css") != NULL) w->response.data->contenttype = CT_TEXT_CSS;
453
- else if(strstr(filename, ".xml") != NULL) w->response.data->contenttype = CT_TEXT_XML;
454
- else if(strstr(filename, ".xsl") != NULL) w->response.data->contenttype = CT_TEXT_XSL;
455
- else if(strstr(filename, ".txt") != NULL) w->response.data->contenttype = CT_TEXT_PLAIN;
456
- else if(strstr(filename, ".svg") != NULL) w->response.data->contenttype = CT_IMAGE_SVG_XML;
457
- else if(strstr(filename, ".ttf") != NULL) w->response.data->contenttype = CT_APPLICATION_X_FONT_TRUETYPE;
458
- else if(strstr(filename, ".otf") != NULL) w->response.data->contenttype = CT_APPLICATION_X_FONT_OPENTYPE;
459
- else if(strstr(filename, ".woff2")!= NULL) w->response.data->contenttype = CT_APPLICATION_FONT_WOFF2;
460
- else if(strstr(filename, ".woff") != NULL) w->response.data->contenttype = CT_APPLICATION_FONT_WOFF;
461
- else if(strstr(filename, ".eot") != NULL) w->response.data->contenttype = CT_APPLICATION_VND_MS_FONTOBJ;
462
- else if(strstr(filename, ".png") != NULL) w->response.data->contenttype = CT_IMAGE_PNG;
463
- else if(strstr(filename, ".jpg") != NULL) w->response.data->contenttype = CT_IMAGE_JPG;
464
- else if(strstr(filename, ".jpeg") != NULL) w->response.data->contenttype = CT_IMAGE_JPG;
465
- else if(strstr(filename, ".gif") != NULL) w->response.data->contenttype = CT_IMAGE_GIF;
466
- else if(strstr(filename, ".bmp") != NULL) w->response.data->contenttype = CT_IMAGE_BMP;
467
- else if(strstr(filename, ".ico") != NULL) w->response.data->contenttype = CT_IMAGE_XICON;
468
- else if(strstr(filename, ".icns") != NULL) w->response.data->contenttype = CT_IMAGE_ICNS;
469
- else w->response.data->contenttype = CT_APPLICATION_OCTET_STREAM;
470
-
471
- debug(D_WEB_CLIENT_ACCESS, "%llu: Sending file '%s' (%ld bytes, ifd %d, ofd %d).", w->id, webfilename, stat.st_size, w->ifd, w->ofd);
521
+ w->response.data->contenttype = contenttype_for_filename(webfilename);
522
+ debug(D_WEB_CLIENT_ACCESS, "%llu: Sending file '%s' (%ld bytes, ifd %d, ofd %d).", w->id, webfilename, statbuf.st_size, w->ifd, w->ofd);
523
524
w->mode = WEB_CLIENT_MODE_FILECOPY;
525
web_client_enable_wait_receive(w);
526
web_client_disable_wait_send(w);
527
buffer_flush(w->response.data);
477
- w->response.rlen = stat.st_size;
528
+ w->response.rlen = (size_t)statbuf.st_size;
529
#ifdef __APPLE__
479
- w->response.data->date = stat.st_mtimespec.tv_sec;
530
+ w->response.data->date = statbuf.st_mtimespec.tv_sec;
531
#else
481
- w->response.data->date = stat.st_mtim.tv_sec;
532
+ w->response.data->date = statbuf.st_mtim.tv_sec;
533
#endif /* __APPLE__ */
534
buffer_cacheable(w->response.data);
535