Diffstat (limited to 'ui-ci.c')
| -rw-r--r-- | ui-ci.c | 129 |
1 files changed, 0 insertions, 129 deletions
diff --git a/ui-ci.c b/ui-ci.c deleted file mode 100644 index 1c9f39c..0000000 --- a/ui-ci.c +++ /dev/null @@ -1,129 +0,0 @@ -/* ui-ci.c: redirect to an external CI system - * - * Copyright (C) 2006-2025 cgit Development Team <cgit@lists.zx2c4.com> - * - * Licensed under GNU General Public License v2 - * (see COPYING for full license text) - */ - -#define USE_THE_REPOSITORY_VARIABLE - -#include "cgit.h" -#include "ui-ci.h" -#include "html.h" -#include "ui-shared.h" - -/* Memoized outcome of resolving the ci url for this request: -1 while - * unresolved, 0 when there is no ci url for the current ref, and 1 when - * ci_url holds the url to redirect to. - */ -static int ci_resolved = -1; -static char *ci_url; - -static int ref_is_tag(const char *ref) -{ - struct strbuf fullref = STRBUF_INIT; - struct object_id oid; - int is_tag; - - strbuf_addf(&fullref, "refs/tags/%s", ref); - is_tag = !repo_get_oid(the_repository, fullref.buf, &oid); - strbuf_release(&fullref); - return is_tag; -} - -/* Append the repository url with any ".git" suffix removed and all - * slashes replaced by dashes, e.g. "sayauz/web.git" becomes - * "sayauz-web". - */ -static void add_repo_slug(struct strbuf *buf, const char *url) -{ - size_t len, i; - - if (!strip_suffix(url, ".git", &len)) - len = strlen(url); - for (i = 0; i < len; i++) - strbuf_addch(buf, url[i] == '/' ? '-' : url[i]); -} - -static char *expand_ci_url(const char *template) -{ - const char *p, *rest; - struct strbuf buf = STRBUF_INIT; - - for (p = template; *p; p++) { - if (*p != '$') { - strbuf_addch(&buf, *p); - continue; - } - if (skip_prefix(p, "$ref", &rest)) - strbuf_addstr(&buf, ctx.qry.head); - else if (skip_prefix(p, "$repo", &rest)) - strbuf_addstr(&buf, ctx.repo->url); - else if (skip_prefix(p, "$slug", &rest)) - add_repo_slug(&buf, ctx.repo->url); - else if (skip_prefix(p, "$$", &rest)) - strbuf_addch(&buf, '$'); - else { - strbuf_addch(&buf, '$'); - continue; - } - p = rest - 1; - } - return strbuf_detach(&buf, NULL); -} - -static void resolve_ci_url(void) -{ - const char *template; - - if (ci_resolved != -1) - return; - ci_resolved = 0; - - if (!ctx.repo || !ctx.qry.head || !cgit_have_repository()) - return; - - if (ref_is_tag(ctx.qry.head)) - template = ctx.repo->ci_tag_url; - else - template = ctx.repo->ci_branch_url; - if (!template) - template = ctx.repo->ci_url; - if (!template) - return; - - ci_url = expand_ci_url(template); - ci_resolved = 1; -} - -int cgit_ci_available(void) -{ - resolve_ci_url(); - return ci_resolved == 1; -} - -void cgit_print_ci(void) -{ - resolve_ci_url(); - - if (ci_resolved != 1) { - cgit_print_error_page(404, "Not found", - "No ci url available for %s", - ctx.qry.head); - return; - } - - /* The expanded template is emitted verbatim rather than through - * cgit_redirect(), which percent-encodes characters such as '?', - * '=' and '%' that are meaningful in a ci url. Refuse anything - * which could be used to smuggle in extra response headers. - */ - if (strpbrk(ci_url, "\r\n")) { - cgit_print_error_page(500, "Internal server error", - "Malformed ci url"); - return; - } - - htmlf("Status: 302 Found\nLocation: %s\n\n", ci_url); -} |