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 <[email protected]>

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(&param2[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

_______________________________________________
CGit mailing list
[email protected]
http://lists.zx2c4.com/mailman/listinfo/cgit

Reply via email to