summaryrefslogtreecommitdiffabout
path: root/cgit.c
authorLars Hjemli <hjemli@gmail.com>2008-12-26 09:33:01 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2008-12-26 09:33:01 (UTC)
commit377a1c8cedcbd18f42e45c6ab757a603af44df33 (patch) (side-by-side diff)
tree8cfe705b3e68cafc913e7aee62033552082adf47 /cgit.c
parent11456a60deab19f5e3a1d191bdf48adfba9195e4 (diff)
downloadcgit-377a1c8cedcbd18f42e45c6ab757a603af44df33.zip
cgit-377a1c8cedcbd18f42e45c6ab757a603af44df33.tar.gz
cgit-377a1c8cedcbd18f42e45c6ab757a603af44df33.tar.bz2
Untie logic for SCRIPT_NAME and PATH_INFO
SCRIPT_NAME is used as fallback for virtual-root when virtual-root is unspecified in cgitrc and PATH_INFO is used as fallback for the query- string parameter 'url' when the latter is unspecified. But until now, the use of PATH_INFO depended on virtual-root also being unspecified, i.e. it was impossible to use PATH_INFO when virtual-root was specified. This commit makes the fallback on SCRIPT_NAME and PATH_INFO independent code paths, i.e. it is now possible to specify virtual-root in cgitrc while still using PATH_INFO (instead of rewrite rules) to get 'pretty urls'. Noticed-by: Jack Moffitt <jack@chesspark.com> Noticed-by: LiKai Liu <liulk@cs.bu.edu> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'cgit.c') (more/less context) (show whitespace changes)
-rw-r--r--cgit.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/cgit.c b/cgit.c
index 166fbc6..d1cee58 100644
--- a/cgit.c
+++ b/cgit.c
@@ -250,227 +250,228 @@ static int prepare_repo_cmd(struct cgit_context *ctx)
ctx->repo = NULL;
cgit_print_http_headers(ctx);
cgit_print_docstart(ctx);
cgit_print_pageheader(ctx);
cgit_print_error(tmp);
cgit_print_docend();
return 1;
}
ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc);
if (!ctx->qry.head) {
ctx->qry.nohead = 1;
ctx->qry.head = find_default_branch(ctx->repo);
ctx->repo->defbranch = ctx->qry.head;
}
if (!ctx->qry.head) {
cgit_print_http_headers(ctx);
cgit_print_docstart(ctx);
cgit_print_pageheader(ctx);
cgit_print_error("Repository seems to be empty");
cgit_print_docend();
return 1;
}
if (get_sha1(ctx->qry.head, sha1)) {
tmp = xstrdup(ctx->qry.head);
ctx->qry.head = ctx->repo->defbranch;
cgit_print_http_headers(ctx);
cgit_print_docstart(ctx);
cgit_print_pageheader(ctx);
cgit_print_error(fmt("Invalid branch: %s", tmp));
cgit_print_docend();
return 1;
}
return 0;
}
static void process_request(void *cbdata)
{
struct cgit_context *ctx = cbdata;
struct cgit_cmd *cmd;
cmd = cgit_get_cmd(ctx);
if (!cmd) {
ctx->page.title = "cgit error";
ctx->repo = NULL;
cgit_print_http_headers(ctx);
cgit_print_docstart(ctx);
cgit_print_pageheader(ctx);
cgit_print_error("Invalid request");
cgit_print_docend();
return;
}
if (cmd->want_repo && !ctx->repo) {
cgit_print_http_headers(ctx);
cgit_print_docstart(ctx);
cgit_print_pageheader(ctx);
cgit_print_error(fmt("No repository selected"));
cgit_print_docend();
return;
}
if (ctx->repo && prepare_repo_cmd(ctx))
return;
if (cmd->want_layout) {
cgit_print_http_headers(ctx);
cgit_print_docstart(ctx);
cgit_print_pageheader(ctx);
}
cmd->fn(ctx);
if (cmd->want_layout)
cgit_print_docend();
}
int cmp_repos(const void *a, const void *b)
{
const struct cgit_repo *ra = a, *rb = b;
return strcmp(ra->url, rb->url);
}
void print_repo(struct cgit_repo *repo)
{
printf("repo.url=%s\n", repo->url);
printf("repo.name=%s\n", repo->name);
printf("repo.path=%s\n", repo->path);
if (repo->owner)
printf("repo.owner=%s\n", repo->owner);
if (repo->desc)
printf("repo.desc=%s\n", repo->desc);
if (repo->readme)
printf("repo.readme=%s\n", repo->readme);
printf("\n");
}
void print_repolist(struct cgit_repolist *list)
{
int i;
for(i = 0; i < list->count; i++)
print_repo(&list->repos[i]);
}
static void cgit_parse_args(int argc, const char **argv)
{
int i;
int scan = 0;
for (i = 1; i < argc; i++) {
if (!strncmp(argv[i], "--cache=", 8)) {
ctx.cfg.cache_root = xstrdup(argv[i]+8);
}
if (!strcmp(argv[i], "--nocache")) {
ctx.cfg.nocache = 1;
}
if (!strncmp(argv[i], "--query=", 8)) {
ctx.qry.raw = xstrdup(argv[i]+8);
}
if (!strncmp(argv[i], "--repo=", 7)) {
ctx.qry.repo = xstrdup(argv[i]+7);
}
if (!strncmp(argv[i], "--page=", 7)) {
ctx.qry.page = xstrdup(argv[i]+7);
}
if (!strncmp(argv[i], "--head=", 7)) {
ctx.qry.head = xstrdup(argv[i]+7);
ctx.qry.has_symref = 1;
}
if (!strncmp(argv[i], "--sha1=", 7)) {
ctx.qry.sha1 = xstrdup(argv[i]+7);
ctx.qry.has_sha1 = 1;
}
if (!strncmp(argv[i], "--ofs=", 6)) {
ctx.qry.ofs = atoi(argv[i]+6);
}
if (!strncmp(argv[i], "--scan-tree=", 12)) {
scan++;
scan_tree(argv[i] + 12);
}
}
if (scan) {
qsort(cgit_repolist.repos, cgit_repolist.count,
sizeof(struct cgit_repo), cmp_repos);
print_repolist(&cgit_repolist);
exit(0);
}
}
static int calc_ttl()
{
if (!ctx.repo)
return ctx.cfg.cache_root_ttl;
if (!ctx.qry.page)
return ctx.cfg.cache_repo_ttl;
if (ctx.qry.has_symref)
return ctx.cfg.cache_dynamic_ttl;
if (ctx.qry.has_sha1)
return ctx.cfg.cache_static_ttl;
return ctx.cfg.cache_repo_ttl;
}
int main(int argc, const char **argv)
{
const char *cgit_config_env = getenv("CGIT_CONFIG");
const char *path;
char *qry;
int err, ttl;
prepare_context(&ctx);
cgit_repolist.length = 0;
cgit_repolist.count = 0;
cgit_repolist.repos = NULL;
if (getenv("SCRIPT_NAME"))
ctx.cfg.script_name = xstrdup(getenv("SCRIPT_NAME"));
if (getenv("QUERY_STRING"))
ctx.qry.raw = xstrdup(getenv("QUERY_STRING"));
cgit_parse_args(argc, argv);
parse_configfile(cgit_config_env ? cgit_config_env : CGIT_CONFIG,
config_cb);
ctx.repo = NULL;
http_parse_querystring(ctx.qry.raw, querystring_cb);
- /* If virtual-root isn't specified in cgitrc and no url
- * parameter is specified on the querystring, lets pretend
- * that virtualroot equals SCRIPT_NAME and use PATH_INFO as
- * url. This allows cgit to work with virtual urls without
- * the need for rewriterules in the webserver (as long as
- * PATH_INFO is included in the cache lookup key).
+ /* If virtual-root isn't specified in cgitrc, lets pretend
+ * that virtual-root equals SCRIPT_NAME.
*/
- if (!ctx.cfg.virtual_root && !ctx.qry.url) {
+ if (!ctx.cfg.virtual_root)
ctx.cfg.virtual_root = ctx.cfg.script_name;
+
+ /* If no url parameter is specified on the querystring, lets
+ * use PATH_INFO as url. This allows cgit to work with virtual
+ * urls without the need for rewriterules in the webserver (as
+ * long as PATH_INFO is included in the cache lookup key).
+ */
path = getenv("PATH_INFO");
- if (path) {
+ if (!ctx.qry.url && path) {
if (path[0] == '/')
path++;
ctx.qry.url = xstrdup(path);
if (ctx.qry.raw) {
qry = ctx.qry.raw;
ctx.qry.raw = xstrdup(fmt("%s?%s", path, qry));
free(qry);
} else
ctx.qry.raw = ctx.qry.url;
cgit_parse_url(ctx.qry.url);
}
- }
ttl = calc_ttl();
ctx.page.expires += ttl*60;
if (ctx.cfg.nocache)
ctx.cfg.cache_size = 0;
err = cache_process(ctx.cfg.cache_size, ctx.cfg.cache_root,
ctx.qry.raw, ttl, process_request, &ctx);
if (err)
cgit_print_error(fmt("Error processing page: %s (%d)",
strerror(err), err));
return err;
}