added option and code to respect https://www.w3.org/TR/tracking-dnt/
Costa Tsaousis (ktsaou) committed
Jun 3, 2016 at 10:24 UTC
7760850aa4277c80ad483c7d0de5657781508b4e
5 files changed
+81
-14
src/main.c
+2
@@ -102,6 +102,8 @@ void web_server_threading_selection(void) {
102
103
web_client_timeout = (int) config_get_number("global", "disconnect idle web clients after seconds", DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS);
104
105
+ web_donotrack_comply = config_get_boolean("global", "respect web browser do not track policy", web_donotrack_comply);
106
+
107
#ifdef NETDATA_WITH_ZLIB
108
web_enable_gzip = config_get_boolean("global", "enable web responses gzip compression", web_enable_gzip);
109
src/web_client.c
+51
-13
@@ -38,6 +38,7 @@
38
#define TOO_BIG_REQUEST 16384
39
40
int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS;
41
+int web_donotrack_comply = 0;
42
43
#ifdef NETDATA_WITH_ZLIB
44
int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
@@ -250,6 +251,9 @@ void web_client_reset(struct web_client *w) {
251
252
w->mode = WEB_CLIENT_MODE_NORMAL;
253
254
+ w->tcp_cork = 0;
255
+ w->donottrack = 0;
256
+ w->tracking_required = 0;
257
w->keepalive = 0;
258
w->decoded_url[0] = '\0';
259
@@ -959,6 +963,12 @@ int web_client_api_request_v1_registry(struct web_client *w, char *url)
963
#endif /* NETDATA_INTERNAL_CHECKS */
964
}
965
966
+ if(web_donotrack_comply && w->donottrack) {
967
+ buffer_flush(w->response.data);
968
+ buffer_sprintf(w->response.data, "Your web browser is sending 'DNT: 1' (Do Not Track). The registry requires persistent cookies on your browser to work.");
969
+ return 400;
970
+ }
971
+
972
if(action == 'A' && (!machine_guid || !machine_url || !url_name)) {
973
buffer_flush(w->response.data);
974
buffer_sprintf(w->response.data, "Invalid registry request - access requires these parameters: machine ('%s'), url ('%s'), name ('%s')",
@@ -986,6 +996,7 @@ int web_client_api_request_v1_registry(struct web_client *w, char *url)
996
997
switch(action) {
998
case 'A':
999
+ w->tracking_required = 1;
1000
if(registry_verify_cookies_redirects() > 0 && (!cookie || !person_guid[0])) {
1001
buffer_flush(w->response.data);
1002
@@ -1040,12 +1051,15 @@ int web_client_api_request_v1_registry(struct web_client *w, char *url)
1051
return registry_request_access_json(w, person_guid, machine_guid, machine_url, url_name, time(NULL));
1052
1053
case 'D':
1054
+ w->tracking_required = 1;
1055
return registry_request_delete_json(w, person_guid, machine_guid, machine_url, delete_url, time(NULL));
1056
1057
case 'S':
1058
+ w->tracking_required = 1;
1059
return registry_request_search_json(w, person_guid, machine_guid, machine_url, search_machine_guid, time(NULL));
1060
1061
case 'W':
1062
+ w->tracking_required = 1;
1063
return registry_request_switch_json(w, person_guid, machine_guid, machine_url, to_person_guid, time(NULL));
1064
1065
case 'H':
@@ -1399,26 +1413,30 @@ const char *web_response_code_to_string(int code) {
1413
}
1414
1415
static inline char *http_header_parse(struct web_client *w, char *s) {
1402
- static uint32_t hash_origin = 0, hash_connection = 0, hash_accept_encoding = 0;
1416
+ static uint32_t hash_origin = 0, hash_connection = 0, hash_accept_encoding = 0, hash_donottrack = 0;
1417
1418
if(unlikely(!hash_origin)) {
1419
hash_origin = simple_uhash("Origin");
1420
hash_connection = simple_uhash("Connection");
1421
hash_accept_encoding = simple_uhash("Accept-Encoding");
1422
+ hash_donottrack = simple_uhash("DNT");
1423
}
1424
1425
char *e = s;
1426
1427
// find the :
1428
while(*e && *e != ':') e++;
1414
- if(!*e || e[1] != ' ') return e;
1429
+ if(!*e) return e;
1430
1431
// get the name
1432
*e = '\0';
1433
1434
// find the value
1420
- char *v, *ve;
1421
- v = ve = e + 2;
1435
+ char *v = e + 1, *ve;
1436
+
1437
+ // skip leading spaces from value
1438
+ while(*v == ' ') v++;
1439
+ ve = v;
1440
1441
// find the \r
1442
while(*ve && *ve != '\r') ve++;
@@ -1440,6 +1458,10 @@ static inline char *http_header_parse(struct web_client *w, char *s) {
1458
if(strcasestr(v, "keep-alive"))
1459
w->keepalive = 1;
1460
}
1461
+ else if(web_donotrack_comply && hash == hash_donottrack && !strcasecmp(s, "DNT")) {
1462
+ if(*v == '0') w->donottrack = 0;
1463
+ else if(*v == '1') w->donottrack = 1;
1464
+ }
1465
#ifdef NETDATA_WITH_ZLIB
1466
else if(hash == hash_accept_encoding && !strcasecmp(s, "Accept-Encoding")) {
1467
if(web_enable_gzip) {
@@ -1778,16 +1800,32 @@ void web_client_process(struct web_client *w) {
1800
, date
1801
);
1802
1781
- if(w->cookie1[0]) {
1782
- buffer_sprintf(w->response.header_output,
1783
- "Set-Cookie: %s\r\n",
1784
- w->cookie1);
1785
- }
1803
+ if(w->cookie1[0] || w->cookie2[0]) {
1804
+ if(w->cookie1[0]) {
1805
+ buffer_sprintf(w->response.header_output,
1806
+ "Set-Cookie: %s\r\n",
1807
+ w->cookie1);
1808
+ }
1809
1787
- if(w->cookie2[0]) {
1788
- buffer_sprintf(w->response.header_output,
1789
- "Set-Cookie: %s\r\n",
1790
- w->cookie2);
1810
+ if(w->cookie2[0]) {
1811
+ buffer_sprintf(w->response.header_output,
1812
+ "Set-Cookie: %s\r\n",
1813
+ w->cookie2);
1814
+ }
1815
+
1816
+ if(web_donotrack_comply)
1817
+ buffer_sprintf(w->response.header_output,
1818
+ "Tk: T;cookies\r\n");
1819
+ }
1820
+ else {
1821
+ if(web_donotrack_comply) {
1822
+ if(w->tracking_required)
1823
+ buffer_sprintf(w->response.header_output,
1824
+ "Tk: T;cookies\r\n");
1825
+ else
1826
+ buffer_sprintf(w->response.header_output,
1827
+ "Tk: N\r\n");
1828
+ }
1829
}
1830
1831
if(w->mode == WEB_CLIENT_MODE_OPTIONS) {
src/web_client.h
+4
-1
@@ -18,7 +18,7 @@
18
extern int web_client_timeout;
19
20
#ifdef NETDATA_WITH_ZLIB
21
-extern int web_enable_gzip, web_gzip_level, web_gzip_strategy;
21
+extern int web_enable_gzip, web_gzip_level, web_gzip_strategy, web_donotrack_comply;
22
#endif /* NETDATA_WITH_ZLIB */
23
24
#ifndef NETDATA_WEB_CLIENT_H
@@ -71,6 +71,9 @@ struct web_client {
71
uint8_t wait_receive:1; // 1 = we are waiting more input data
72
uint8_t wait_send:1; // 1 = we have data to send to the client
73
74
+ uint8_t donottrack:1; // 1 = we should not set cookies on this client
75
+ uint8_t tracking_required:1; // 1 = if the request requires cookies
76
+
77
int tcp_cork; // 1 = we have a cork on the socket
78
79
int ifd;
web/.well-known/dnt/cookies
new
+14
@@ -0,0 +1,14 @@
1
+{
2
+ "tracking": "T",
3
+ "compliance": ["https://github.com/firehol/netdata/wiki/cookies#compliance"],
4
+ "qualifiers": "afc",
5
+ "controller": ["https://github.com/firehol/netdata/wiki/cookies#controller"],
6
+ "same-party": [
7
+ "my-netdata.io",
8
+ "mynetdata.io",
9
+ "netdata.online",
10
+ "netdata.rocks",
11
+ "registry.my-netdata.io"
12
+ ],
13
+ "policy": "https://github.com/firehol/netdata/wiki/cookies#policy",
14
+}
web/Makefile.am
+10
@@ -94,6 +94,16 @@ dist_webimages_DATA = \
94
images/seo-performance-multi-size.icns \
95
$(NULL)
96
97
+
98
+webwellknowndir=$(webdir)/.well-known
99
+dist_webwellknown_DATA = \
100
+ $(NULL)
101
+
102
+webdntdir=$(webdir)/.well-known/dnt
103
+dist_webdnt_DATA = \
104
+ .well-known/dnt/cookies \
105
+ $(NULL)
106
+
107
version.txt:
108
if test -d "$(top_srcdir)/.git"; then \
109
git --git-dir="$(top_srcdir)/.git" log -n 1 --format=%H; \