diff options
author | Ferry Huberts <ferry.huberts@pelagic.nl> | 2011-07-19 17:51:58 (JST) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2011-07-19 18:30:07 (JST) |
commit | d01c600c179593a53162a9d4e3040ecfc5078fdc (patch) | |
tree | 487f8afaefe7b5f09f05d0d3e3796aaff86b931a | |
parent | 96f05018c9dbdf8131f18c87ee3bbbac40e0f729 (diff) | |
download | cgit-d01c600c179593a53162a9d4e3040ecfc5078fdc.zip cgit-d01c600c179593a53162a9d4e3040ecfc5078fdc.tar.gz |
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.c | 2 | ||||
-rw-r--r-- | cgit.h | 1 | ||||
-rw-r--r-- | cgitrc.5.txt | 11 | ||||
-rw-r--r-- | ui-plain.c | 52 |
4 files changed, 65 insertions, 1 deletions
@@ -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")) |
@@ -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 | ||
229 | mimetype-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 | |||
229 | module-link:: | 240 | module-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 |
@@ -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 @@ | |||
13 | int match_baselen; | 14 | int match_baselen; |
14 | int match; | 15 | int match; |
15 | 16 | ||
17 | static 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 | |||
16 | static void print_object(const unsigned char *sha1, const char *path) | 57 | static 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 | ||
55 | static char *buildpath(const char *base, int baselen, const char *path) | 105 | static char *buildpath(const char *base, int baselen, const char *path) |