diff options
| author | Per Buer <per.buer@gmail.com> | 2026-09-10 21:08:49 +0200 |
|---|---|---|
| committer | Per Buer <per.buer@gmail.com> | 2026-09-10 21:08:49 +0200 |
| commit | 61a2657f3333e8f634134b51dfa41b98320a7908 (patch) | |
| tree | 4c73217972ff767566d08de11d6875e71d182112 | |
| parent | 1dea2b214f46f7d747284f96cc5957057fb16bf8 (diff) | |
02-cgit-output-buffering.patch was cut from a working tree that already
carried the ESI work, so it also contained the enable-esi config hook,
cache_key(), the repolink and cgit_fileurl fragment hunks and the
memrchr fix. That contradicted its README and made it fail to apply on
any tree that already had ESI, which is every tree in this repository.
Regenerate it with only the output buffering change: the html.c buffer
itself and the flushes in cache.c, filter.c, cgit.c and ui-shared.c.
Verified to apply cleanly both to stock cgit and on top of the ESI
commits here.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| -rw-r--r-- | contrib/perf/02-cgit-output-buffering.patch | 147 |
1 files changed, 5 insertions, 142 deletions
diff --git a/contrib/perf/02-cgit-output-buffering.patch b/contrib/perf/02-cgit-output-buffering.patch index 43738f5..fcd9247 100644 --- a/contrib/perf/02-cgit-output-buffering.patch +++ b/contrib/perf/02-cgit-output-buffering.patch @@ -47,19 +47,10 @@ index e70af13..9c36f1a 100644 return errno; diff --git a/cgit.c b/cgit.c -index ca318e8..65e369c 100644 +index a6ed39f..65e369c 100644 --- a/cgit.c +++ b/cgit.c -@@ -197,6 +197,8 @@ static void config_cb(const char *name, const char *value) - ctx.cfg.enable_subject_links = atoi(value); - else if (!strcmp(name, "enable-html-serving")) - ctx.cfg.enable_html_serving = atoi(value); -+ else if (!strcmp(name, "enable-esi")) -+ ctx.cfg.enable_esi = atoi(value); - else if (!strcmp(name, "enable-tree-linenumbers")) - ctx.cfg.enable_tree_linenumbers = atoi(value); - else if (!strcmp(name, "enable-git-config")) -@@ -684,6 +686,7 @@ static inline void authenticate_post(void) +@@ -686,6 +686,7 @@ static inline void authenticate_post(void) len = MAX_AUTHENTICATION_POST_BYTES; if ((len = read(STDIN_FILENO, buffer, len)) < 0) die_errno("Could not read POST from stdin"); @@ -67,33 +58,7 @@ index ca318e8..65e369c 100644 if (write(STDOUT_FILENO, buffer, len) < 0) die_errno("Could not write POST to stdout"); cgit_close_filter(ctx.cfg.auth_filter); -@@ -1045,6 +1048,25 @@ static int calc_ttl(void) - return ctx.cfg.cache_repo_ttl; - } - -+/* -+ * ESI diff fragments are shared between every repository holding the same -+ * objects, so key them on the diff parameters alone rather than on the -+ * full URL. Everything else is keyed on the raw URL as before. -+ */ -+static char *cache_key(void) -+{ -+ if (!ctx.cfg.enable_esi || !ctx.qry.page || -+ strcmp(ctx.qry.page, "esi-diff")) -+ return ctx.qry.raw; -+ -+ return fmtalloc("esi-diff/%s?id=%s&id2=%s&dt=%d&context=%d&ignorews=%d", -+ ctx.qry.path ? ctx.qry.path : "", -+ ctx.qry.oid ? ctx.qry.oid : "", -+ ctx.qry.oid2 ? ctx.qry.oid2 : "", -+ ctx.qry.has_difftype ? ctx.qry.difftype : -1, -+ ctx.qry.context, ctx.qry.ignorews); -+} -+ - static NORETURN void cgit_die_routine(const char *msg, va_list params) - { - cgit_vprint_error_page(400, "Bad request", msg, params); -@@ -1057,6 +1079,7 @@ int cmd_main(int argc, const char **argv) +@@ -1078,6 +1079,7 @@ int cmd_main(int argc, const char **argv) int err, ttl; cgit_init_filters(); @@ -101,15 +66,6 @@ index ca318e8..65e369c 100644 atexit(cgit_cleanup_filters); set_die_routine(cgit_die_routine); -@@ -1109,7 +1132,7 @@ 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; - err = cache_process(ctx.cfg.cache_size, ctx.cfg.cache_root, -- ctx.qry.raw, ttl, process_request); -+ cache_key(), ttl, process_request); - cgit_cleanup_filters(); - if (err) - cgit_print_error("Error processing page: %s (%d)", diff --git a/filter.c b/filter.c index c778d05..6b70cc2 100644 --- a/filter.c @@ -196,51 +152,10 @@ index fa4de77..1d384d9 100644 __attribute__((format (printf,1,2))) diff --git a/ui-shared.c b/ui-shared.c -index df52a9b..cb306bc 100644 +index e015590..cb306bc 100644 --- a/ui-shared.c +++ b/ui-shared.c -@@ -143,7 +143,11 @@ char *cgit_fileurl(const char *reponame, const char *pagename, - struct strbuf sb = STRBUF_INIT; - char *delim; - -- if (ctx.cfg.virtual_root) { -+ if (ctx.page.esi_fragment && ctx.cfg.virtual_root) { -+ /* Relative to the <base href> of the including page. */ -+ strbuf_addf(&sb, "%s/%s", pagename, (filename ? filename:"")); -+ delim = "?"; -+ } else if (ctx.cfg.virtual_root) { - strbuf_addf(&sb, "%s%s/%s/%s", ctx.cfg.virtual_root, reponame, - pagename, (filename ? filename:"")); - delim = "?"; -@@ -279,6 +283,20 @@ static char *repolink(const char *title, const char *class, const char *page, - html("'"); - } - html(" href='"); -+ if (ctx.page.esi_fragment && ctx.cfg.virtual_root) { -+ /* -+ * Fragment output is shared between repositories, so links -+ * are relative to the <base href> emitted by the including -+ * page and carry no branch. -+ */ -+ if (page) { -+ html_url_path(page); -+ html("/"); -+ if (path) -+ html_url_path(path); -+ } -+ return fmt("%s", delim); -+ } - if (ctx.cfg.virtual_root) { - html_url_path(ctx.cfg.virtual_root); - html_url_path(ctx.repo->url); -@@ -744,11 +762,19 @@ void cgit_print_http_headers(void) - } - if (!ctx.env.authenticated) - html("Cache-Control: no-cache, no-store\n"); -+ if (ctx.page.esi_frame) -+ html("Surrogate-Control: content=\"ESI/1.0\"\n"); - htmlf("Last-Modified: %s\n", http_date(ctx.page.modified)); - htmlf("Expires: %s\n", http_date(ctx.page.expires)); +@@ -769,6 +769,12 @@ void cgit_print_http_headers(void) if (ctx.page.etag) htmlf("ETag: \"%s\"\n", ctx.page.etag); html("\n"); @@ -253,55 +168,3 @@ index df52a9b..cb306bc 100644 if (ctx.env.request_method && !strcmp(ctx.env.request_method, "HEAD")) exit(0); } -@@ -819,6 +845,14 @@ void cgit_print_docstart(void) - html_txt(ctx.page.title); - html("</title>\n"); - htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version); -+ if (ctx.page.esi_frame && ctx.repo) { -+ /* Links inside ESI fragments are relative to the repo root. */ -+ char *repourl = cgit_repourl(ctx.repo->url); -+ html("<base href='"); -+ html_attr(repourl); -+ html("'/>\n"); -+ free(repourl); -+ } - if (ctx.cfg.robots && *ctx.cfg.robots) - htmlf("<meta name='robots' content='%s'/>\n", ctx.cfg.robots); - -@@ -907,12 +941,16 @@ void cgit_vprint_error_page(int code, const char *msg, const char *fmt, va_list - void cgit_print_layout_start(void) - { - cgit_print_http_headers(); -+ if (ctx.page.esi_fragment) -+ return; - cgit_print_docstart(); - cgit_print_pageheader(); - } - - void cgit_print_layout_end(void) - { -+ if (ctx.page.esi_fragment) -+ return; - cgit_print_docend(); - } - -@@ -1255,9 +1293,18 @@ void cgit_set_title_from_path(const char *path) - if (!path) - return; - -- for (last_slash = path + strlen(path); (slash = memrchr(path, '/', last_slash - path)) != NULL; last_slash = slash) { -+ /* memrchr() is a GNU extension, so find the last '/' by hand. */ -+ last_slash = path + strlen(path); -+ for (;;) { -+ slash = last_slash; -+ while (slash > path && slash[-1] != '/') -+ slash--; -+ if (slash == path) -+ break; -+ slash--; - strbuf_add(&sb, slash + 1, last_slash - slash - 1); - strbuf_addstr(&sb, " \xc2\xab "); -+ last_slash = slash; - } - strbuf_add(&sb, path, last_slash - path); - strbuf_addf(&sb, " - %s", ctx.page.title); |
