Author: Lars Hjemli <hjemli@gmail.com>
Merge branch 'lh/mimetypes'
cgit.c | 11 +++++++++++ cgit.h | 2 ++ cgitrc.5.txt | 17 +++++++++++++++++ ui-plain.c | 20 +++++++++++++++-----
diff --git a/cgit.c b/cgit.c index f6bb0c7ed01bdb8402ce26c4490609a21e24e4d4..aa1107ae2100f0c13b47f18085f38542bfb3c570 100644 --- a/cgit.c +++ b/cgit.c @@ -17,6 +17,14 @@ #include "scan-tree.h" const char *cgit_version = CGIT_VERSION; +void add_mimetype(const char *name, const char *value) +{ + struct string_list_item *item; + + item = string_list_insert(xstrdup(name), &ctx.cfg.mimetypes); + item->util = xstrdup(value); +} + void config_cb(const char *name, const char *value) { if (!strcmp(name, "root-title")) @@ -103,6 +111,8 @@ else if (!strcmp(name, "clone-prefix")) ctx.cfg.clone_prefix = xstrdup(value); else if (!strcmp(name, "local-time")) ctx.cfg.local_time = atoi(value); + else if (!prefixcmp(name, "mimetype.")) + add_mimetype(name + 9, value); else if (!strcmp(name, "repo.group")) ctx.cfg.repo_group = xstrdup(value); else if (!strcmp(name, "repo.url")) @@ -215,6 +225,7 @@ ctx->page.size = 0; ctx->page.modified = time(NULL); ctx->page.expires = ctx->page.modified; ctx->page.etag = NULL; + memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list)); } struct refmatch { diff --git a/cgit.h b/cgit.h index acb5e8fd52ff1e9a1e8e16dbcbb10569cef36a74..1194eb0209880289729ac3a196d6037ea7427561 100644 --- a/cgit.h +++ b/cgit.h @@ -15,6 +15,7 @@ #include#include <revision.h> #include <log-tree.h> #include <archive.h> +#include <string-list.h> #include <xdiff-interface.h> #include <xdiff/xdiff.h> #include <utf8.h> @@ -175,6 +176,7 @@ int snapshots; int summary_branches; int summary_log; int summary_tags; + struct string_list mimetypes; }; struct cgit_page { diff --git a/cgitrc.5.txt b/cgitrc.5.txt index 77549236072347a9d2c95301f188f822e117e4ba..0412f64acb507b3a2fa652108890e367017c0732 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@ -147,6 +147,10 @@ Set the default maximum statistics period. Valid values are "week", "month", "quarter" and "year". If unspecified, statistics are disabled. Default value: none. See also: "repo.max-stats". +mimetype.<ext>:: + Set the mimetype for the specified filename extension. This is used + by the `plain` command when returning blob content. + module-link:: Text which will be used as the formatstring for a hyperlink when a submodule is printed in a directory listing. The arguments for the @@ -326,6 +330,19 @@ # Allow download of tar.gz, tar.bz2 and zip-files snapshots=tar.gz tar.bz2 zip + + +## +## List of common mimetypes +## + +mimetype.git=image/git +mimetype.html=text/html +mimetype.jpg=image/jpeg +mimetype.jpeg=image/jpeg +mimetype.pdf=application/pdf +mimetype.png=image/png +mimetype.svg=image/svg+xml ## diff --git a/ui-plain.c b/ui-plain.c index 93a3a05ac50f7a43b3c50529a011f0c9fdbf547c..27c6daec7f1dc71bfd7b8b74c8179467a5d39224 100644 --- a/ui-plain.c +++ b/ui-plain.c @@ -17,8 +17,9 @@ static void print_object(const unsigned char *sha1, const char *path) { enum object_type type; - char *buf; + char *buf, *ext; unsigned long size; + struct string_list_item *mime; type = sha1_object_info(sha1, &size); if (type == OBJ_BAD) { @@ -31,10 +32,19 @@ if (!buf) { html_status(404, "Not found", 0); return; } - if (buffer_is_binary(buf, size)) - ctx.page.mimetype = "application/octet-stream"; - else - ctx.page.mimetype = "text/plain"; + ctx.page.mimetype = NULL; + ext = strrchr(path, '.'); + if (ext && *(++ext)) { + mime = string_list_lookup(ext, &ctx.cfg.mimetypes); + if (mime) + ctx.page.mimetype = (char *)mime->util; + } + if (!ctx.page.mimetype) { + if (buffer_is_binary(buf, size)) + ctx.page.mimetype = "application/octet-stream"; + else + ctx.page.mimetype = "text/plain"; + } ctx.page.filename = fmt("%s", path); ctx.page.size = size; ctx.page.etag = sha1_to_hex(sha1);