diff options
author | Costa Tsaousis (ktsaou) <costa@tsaousis.gr> | 2016-01-16 21:11:12 +0200 |
---|---|---|
committer | Costa Tsaousis (ktsaou) <costa@tsaousis.gr> | 2016-01-16 21:11:12 +0200 |
commit | 253dbf6a5a8bf3f8fa74f676af41b68cd39d05d6 (patch) | |
tree | 676b52e45869f178fbc2a4dd144a9f5966a8015f /src | |
parent | 6a1cd14e17718c5b53680b8cf8d9a63b232ceb7e (diff) |
finer cache control; Expires header is now always added; default expiration for static content is a day; #37
Diffstat (limited to 'src')
-rwxr-xr-x | src/rrd2json.c | 30 | ||||
-rwxr-xr-x | src/web_buffer.c | 1 | ||||
-rwxr-xr-x | src/web_buffer.h | 7 | ||||
-rwxr-xr-x | src/web_client.c | 15 |
4 files changed, 45 insertions, 8 deletions
diff --git a/src/rrd2json.c b/src/rrd2json.c index 7a5f6df3e5..b9a123db66 100755 --- a/src/rrd2json.c +++ b/src/rrd2json.c @@ -259,16 +259,21 @@ void rrd_stats_all_json(BUFFER *wb) // ---------------------------------------------------------------------------- -// RRDR options +// RRDR dimension options #define RRDR_EMPTY 0x01 // the dimension contains / the value is empty (null) #define RRDR_RESET 0x02 // the dimension contains / the value is reset #define RRDR_HIDDEN 0x04 // the dimension contains / the value is hidden #define RRDR_NONZERO 0x08 // the dimension contains / the value is non-zero +// RRDR result options +#define RRDR_RESULT_OPTION_ABSOLUTE 0x00000001 +#define RRDR_RESULT_OPTION_RELATIVE 0x00000002 typedef struct rrdresult { RRDSET *st; // the chart this result refers to + uint32_t result_options; // RRDR_RESULT_OPTION_* + int d; // the number of dimensions long n; // the number of values in the arrays long rows; // the number of rows used @@ -1200,6 +1205,7 @@ cleanup: RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int group_method) { int debug = st->debug; + int absolute_period_requested = -1; time_t first_entry_t = rrdset_first_entry_t(st); 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 if(before == 0 && after == 0) { before = last_entry_t; after = first_entry_t; + absolute_period_requested = 0; } // allow relative for before and after - if(before <= st->update_every * st->entries) + if(before <= st->update_every * st->entries) { before = last_entry_t + before; + absolute_period_requested = 0; + } - if(after <= st->update_every * st->entries) + if(after <= st->update_every * st->entries) { after = last_entry_t + after; + absolute_period_requested = 0; + } + + if(absolute_period_requested == -1) + absolute_period_requested = 1; // make sure they are within our timeframe 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 return r; } + if(absolute_period_requested == 1) + r->result_options |= RRDR_RESULT_OPTION_ABSOLUTE; + else + r->result_options |= RRDR_RESULT_OPTION_RELATIVE; + // find how many dimensions we have long dimensions = r->d; @@ -1497,6 +1516,11 @@ int rrd2format(RRDSET *st, BUFFER *wb, BUFFER *dimensions, uint32_t format, long return 500; } + if(r->result_options & RRDR_RESULT_OPTION_RELATIVE) + wb->options |= WB_CONTENT_NO_CACHEABLE; + else if(r->result_options & RRDR_RESULT_OPTION_ABSOLUTE) + wb->options |= WB_CONTENT_CACHEABLE; + options = rrdr_check_options(r, options, (dimensions)?buffer_tostring(dimensions):NULL); if(dimensions) diff --git a/src/web_buffer.c b/src/web_buffer.c index 7a169eb40a..482eb3900e 100755 --- a/src/web_buffer.c +++ b/src/web_buffer.c @@ -45,6 +45,7 @@ void buffer_reset(BUFFER *wb) buffer_flush(wb); wb->contenttype = CT_TEXT_PLAIN; + wb->options = 0; wb->date = 0; buffer_overflow_check(wb); diff --git a/src/web_buffer.h b/src/web_buffer.h index 4f01f19907..dfffb64949 100755 --- a/src/web_buffer.h +++ b/src/web_buffer.h @@ -11,10 +11,15 @@ typedef struct web_buffer { size_t size; // allocation size of buffer size_t len; // current data length in buffer char *buffer; // the buffer - int contenttype; + uint8_t contenttype; + uint8_t options; time_t date; // the date this content has been generated } BUFFER; +// options +#define WB_CONTENT_CACHEABLE 1 +#define WB_CONTENT_NO_CACHEABLE 2 + // content-types #define CT_APPLICATION_JSON 1 #define CT_TEXT_PLAIN 2 diff --git a/src/web_client.c b/src/web_client.c index 3312d70fef..b8eb7bf14d 100755 --- a/src/web_client.c +++ b/src/web_client.c @@ -1311,6 +1311,7 @@ void web_client_process(struct web_client *w) { "Access-Control-Allow-Origin: *\r\n" "Access-Control-Allow-Methods: GET, OPTIONS\r\n" "Access-Control-Allow-Headers: accept, x-requested-with\r\n" + "Access-Control-Max-Age: 86400\r\n" "Date: %s\r\n" , code, code_msg , w->keepalive?"keep-alive":"close" @@ -1321,16 +1322,22 @@ void web_client_process(struct web_client *w) { if(buffer_strlen(w->response.header)) buffer_strcat(w->response.header_output, buffer_tostring(w->response.header)); - if(w->mode == WEB_CLIENT_MODE_NORMAL) { + if(w->mode == WEB_CLIENT_MODE_NORMAL && (w->response.data->options & WB_CONTENT_NO_CACHEABLE)) { buffer_sprintf(w->response.header_output, "Expires: %s\r\n" "Cache-Control: no-cache\r\n" - "Access-Control-Max-Age: 0\r\n" , date); } else { - buffer_strcat(w->response.header_output, "Cache-Control: public\r\n"); - buffer_strcat(w->response.header_output, "Access-Control-Max-Age: 3600\r\n"); + char edate[100]; + time_t et = w->response.data->date + 86400; + struct tm etmbuf, *etm = gmtime_r(&et, &etmbuf); + strftime(edate, sizeof(edate), "%a, %d %b %Y %H:%M:%S %Z", etm); + + buffer_sprintf(w->response.header_output, + "Expires: %s\r\n" + "Cache-Control: public\r\n" + , edate); } // if we know the content length, put it |