cgit

commit 17e3ff42646f182911fd0e5d872082977538db9e

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);