diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Keep clone files and oversized responses out of the cache
The dumb transport reads files that already sit on the disk, so a pack copied into a slot cost that disk twice and the request a second write of every byte. A snapshot took a slot whatever its size, so a visitor naming distinct refs and ids could fill the cache root with archives. `cache-max-slot-size`, 64 MB unless set, now serves a larger response from the lock file and drops it, along with any expired copy it would have replaced.
Diffstat (limited to '')
-rw-r--r--source/cgit.c20
1 file changed, 19 insertions, 1 deletion
diff --git a/source/cgit.c b/source/cgit.c
index 5806293..3e47dbe 100644
--- a/source/cgit.c
+++ b/source/cgit.c
@@ -100,6 +100,9 @@ static void prepare_context(void)
ctx.cfg.cache_scan_ttl = 15;
ctx.cfg.cache_dynamic_ttl = 5;
ctx.cfg.cache_static_ttl = -1;
+ // Counted in kilobytes, so sixty-four megabytes, past which a response
+ // is served but not kept.
+ ctx.cfg.cache_max_slot_size = 64 * 1024;
ctx.cfg.case_sensitive_sort = 1;
ctx.cfg.branch_sort = 0;
ctx.cfg.commit_sort = 0;
@@ -608,6 +611,8 @@ static void apply_config(const char *name, const char *value)
ctx.cfg.cache_about_ttl = atoi(value);
else if (!strcmp(name, "cache-snapshot-ttl"))
ctx.cfg.cache_snapshot_ttl = atoi(value);
+ else if (!strcmp(name, "cache-max-slot-size"))
+ ctx.cfg.cache_max_slot_size = atoi(value);
else if (!strcmp(name, "case-sensitive-sort"))
ctx.cfg.case_sensitive_sort = atoi(value);
else if (!strcmp(name, "about-filter"))
@@ -908,12 +913,20 @@ static int page_is_static(void)
*/
static int calc_ttl(void)
{
+ const struct cgit_cmd *cmd;
+
if (!ctx.repo)
return ctx.cfg.cache_index_ttl;
if (!ctx.qry.page)
return ctx.cfg.cache_summary_ttl;
+ // The dumb transport serves files that already sit on the disk, so a
+ // copy in a slot would cost that disk twice and gain nothing.
+ cmd = cgit_find_cmd(ctx.qry.page);
+ if (cmd && cmd->is_clone)
+ return 0;
+
if (!strcmp(ctx.qry.page, "about"))
return ctx.cfg.cache_about_ttl;
@@ -1304,6 +1317,7 @@ int cmd_main(int argc, const char **argv)
{
struct strbuf cache_key = STRBUF_INIT;
const char *path;
+ size_t max_bytes = 0;
int err, ttl;
isolate_git_environment();
@@ -1357,8 +1371,12 @@ int cmd_main(int argc, const char **argv)
if (!ctx.env.authenticated || (ctx.env.request_method && !strcmp(ctx.env.request_method, "HEAD")))
ctx.cfg.cache_size = 0;
+ // Written in kilobytes in cgitrc, where zero and below lift the bound.
+ if (ctx.cfg.cache_max_slot_size > 0)
+ max_bytes = (size_t)ctx.cfg.cache_max_slot_size * 1024;
build_cache_key(&cache_key);
- err = cache_process(ctx.cfg.cache_size, ctx.cfg.cache_root, cache_key.buf, ttl, process_request);
+ err = cache_process(ctx.cfg.cache_size, ctx.cfg.cache_root, cache_key.buf, ttl,
+ max_bytes, process_request);
strbuf_release(&cache_key);
cgit_cleanup_filters();