[PATCH 2/2] ttl: Support different TTL times based on cache-control
Tim Nordell
tim.nordell at logicpd.com
Fri Feb 26 21:57:09 CET 2016
Allow the client browser to pass in "max-age=0" and "no-cache"
to control a separate TTL time on the server for each type of
page. This extends the TTL field to have the additional form
of:
some-ttl=5:1
where 5 is the number of minutes if the user were to simply
load the page, and 1 is the number of minutes if the user were
to reload the page in their web browser (hit refresh).
Signed-off-by: Tim Nordell <tim.nordell at logicpd.com>
diff --git a/cgit.c b/cgit.c
index 963aee8..0ca1baa 100644
--- a/cgit.c
+++ b/cgit.c
@@ -29,6 +29,30 @@ static void add_mimetype(const char *name, const char *value)
static void process_cached_repolist(const char *path);
+/**
+ * \brief Convert TTL field into a TTL structure
+ *
+ * \param value Value from field; should be one of the following forms:
+ * [normal]
+ * [normal]:[forced]
+ * \return Parsed TTL value
+ */
+static struct cgit_ttl ttl_value(const char *value)
+{
+ char *param2;
+ struct cgit_ttl ret;
+
+ ret.normal = atoi(value);
+
+ param2 = strchr(value, ':');
+ if(NULL != param2)
+ ret.forced = atoi(¶m2[1]);
+ else
+ ret.forced = -1;
+
+ return ret;
+}
+
static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
{
struct string_list_item *item;
@@ -187,19 +211,19 @@ static void config_cb(const char *name, const char *value)
else if (!strcmp(name, "cache-root"))
ctx.cfg.cache_root = xstrdup(expand_macros(value));
else if (!strcmp(name, "cache-root-ttl"))
- ctx.cfg.cache_root_ttl = atoi(value);
+ ctx.cfg.cache_root_ttl = ttl_value(value);
else if (!strcmp(name, "cache-repo-ttl"))
- ctx.cfg.cache_repo_ttl = atoi(value);
+ ctx.cfg.cache_repo_ttl = ttl_value(value);
else if (!strcmp(name, "cache-scanrc-ttl"))
ctx.cfg.cache_scanrc_ttl = atoi(value);
else if (!strcmp(name, "cache-static-ttl"))
- ctx.cfg.cache_static_ttl = atoi(value);
+ ctx.cfg.cache_static_ttl = ttl_value(value);
else if (!strcmp(name, "cache-dynamic-ttl"))
- ctx.cfg.cache_dynamic_ttl = atoi(value);
+ ctx.cfg.cache_dynamic_ttl = ttl_value(value);
else if (!strcmp(name, "cache-about-ttl"))
- ctx.cfg.cache_about_ttl = atoi(value);
+ ctx.cfg.cache_about_ttl = ttl_value(value);
else if (!strcmp(name, "cache-snapshot-ttl"))
- ctx.cfg.cache_snapshot_ttl = atoi(value);
+ ctx.cfg.cache_snapshot_ttl = ttl_value(value);
else if (!strcmp(name, "case-sensitive-sort"))
ctx.cfg.case_sensitive_sort = atoi(value);
else if (!strcmp(name, "about-filter"))
@@ -352,13 +376,19 @@ static void prepare_context(void)
ctx.cfg.cache_size = 0;
ctx.cfg.cache_max_create_time = 5;
ctx.cfg.cache_root = CGIT_CACHE_ROOT;
- ctx.cfg.cache_about_ttl = 15;
- ctx.cfg.cache_snapshot_ttl = 5;
- ctx.cfg.cache_repo_ttl = 5;
- ctx.cfg.cache_root_ttl = 5;
+ ctx.cfg.cache_about_ttl.normal = 15;
+ ctx.cfg.cache_about_ttl.forced = -1;
+ ctx.cfg.cache_snapshot_ttl.normal = 5;
+ ctx.cfg.cache_snapshot_ttl.forced = -1;
+ ctx.cfg.cache_repo_ttl.normal = 5;
+ ctx.cfg.cache_repo_ttl.forced = -1;
+ ctx.cfg.cache_root_ttl.normal = 5;
+ ctx.cfg.cache_root_ttl.forced = -1;
ctx.cfg.cache_scanrc_ttl = 15;
- ctx.cfg.cache_dynamic_ttl = 5;
- ctx.cfg.cache_static_ttl = -1;
+ ctx.cfg.cache_dynamic_ttl.normal = 5;
+ ctx.cfg.cache_dynamic_ttl.forced = -1;
+ ctx.cfg.cache_static_ttl.normal = -1;
+ ctx.cfg.cache_static_ttl.forced = -1;
ctx.cfg.case_sensitive_sort = 1;
ctx.cfg.branch_sort = 0;
ctx.cfg.commit_sort = 0;
@@ -405,6 +435,7 @@ static void prepare_context(void)
ctx.env.server_port = getenv("SERVER_PORT");
ctx.env.http_cookie = getenv("HTTP_COOKIE");
ctx.env.http_referer = getenv("HTTP_REFERER");
+ ctx.env.http_cache_control = getenv("HTTP_CACHE_CONTROL");
ctx.env.content_length = getenv("CONTENT_LENGTH") ? strtoul(getenv("CONTENT_LENGTH"), NULL, 10) : 0;
ctx.env.authenticated = 0;
ctx.page.mimetype = "text/html";
@@ -1006,7 +1037,7 @@ static void cgit_parse_args(int argc, const char **argv)
static int calc_ttl(void)
{
const int ttl_conversion_multiplier = 60;
- int ttl;
+ struct cgit_ttl ttl;
if (!ctx.repo)
ttl = ctx.cfg.cache_root_ttl;
@@ -1023,8 +1054,14 @@ static int calc_ttl(void)
else
ttl = ctx.cfg.cache_repo_ttl;
- if (ttl >= 0)
- return ttl * ttl_conversion_multiplier;
+ if(ttl.forced >= 0 && NULL != ctx.env.http_cache_control &&
+ (!strcmp(ctx.env.http_cache_control, "max-age=0") ||
+ !strcmp(ctx.env.http_cache_control, "no-cache"))
+ )
+ return ttl.forced * ttl_conversion_multiplier;
+
+ if (ttl.normal >= 0)
+ return ttl.normal * ttl_conversion_multiplier;
return 10 * 365 * 24 * 60 * 60; /* 10 years */
}
diff --git a/cgit.h b/cgit.h
index 325432b..350d25d 100644
--- a/cgit.h
+++ b/cgit.h
@@ -185,6 +185,11 @@ struct cgit_query {
char *vpath;
};
+struct cgit_ttl {
+ int normal;
+ int forced;
+};
+
struct cgit_config {
char *agefile;
char *cache_root;
@@ -213,14 +218,14 @@ struct cgit_config {
char *virtual_root; /* Always ends with '/'. */
char *strict_export;
int cache_size;
- int cache_dynamic_ttl;
int cache_max_create_time;
- int cache_repo_ttl;
- int cache_root_ttl;
int cache_scanrc_ttl;
- int cache_static_ttl;
- int cache_about_ttl;
- int cache_snapshot_ttl;
+ struct cgit_ttl cache_root_ttl;
+ struct cgit_ttl cache_repo_ttl;
+ struct cgit_ttl cache_about_ttl;
+ struct cgit_ttl cache_static_ttl;
+ struct cgit_ttl cache_dynamic_ttl;
+ struct cgit_ttl cache_snapshot_ttl;
int case_sensitive_sort;
int embedded;
int enable_filter_overrides;
@@ -295,6 +300,7 @@ struct cgit_environment {
const char *server_port;
const char *http_cookie;
const char *http_referer;
+ const char *http_cache_control;
unsigned int content_length;
int authenticated;
};
diff --git a/ui-shared.c b/ui-shared.c
index 9a38aa9..2ab2fd9 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -789,7 +789,7 @@ void cgit_print_docend(void)
void cgit_print_error_page(int code, const char *msg, const char *fmt, ...)
{
va_list ap;
- ctx.page.expires = ctx.cfg.cache_dynamic_ttl;
+ ctx.page.expires = ctx.cfg.cache_dynamic_ttl.normal;
ctx.page.status = code;
ctx.page.statusmsg = msg;
cgit_print_http_headers();
--
2.4.9
More information about the CGit
mailing list