From aaa8ecf0d28488754c6eb214c9e11b311d2710b7 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 22 Aug 2026 10:36:23 -0700 Subject: Cache id-pinned pages and snapshots as static --- source/cgit.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'source') 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; -- cgit v2.8.0