diff options
context:
space:
mode:
-rw-r--r--cgitrc.5.txt4
-rw-r--r--source/cgit.c30
2 files changed, 30 insertions, 4 deletions
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 4040617..c795425 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -95,7 +95,9 @@ cache-size::
cache-snapshot-ttl::
Number which specifies the time-to-live, in minutes, for the cached
- version of snapshots. See also: "CACHE". Default value: "5".
+ version of snapshots. A snapshot requested with a fixed object id
+ uses "cache-static-ttl" instead, since its content can never change.
+ See also: "CACHE". Default value: "5".
cache-static-ttl::
Number which specifies the time-to-live, in minutes, for the cached
diff --git a/source/cgit.c b/source/cgit.c
index 12981c2..f284ad9 100644
--- a/source/cgit.c
+++ b/source/cgit.c
@@ -792,6 +792,25 @@ static void authenticate_cookie(void)
ctx.env.authenticated = cgit_close_filter(ctx.cfg.auth_filter);
}
+/*
+ * Only a full object id names content that can never change. The id parameter
+ * accepts anything git can resolve, so a ref name or an abbreviation arrives
+ * here just as marked as a real id, and a page pinned to one of those must
+ * not be cached under the never-expiring static ttl.
+ */
+static int is_full_oid(const char *rev)
+{
+ size_t len = strlen(rev);
+
+ if (len != GIT_SHA1_HEXSZ && len != GIT_SHA256_HEXSZ)
+ return 0;
+ for (; *rev; rev++) {
+ if (!isxdigit(*rev))
+ return 0;
+ }
+ return 1;
+}
+
// Every cache-*-ttl setting is written in minutes, and so is this.
static int calc_ttl(void)
{
@@ -804,12 +823,17 @@ static int calc_ttl(void)
if (!strcmp(ctx.qry.page, "about"))
return ctx.cfg.cache_about_ttl;
+ // Checked ahead of the snapshot ttl, because a tarball pinned to an
+ // object id can never come out differently and is the most expensive
+ // page to rebuild.
+ if (ctx.qry.has_oid &&
+ (!ctx.qry.oid || is_full_oid(ctx.qry.oid)) &&
+ (!ctx.qry.oid2 || is_full_oid(ctx.qry.oid2)))
+ return ctx.cfg.cache_static_ttl;
+
if (!strcmp(ctx.qry.page, "snapshot"))
return ctx.cfg.cache_snapshot_ttl;
- if (ctx.qry.has_oid)
- return ctx.cfg.cache_static_ttl;
-
if (ctx.qry.has_symref)
return ctx.cfg.cache_dynamic_ttl;