@cryptotaxi247 / netdata-1 / commits / 253dbf6a5

finer cache control; Expires header is now always added; default expiration for static content is a day; #37

Costa Tsaousis (ktsaou) committed Jan 16, 2016 at 21:11 UTC 253dbf6a5a8bf3f8fa74f676af41b68cd39d05d6
4 files changed +45 -8
src/rrd2json.c
+27 -3
@@ -259,16 +259,21 @@ void rrd_stats_all_json(BUFFER *wb)
259
260 // ----------------------------------------------------------------------------
261
262 -// RRDR options
262 +// RRDR dimension options
263 #define RRDR_EMPTY 0x01 // the dimension contains / the value is empty (null)
264 #define RRDR_RESET 0x02 // the dimension contains / the value is reset
265 #define RRDR_HIDDEN 0x04 // the dimension contains / the value is hidden
266 #define RRDR_NONZERO 0x08 // the dimension contains / the value is non-zero
267
268 +// RRDR result options
269 +#define RRDR_RESULT_OPTION_ABSOLUTE 0x00000001
270 +#define RRDR_RESULT_OPTION_RELATIVE 0x00000002
271
272 typedef struct rrdresult {
273 RRDSET *st; // the chart this result refers to
274
275 + uint32_t result_options; // RRDR_RESULT_OPTION_*
276 +
277 int d; // the number of dimensions
278 long n; // the number of values in the arrays
279 long rows; // the number of rows used
@@ -1200,6 +1205,7 @@ cleanup:
1205 RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int group_method)
1206 {
1207 int debug = st->debug;
1208 + int absolute_period_requested = -1;
1209
1210 time_t first_entry_t = rrdset_first_entry_t(st);
1211 time_t last_entry_t = rrdset_last_entry_t(st);
@@ -1207,14 +1213,22 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1213 if(before == 0 && after == 0) {
1214 before = last_entry_t;
1215 after = first_entry_t;
1216 + absolute_period_requested = 0;
1217 }
1218
1219 // allow relative for before and after
1213 - if(before <= st->update_every * st->entries)
1220 + if(before <= st->update_every * st->entries) {
1221 before = last_entry_t + before;
1222 + absolute_period_requested = 0;
1223 + }
1224
1216 - if(after <= st->update_every * st->entries)
1225 + if(after <= st->update_every * st->entries) {
1226 after = last_entry_t + after;
1227 + absolute_period_requested = 0;
1228 + }
1229 +
1230 + if(absolute_period_requested == -1)
1231 + absolute_period_requested = 1;
1232
1233 // make sure they are within our timeframe
1234 if(before > last_entry_t) before = last_entry_t;
@@ -1314,6 +1328,11 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1328 return r;
1329 }
1330
1331 + if(absolute_period_requested == 1)
1332 + r->result_options |= RRDR_RESULT_OPTION_ABSOLUTE;
1333 + else
1334 + r->result_options |= RRDR_RESULT_OPTION_RELATIVE;
1335 +
1336 // find how many dimensions we have
1337 long dimensions = r->d;
1338
@@ -1497,6 +1516,11 @@ int rrd2format(RRDSET *st, BUFFER *wb, BUFFER *dimensions, uint32_t format, long
1516 return 500;
1517 }
1518
1519 + if(r->result_options & RRDR_RESULT_OPTION_RELATIVE)
1520 + wb->options |= WB_CONTENT_NO_CACHEABLE;
1521 + else if(r->result_options & RRDR_RESULT_OPTION_ABSOLUTE)
1522 + wb->options |= WB_CONTENT_CACHEABLE;
1523 +
1524 options = rrdr_check_options(r, options, (dimensions)?buffer_tostring(dimensions):NULL);
1525
1526 if(dimensions)
src/web_buffer.c
+1
@@ -45,6 +45,7 @@ void buffer_reset(BUFFER *wb)
45 buffer_flush(wb);
46
47 wb->contenttype = CT_TEXT_PLAIN;
48 + wb->options = 0;
49 wb->date = 0;
50
51 buffer_overflow_check(wb);
src/web_buffer.h
+6 -1
@@ -11,10 +11,15 @@ typedef struct web_buffer {
11 size_t size; // allocation size of buffer
12 size_t len; // current data length in buffer
13 char *buffer; // the buffer
14 - int contenttype;
14 + uint8_t contenttype;
15 + uint8_t options;
16 time_t date; // the date this content has been generated
17 } BUFFER;
18
19 +// options
20 +#define WB_CONTENT_CACHEABLE 1
21 +#define WB_CONTENT_NO_CACHEABLE 2
22 +
23 // content-types
24 #define CT_APPLICATION_JSON 1
25 #define CT_TEXT_PLAIN 2
src/web_client.c
+11 -4
@@ -1311,6 +1311,7 @@ void web_client_process(struct web_client *w) {
1311 "Access-Control-Allow-Origin: *\r\n"
1312 "Access-Control-Allow-Methods: GET, OPTIONS\r\n"
1313 "Access-Control-Allow-Headers: accept, x-requested-with\r\n"
1314 + "Access-Control-Max-Age: 86400\r\n"
1315 "Date: %s\r\n"
1316 , code, code_msg
1317 , w->keepalive?"keep-alive":"close"
@@ -1321,16 +1322,22 @@ void web_client_process(struct web_client *w) {
1322 if(buffer_strlen(w->response.header))
1323 buffer_strcat(w->response.header_output, buffer_tostring(w->response.header));
1324
1324 - if(w->mode == WEB_CLIENT_MODE_NORMAL) {
1325 + if(w->mode == WEB_CLIENT_MODE_NORMAL && (w->response.data->options & WB_CONTENT_NO_CACHEABLE)) {
1326 buffer_sprintf(w->response.header_output,
1327 "Expires: %s\r\n"
1328 "Cache-Control: no-cache\r\n"
1328 - "Access-Control-Max-Age: 0\r\n"
1329 , date);
1330 }
1331 else {
1332 - buffer_strcat(w->response.header_output, "Cache-Control: public\r\n");
1333 - buffer_strcat(w->response.header_output, "Access-Control-Max-Age: 3600\r\n");
1332 + char edate[100];
1333 + time_t et = w->response.data->date + 86400;
1334 + struct tm etmbuf, *etm = gmtime_r(&et, &etmbuf);
1335 + strftime(edate, sizeof(edate), "%a, %d %b %Y %H:%M:%S %Z", etm);
1336 +
1337 + buffer_sprintf(w->response.header_output,
1338 + "Expires: %s\r\n"
1339 + "Cache-Control: public\r\n"
1340 + , edate);
1341 }
1342
1343 // if we know the content length, put it