about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorLars Hjemli2009-02-13 20:43:30 +0100
committerLars Hjemli2009-07-25 12:55:15 +0200
commitc4d46c7035d07070ac1ebf0c0b44df927358687f (patch)
tree562cf4f01afe78b92b13ad5be5dc01e07db04a66
parentMerge branch 'lh/embedded' (diff)
downloadcgit-c4d46c7035d07070ac1ebf0c0b44df927358687f.tar.gz
cgit-c4d46c7035d07070ac1ebf0c0b44df927358687f.zip
Add support for mime type registration and lookup
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>
-rw-r--r--cgit.c11
-rw-r--r--cgit.h2
-rw-r--r--cgitrc.5.txt17
-rw-r--r--ui-plain.c20
4 files changed, 45 insertions, 5 deletions
diff --git a/cgit.c b/cgit.c index 2039ab1..4f414c3 100644 --- a/cgit.c +++ b/cgit.c
@@ -17,6 +17,14 @@
17 17
18const char *cgit_version = CGIT_VERSION; 18const char *cgit_version = CGIT_VERSION;
19 19
20void add_mimetype(const char *name, const char *value)
21{
22 struct string_list_item *item;
23
24 item = string_list_insert(xstrdup(name), &ctx.cfg.mimetypes);
25 item->util = xstrdup(value);
26}
27
20void config_cb(const char *name, const char *value) 28void config_cb(const char *name, const char *value)
21{ 29{
22 if (!strcmp(name, "root-title")) 30 if (!strcmp(name, "root-title"))
@@ -101,6 +109,8 @@ void config_cb(const char *name, const char *value)
101 ctx.cfg.clone_prefix = xstrdup(value); 109 ctx.cfg.clone_prefix = xstrdup(value);
102 else if (!strcmp(name, "local-time")) 110 else if (!strcmp(name, "local-time"))
103 ctx.cfg.local_time = atoi(value); 111 ctx.cfg.local_time = atoi(value);
112 else if (!prefixcmp(name, "mimetype."))
113 add_mimetype(name + 9, value);
104 else if (!strcmp(name, "repo.group")) 114 else if (!strcmp(name, "repo.group"))
105 ctx.cfg.repo_group = xstrdup(value); 115 ctx.cfg.repo_group = xstrdup(value);
106 else if (!strcmp(name, "repo.url")) 116 else if (!strcmp(name, "repo.url"))
@@ -213,6 +223,7 @@ static void prepare_context(struct cgit_context *ctx)
213 ctx->page.modified = time(NULL); 223 ctx->page.modified = time(NULL);
214 ctx->page.expires = ctx->page.modified; 224 ctx->page.expires = ctx->page.modified;
215 ctx->page.etag = NULL; 225 ctx->page.etag = NULL;
226 memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list));
216} 227}
217 228
218struct refmatch { 229struct refmatch {
diff --git a/cgit.h b/cgit.h index 8c64efe..9259f33 100644 --- a/cgit.h +++ b/cgit.h
@@ -15,6 +15,7 @@
15#include <revision.h> 15#include <revision.h>
16#include <log-tree.h> 16#include <log-tree.h>
17#include <archive.h> 17#include <archive.h>
18#include <string-list.h>
18#include <xdiff-interface.h> 19#include <xdiff-interface.h>
19#include <xdiff/xdiff.h> 20#include <xdiff/xdiff.h>
20#include <utf8.h> 21#include <utf8.h>
@@ -174,6 +175,7 @@ struct cgit_config {
174 int summary_branches; 175 int summary_branches;
175 int summary_log; 176 int summary_log;
176 int summary_tags; 177 int summary_tags;
178 struct string_list mimetypes;
177}; 179};
178 180
179struct cgit_page { 181struct cgit_page {
diff --git a/cgitrc.5.txt b/cgitrc.5.txt index a207fe0..7256ec0 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt
@@ -147,6 +147,10 @@ max-stats::
147 "month", "quarter" and "year". If unspecified, statistics are 147 "month", "quarter" and "year". If unspecified, statistics are
148 disabled. Default value: none. See also: "repo.max-stats". 148 disabled. Default value: none. See also: "repo.max-stats".
149 149
150mimetype.<ext>::
151 Set the mimetype for the specified filename extension. This is used
152 by the `plain` command when returning blob content.
153
150module-link:: 154module-link::
151 Text which will be used as the formatstring for a hyperlink when a 155 Text which will be used as the formatstring for a hyperlink when a
152 submodule is printed in a directory listing. The arguments for the 156 submodule is printed in a directory listing. The arguments for the
@@ -325,6 +329,19 @@ snapshots=tar.gz tar.bz2 zip
325 329
326 330
327## 331##
332## List of common mimetypes
333##
334
335mimetype.git=image/git
336mimetype.html=text/html
337mimetype.jpg=image/jpeg
338mimetype.jpeg=image/jpeg
339mimetype.pdf=application/pdf
340mimetype.png=image/png
341mimetype.svg=image/svg+xml
342
343
344##
328## List of repositories. 345## List of repositories.
329## PS: Any repositories listed when repo.group is unset will not be 346## PS: Any repositories listed when repo.group is unset will not be
330## displayed under a group heading 347## displayed under a group heading
diff --git a/ui-plain.c b/ui-plain.c index 93a3a05..27c6dae 100644 --- a/ui-plain.c +++ b/ui-plain.c
@@ -17,8 +17,9 @@ int match;
17static void print_object(const unsigned char *sha1, const char *path) 17static void print_object(const unsigned char *sha1, const char *path)
18{ 18{
19 enum object_type type; 19 enum object_type type;
20 char *buf; 20 char *buf, *ext;
21 unsigned long size; 21 unsigned long size;
22 struct string_list_item *mime;
22 23
23 type = sha1_object_info(sha1, &size); 24 type = sha1_object_info(sha1, &size);
24 if (type == OBJ_BAD) { 25 if (type == OBJ_BAD) {
@@ -31,10 +32,19 @@ static void print_object(const unsigned char *sha1, const char *path)
31 html_status(404, "Not found", 0); 32 html_status(404, "Not found", 0);
32 return; 33 return;
33 } 34 }
34 if (buffer_is_binary(buf, size)) 35 ctx.page.mimetype = NULL;
35 ctx.page.mimetype = "application/octet-stream"; 36 ext = strrchr(path, '.');
36 else 37 if (ext && *(++ext)) {
37 ctx.page.mimetype = "text/plain"; 38 mime = string_list_lookup(ext, &ctx.cfg.mimetypes);
39 if (mime)
40 ctx.page.mimetype = (char *)mime->util;
41 }
42 if (!ctx.page.mimetype) {
43 if (buffer_is_binary(buf, size))
44 ctx.page.mimetype = "application/octet-stream";
45 else
46 ctx.page.mimetype = "text/plain";
47 }
38 ctx.page.filename = fmt("%s", path); 48 ctx.page.filename = fmt("%s", path);
39 ctx.page.size = size; 49 ctx.page.size = size;
40 ctx.page.etag = sha1_to_hex(sha1); 50 ctx.page.etag = sha1_to_hex(sha1);