diff options
| author | 2011-07-19 17:51:58 (JST) | |
|---|---|---|
| committer | 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) |
