aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerry Huberts2011-07-19 10:51:58 +0200
committerLars Hjemli2011-07-19 09:30:07 +0000
commitd01c600c179593a53162a9d4e3040ecfc5078fdc (patch)
tree487f8afaefe7b5f09f05d0d3e3796aaff86b931a
parent96f05018c9dbdf8131f18c87ee3bbbac40e0f729 (diff)
downloadcgit-d01c600c179593a53162a9d4e3040ecfc5078fdc.tar.gz
cgit-d01c600c179593a53162a9d4e3040ecfc5078fdc.tar.bz2
cgit-d01c600c179593a53162a9d4e3040ecfc5078fdc.zip
ui_plain: automatically lookup mimetype when mimetype-file is set
For sites that do not want to configure mime types by hand but still want the correct mime type for 'plain' blobs, configuring a mime type file is made possible. This is handy since such a file is normally already provided (at least on Linux systems). Also, this reflects the gitweb option '$mimetypes_file' Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r--cgit.c2
-rw-r--r--cgit.h1
-rw-r--r--cgitrc.5.txt11
-rw-r--r--ui-plain.c52
4 files changed, 65 insertions, 1 deletions
diff --git a/cgit.c b/cgit.c
index b7807ad..abb698b 100644
--- a/cgit.c
+++ b/cgit.c
@@ -236,6 +236,8 @@ void config_cb(const char *name, const char *value)
236 ctx.cfg.ssdiff = atoi(value); 236 ctx.cfg.ssdiff = atoi(value);
237 else if (!strcmp(name, "agefile")) 237 else if (!strcmp(name, "agefile"))
238 ctx.cfg.agefile = xstrdup(value); 238 ctx.cfg.agefile = xstrdup(value);
239 else if (!strcmp(name, "mimetype-file"))
240 ctx.cfg.mimetype_file = xstrdup(value);
239 else if (!strcmp(name, "renamelimit")) 241 else if (!strcmp(name, "renamelimit"))
240 ctx.cfg.renamelimit = atoi(value); 242 ctx.cfg.renamelimit = atoi(value);
241 else if (!strcmp(name, "remove-suffix")) 243 else if (!strcmp(name, "remove-suffix"))
diff --git a/cgit.h b/cgit.h
index bad66f0..db24941 100644
--- a/cgit.h
+++ b/cgit.h
@@ -175,6 +175,7 @@ struct cgit_config {
175 char *index_info; 175 char *index_info;
176 char *logo; 176 char *logo;
177 char *logo_link; 177 char *logo_link;
178 char *mimetype_file;
178 char *module_link; 179 char *module_link;
179 char *project_list; 180 char *project_list;
180 char *readme; 181 char *readme;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 4721c1e..22a0dc3 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -226,6 +226,17 @@ mimetype.<ext>::
226 Set the mimetype for the specified filename extension. This is used 226 Set the mimetype for the specified filename extension. This is used
227 by the `plain` command when returning blob content. 227 by the `plain` command when returning blob content.
228 228
229mimetype-file::
230 Specifies the file to use for automatic mimetype lookup. If specified
231 then this field is used as a fallback when no "mimetype.<ext>" match is
232 found. If unspecified then no such lookup is performed. The typical file
233 to use on a Linux system is /etc/mime.types. Default value: none. See
234 also: "mimetype.<ext>". The format of the file must comply to:
235 - a comment line is an empty line or a line starting with a hash (#),
236 optionally preceded by whitespace
237 - a non-comment line starts with the mimetype (like image/png), followed
238 by one or more file extensions (like jpg), all separated by whitespace
239
229module-link:: 240module-link::
230 Text which will be used as the formatstring for a hyperlink when a 241 Text which will be used as the formatstring for a hyperlink when a
231 submodule is printed in a directory listing. The arguments for the 242 submodule is printed in a directory listing. The arguments for the
diff --git a/ui-plain.c b/ui-plain.c
index 733db4d..7fecc32 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -6,6 +6,7 @@
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include <stdio.h>
9#include "cgit.h" 10#include "cgit.h"
10#include "html.h" 11#include "html.h"
11#include "ui-shared.h" 12#include "ui-shared.h"
@@ -13,12 +14,53 @@
13int match_baselen; 14int match_baselen;
14int match; 15int match;
15 16
17static char *get_mimetype_from_file(const char *filename, const char *ext)
18{
19 static const char *delimiters;
20 char *result;
21 FILE *fd;
22 char line[1024];
23 char *mimetype;
24 char *token;
25
26 if (!filename)
27 return NULL;
28
29 fd = fopen(filename, "r");
30 if (!fd)
31 return NULL;
32
33 delimiters = " \t\r\n";
34 result = NULL;
35
36 /* loop over all lines in the file */
37 while (!result && fgets(line, sizeof(line), fd)) {
38 mimetype = strtok(line, delimiters);
39
40 /* skip empty lines and comment lines */
41 if (!mimetype || (mimetype[0] == '#'))
42 continue;
43
44 /* loop over all extensions of mimetype */
45 while ((token = strtok(NULL, delimiters))) {
46 if (!strcasecmp(ext, token)) {
47 result = xstrdup(mimetype);
48 break;
49 }
50 }
51 }
52 fclose(fd);
53
54 return result;
55}
56
16static void print_object(const unsigned char *sha1, const char *path) 57static void print_object(const unsigned char *sha1, const char *path)
17{ 58{
18 enum object_type type; 59 enum object_type type;
19 char *buf, *ext; 60 char *buf, *ext;
20 unsigned long size; 61 unsigned long size;
21 struct string_list_item *mime; 62 struct string_list_item *mime;
63 int freemime;
22 64
23 type = sha1_object_info(sha1, &size); 65 type = sha1_object_info(sha1, &size);
24 if (type == OBJ_BAD) { 66 if (type == OBJ_BAD) {
@@ -33,10 +75,16 @@ static void print_object(const unsigned char *sha1, const char *path)
33 } 75 }
34 ctx.page.mimetype = NULL; 76 ctx.page.mimetype = NULL;
35 ext = strrchr(path, '.'); 77 ext = strrchr(path, '.');
78 freemime = 0;
36 if (ext && *(++ext)) { 79 if (ext && *(++ext)) {
37 mime = string_list_lookup(&ctx.cfg.mimetypes, ext); 80 mime = string_list_lookup(&ctx.cfg.mimetypes, ext);
38 if (mime) 81 if (mime) {
39 ctx.page.mimetype = (char *)mime->util; 82 ctx.page.mimetype = (char *)mime->util;
83 } else {
84 ctx.page.mimetype = get_mimetype_from_file(ctx.cfg.mimetype_file, ext);
85 if (ctx.page.mimetype)
86 freemime = 1;
87 }
40 } 88 }
41 if (!ctx.page.mimetype) { 89 if (!ctx.page.mimetype) {
42 if (buffer_is_binary(buf, size)) 90 if (buffer_is_binary(buf, size))
@@ -50,6 +98,8 @@ static void print_object(const unsigned char *sha1, const char *path)
50 cgit_print_http_headers(&ctx); 98 cgit_print_http_headers(&ctx);
51 html_raw(buf, size); 99 html_raw(buf, size);
52 match = 1; 100 match = 1;
101 if (freemime)
102 free(ctx.page.mimetype);
53} 103}
54 104
55static char *buildpath(const char *base, int baselen, const char *path) 105static char *buildpath(const char *base, int baselen, const char *path)