]> granicus.if.org Git - cgit/commitdiff
Add support for mime type registration and lookup
authorLars Hjemli <hjemli@gmail.com>
Fri, 13 Feb 2009 19:43:30 +0000 (20:43 +0100)
committerLars Hjemli <hjemli@gmail.com>
Sat, 25 Jul 2009 10:55:15 +0000 (12:55 +0200)
This patch makes it possible to register mappings from filename
extension to mime type in cgitrc and use this mapping when returning
blob content in `plain` view.

The reason for adding this mapping to cgitrc (as opposed to parsing
something like /etc/mime.types) is to allow quick lookup of a limited
number of filename extensions (/etc/mime-types on my machine currently
contains over 700 entries).

NB: A nice addition to this patch would be to parse /etc/mime.types
when `plain` view is requested for a file with an extension for which
there is no mapping registered in cgitrc.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
cgit.c
cgit.h
cgitrc.5.txt
ui-plain.c

diff --git a/cgit.c b/cgit.c
index 2039ab1de53699b6d29a23f1409461386589a227..4f414c333437a67106c327c7fddbefa964d400c7 100644 (file)
--- a/cgit.c
+++ b/cgit.c
 
 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"))
@@ -101,6 +109,8 @@ void config_cb(const char *name, const char *value)
                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"))
@@ -213,6 +223,7 @@ static void prepare_context(struct cgit_context *ctx)
        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 8c64efeaa6e7f5698751e202b64765280e3985cf..9259f33d60e0d21f6dc61e50e39e094ac43d8a9f 100644 (file)
--- a/cgit.h
+++ b/cgit.h
@@ -15,6 +15,7 @@
 #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>
@@ -174,6 +175,7 @@ struct cgit_config {
        int summary_branches;
        int summary_log;
        int summary_tags;
+       struct string_list mimetypes;
 };
 
 struct cgit_page {
index a207fe07aadb9eb2863b1c47165e804772a12e5b..7256ec0d0fa1a0f6baad63cde084102190cfbce9 100644 (file)
@@ -147,6 +147,10 @@ max-stats::
        "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
@@ -324,6 +328,19 @@ root-readme=/var/www/htdocs/about.html
 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
+
+
 ##
 ## List of repositories.
 ## PS: Any repositories listed when repo.group is unset will not be
index 93a3a05ac50f7a43b3c50529a011f0c9fdbf547c..27c6daec7f1dc71bfd7b8b74c8179467a5d39224 100644 (file)
@@ -17,8 +17,9 @@ int match;
 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 @@ static void print_object(const unsigned char *sha1, const char *path)
                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);