author | Lars Hjemli <hjemli@gmail.com> | 2009-02-13 19:43:30 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2009-07-25 10:55:15 (UTC) |
commit | c4d46c7035d07070ac1ebf0c0b44df927358687f (patch) (unidiff) | |
tree | 562cf4f01afe78b92b13ad5be5dc01e07db04a66 | |
parent | 286a905842dc0bec6d21a614ec4a97c5f19d5bc4 (diff) | |
download | cgit-c4d46c7035d07070ac1ebf0c0b44df927358687f.zip cgit-c4d46c7035d07070ac1ebf0c0b44df927358687f.tar.gz cgit-c4d46c7035d07070ac1ebf0c0b44df927358687f.tar.bz2 |
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.c | 11 | ||||
-rw-r--r-- | cgit.h | 2 | ||||
-rw-r--r-- | cgitrc.5.txt | 17 | ||||
-rw-r--r-- | ui-plain.c | 20 |
4 files changed, 45 insertions, 5 deletions
@@ -1,43 +1,51 @@ | |||
1 | /* cgit.c: cgi for the git scm | 1 | /* cgit.c: cgi for the git scm |
2 | * | 2 | * |
3 | * Copyright (C) 2006 Lars Hjemli | 3 | * Copyright (C) 2006 Lars Hjemli |
4 | * | 4 | * |
5 | * Licensed under GNU General Public License v2 | 5 | * Licensed under GNU General Public License v2 |
6 | * (see COPYING for full license text) | 6 | * (see COPYING for full license text) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include "cgit.h" | 9 | #include "cgit.h" |
10 | #include "cache.h" | 10 | #include "cache.h" |
11 | #include "cmd.h" | 11 | #include "cmd.h" |
12 | #include "configfile.h" | 12 | #include "configfile.h" |
13 | #include "html.h" | 13 | #include "html.h" |
14 | #include "ui-shared.h" | 14 | #include "ui-shared.h" |
15 | #include "ui-stats.h" | 15 | #include "ui-stats.h" |
16 | #include "scan-tree.h" | 16 | #include "scan-tree.h" |
17 | 17 | ||
18 | const char *cgit_version = CGIT_VERSION; | 18 | const char *cgit_version = CGIT_VERSION; |
19 | 19 | ||
20 | void 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 | |||
20 | void config_cb(const char *name, const char *value) | 28 | void config_cb(const char *name, const char *value) |
21 | { | 29 | { |
22 | if (!strcmp(name, "root-title")) | 30 | if (!strcmp(name, "root-title")) |
23 | ctx.cfg.root_title = xstrdup(value); | 31 | ctx.cfg.root_title = xstrdup(value); |
24 | else if (!strcmp(name, "root-desc")) | 32 | else if (!strcmp(name, "root-desc")) |
25 | ctx.cfg.root_desc = xstrdup(value); | 33 | ctx.cfg.root_desc = xstrdup(value); |
26 | else if (!strcmp(name, "root-readme")) | 34 | else if (!strcmp(name, "root-readme")) |
27 | ctx.cfg.root_readme = xstrdup(value); | 35 | ctx.cfg.root_readme = xstrdup(value); |
28 | else if (!strcmp(name, "css")) | 36 | else if (!strcmp(name, "css")) |
29 | ctx.cfg.css = xstrdup(value); | 37 | ctx.cfg.css = xstrdup(value); |
30 | else if (!strcmp(name, "favicon")) | 38 | else if (!strcmp(name, "favicon")) |
31 | ctx.cfg.favicon = xstrdup(value); | 39 | ctx.cfg.favicon = xstrdup(value); |
32 | else if (!strcmp(name, "footer")) | 40 | else if (!strcmp(name, "footer")) |
33 | ctx.cfg.footer = xstrdup(value); | 41 | ctx.cfg.footer = xstrdup(value); |
34 | else if (!strcmp(name, "head-include")) | 42 | else if (!strcmp(name, "head-include")) |
35 | ctx.cfg.head_include = xstrdup(value); | 43 | ctx.cfg.head_include = xstrdup(value); |
36 | else if (!strcmp(name, "header")) | 44 | else if (!strcmp(name, "header")) |
37 | ctx.cfg.header = xstrdup(value); | 45 | ctx.cfg.header = xstrdup(value); |
38 | else if (!strcmp(name, "logo")) | 46 | else if (!strcmp(name, "logo")) |
39 | ctx.cfg.logo = xstrdup(value); | 47 | ctx.cfg.logo = xstrdup(value); |
40 | else if (!strcmp(name, "index-header")) | 48 | else if (!strcmp(name, "index-header")) |
41 | ctx.cfg.index_header = xstrdup(value); | 49 | ctx.cfg.index_header = xstrdup(value); |
42 | else if (!strcmp(name, "index-info")) | 50 | else if (!strcmp(name, "index-info")) |
43 | ctx.cfg.index_info = xstrdup(value); | 51 | ctx.cfg.index_info = xstrdup(value); |
@@ -80,48 +88,50 @@ void config_cb(const char *name, const char *value) | |||
80 | else if (!strcmp(name, "max-message-length")) | 88 | else if (!strcmp(name, "max-message-length")) |
81 | ctx.cfg.max_msg_len = atoi(value); | 89 | ctx.cfg.max_msg_len = atoi(value); |
82 | else if (!strcmp(name, "max-repodesc-length")) | 90 | else if (!strcmp(name, "max-repodesc-length")) |
83 | ctx.cfg.max_repodesc_len = atoi(value); | 91 | ctx.cfg.max_repodesc_len = atoi(value); |
84 | else if (!strcmp(name, "max-repo-count")) | 92 | else if (!strcmp(name, "max-repo-count")) |
85 | ctx.cfg.max_repo_count = atoi(value); | 93 | ctx.cfg.max_repo_count = atoi(value); |
86 | else if (!strcmp(name, "max-commit-count")) | 94 | else if (!strcmp(name, "max-commit-count")) |
87 | ctx.cfg.max_commit_count = atoi(value); | 95 | ctx.cfg.max_commit_count = atoi(value); |
88 | else if (!strcmp(name, "summary-log")) | 96 | else if (!strcmp(name, "summary-log")) |
89 | ctx.cfg.summary_log = atoi(value); | 97 | ctx.cfg.summary_log = atoi(value); |
90 | else if (!strcmp(name, "summary-branches")) | 98 | else if (!strcmp(name, "summary-branches")) |
91 | ctx.cfg.summary_branches = atoi(value); | 99 | ctx.cfg.summary_branches = atoi(value); |
92 | else if (!strcmp(name, "summary-tags")) | 100 | else if (!strcmp(name, "summary-tags")) |
93 | ctx.cfg.summary_tags = atoi(value); | 101 | ctx.cfg.summary_tags = atoi(value); |
94 | else if (!strcmp(name, "agefile")) | 102 | else if (!strcmp(name, "agefile")) |
95 | ctx.cfg.agefile = xstrdup(value); | 103 | ctx.cfg.agefile = xstrdup(value); |
96 | else if (!strcmp(name, "renamelimit")) | 104 | else if (!strcmp(name, "renamelimit")) |
97 | ctx.cfg.renamelimit = atoi(value); | 105 | ctx.cfg.renamelimit = atoi(value); |
98 | else if (!strcmp(name, "robots")) | 106 | else if (!strcmp(name, "robots")) |
99 | ctx.cfg.robots = xstrdup(value); | 107 | ctx.cfg.robots = xstrdup(value); |
100 | else if (!strcmp(name, "clone-prefix")) | 108 | else if (!strcmp(name, "clone-prefix")) |
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")) |
107 | ctx.repo = cgit_add_repo(value); | 117 | ctx.repo = cgit_add_repo(value); |
108 | else if (!strcmp(name, "repo.name")) | 118 | else if (!strcmp(name, "repo.name")) |
109 | ctx.repo->name = xstrdup(value); | 119 | ctx.repo->name = xstrdup(value); |
110 | else if (ctx.repo && !strcmp(name, "repo.path")) | 120 | else if (ctx.repo && !strcmp(name, "repo.path")) |
111 | ctx.repo->path = trim_end(value, '/'); | 121 | ctx.repo->path = trim_end(value, '/'); |
112 | else if (ctx.repo && !strcmp(name, "repo.clone-url")) | 122 | else if (ctx.repo && !strcmp(name, "repo.clone-url")) |
113 | ctx.repo->clone_url = xstrdup(value); | 123 | ctx.repo->clone_url = xstrdup(value); |
114 | else if (ctx.repo && !strcmp(name, "repo.desc")) | 124 | else if (ctx.repo && !strcmp(name, "repo.desc")) |
115 | ctx.repo->desc = xstrdup(value); | 125 | ctx.repo->desc = xstrdup(value); |
116 | else if (ctx.repo && !strcmp(name, "repo.owner")) | 126 | else if (ctx.repo && !strcmp(name, "repo.owner")) |
117 | ctx.repo->owner = xstrdup(value); | 127 | ctx.repo->owner = xstrdup(value); |
118 | else if (ctx.repo && !strcmp(name, "repo.defbranch")) | 128 | else if (ctx.repo && !strcmp(name, "repo.defbranch")) |
119 | ctx.repo->defbranch = xstrdup(value); | 129 | ctx.repo->defbranch = xstrdup(value); |
120 | else if (ctx.repo && !strcmp(name, "repo.snapshots")) | 130 | else if (ctx.repo && !strcmp(name, "repo.snapshots")) |
121 | ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ | 131 | ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ |
122 | else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount")) | 132 | else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount")) |
123 | ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); | 133 | ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); |
124 | else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) | 134 | else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) |
125 | ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); | 135 | ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); |
126 | else if (ctx.repo && !strcmp(name, "repo.max-stats")) | 136 | else if (ctx.repo && !strcmp(name, "repo.max-stats")) |
127 | ctx.repo->max_stats = cgit_find_stats_period(value, NULL); | 137 | ctx.repo->max_stats = cgit_find_stats_period(value, NULL); |
@@ -192,48 +202,49 @@ static void prepare_context(struct cgit_context *ctx) | |||
192 | ctx->cfg.logo = "/git-logo.png"; | 202 | ctx->cfg.logo = "/git-logo.png"; |
193 | ctx->cfg.local_time = 0; | 203 | ctx->cfg.local_time = 0; |
194 | ctx->cfg.max_repo_count = 50; | 204 | ctx->cfg.max_repo_count = 50; |
195 | ctx->cfg.max_commit_count = 50; | 205 | ctx->cfg.max_commit_count = 50; |
196 | ctx->cfg.max_lock_attempts = 5; | 206 | ctx->cfg.max_lock_attempts = 5; |
197 | ctx->cfg.max_msg_len = 80; | 207 | ctx->cfg.max_msg_len = 80; |
198 | ctx->cfg.max_repodesc_len = 80; | 208 | ctx->cfg.max_repodesc_len = 80; |
199 | ctx->cfg.max_stats = 0; | 209 | ctx->cfg.max_stats = 0; |
200 | ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; | 210 | ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; |
201 | ctx->cfg.renamelimit = -1; | 211 | ctx->cfg.renamelimit = -1; |
202 | ctx->cfg.robots = "index, nofollow"; | 212 | ctx->cfg.robots = "index, nofollow"; |
203 | ctx->cfg.root_title = "Git repository browser"; | 213 | ctx->cfg.root_title = "Git repository browser"; |
204 | ctx->cfg.root_desc = "a fast webinterface for the git dscm"; | 214 | ctx->cfg.root_desc = "a fast webinterface for the git dscm"; |
205 | ctx->cfg.script_name = CGIT_SCRIPT_NAME; | 215 | ctx->cfg.script_name = CGIT_SCRIPT_NAME; |
206 | ctx->cfg.summary_branches = 10; | 216 | ctx->cfg.summary_branches = 10; |
207 | ctx->cfg.summary_log = 10; | 217 | ctx->cfg.summary_log = 10; |
208 | ctx->cfg.summary_tags = 10; | 218 | ctx->cfg.summary_tags = 10; |
209 | ctx->page.mimetype = "text/html"; | 219 | ctx->page.mimetype = "text/html"; |
210 | ctx->page.charset = PAGE_ENCODING; | 220 | ctx->page.charset = PAGE_ENCODING; |
211 | ctx->page.filename = NULL; | 221 | ctx->page.filename = NULL; |
212 | ctx->page.size = 0; | 222 | ctx->page.size = 0; |
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 | ||
218 | struct refmatch { | 229 | struct refmatch { |
219 | char *req_ref; | 230 | char *req_ref; |
220 | char *first_ref; | 231 | char *first_ref; |
221 | int match; | 232 | int match; |
222 | }; | 233 | }; |
223 | 234 | ||
224 | int find_current_ref(const char *refname, const unsigned char *sha1, | 235 | int find_current_ref(const char *refname, const unsigned char *sha1, |
225 | int flags, void *cb_data) | 236 | int flags, void *cb_data) |
226 | { | 237 | { |
227 | struct refmatch *info; | 238 | struct refmatch *info; |
228 | 239 | ||
229 | info = (struct refmatch *)cb_data; | 240 | info = (struct refmatch *)cb_data; |
230 | if (!strcmp(refname, info->req_ref)) | 241 | if (!strcmp(refname, info->req_ref)) |
231 | info->match = 1; | 242 | info->match = 1; |
232 | if (!info->first_ref) | 243 | if (!info->first_ref) |
233 | info->first_ref = xstrdup(refname); | 244 | info->first_ref = xstrdup(refname); |
234 | return info->match; | 245 | return info->match; |
235 | } | 246 | } |
236 | 247 | ||
237 | char *find_default_branch(struct cgit_repo *repo) | 248 | char *find_default_branch(struct cgit_repo *repo) |
238 | { | 249 | { |
239 | struct refmatch info; | 250 | struct refmatch info; |
@@ -1,41 +1,42 @@ | |||
1 | #ifndef CGIT_H | 1 | #ifndef CGIT_H |
2 | #define CGIT_H | 2 | #define CGIT_H |
3 | 3 | ||
4 | 4 | ||
5 | #include <git-compat-util.h> | 5 | #include <git-compat-util.h> |
6 | #include <cache.h> | 6 | #include <cache.h> |
7 | #include <grep.h> | 7 | #include <grep.h> |
8 | #include <object.h> | 8 | #include <object.h> |
9 | #include <tree.h> | 9 | #include <tree.h> |
10 | #include <commit.h> | 10 | #include <commit.h> |
11 | #include <tag.h> | 11 | #include <tag.h> |
12 | #include <diff.h> | 12 | #include <diff.h> |
13 | #include <diffcore.h> | 13 | #include <diffcore.h> |
14 | #include <refs.h> | 14 | #include <refs.h> |
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> |
21 | 22 | ||
22 | 23 | ||
23 | /* | 24 | /* |
24 | * Dateformats used on misc. pages | 25 | * Dateformats used on misc. pages |
25 | */ | 26 | */ |
26 | #define FMT_LONGDATE "%Y-%m-%d %H:%M:%S (%Z)" | 27 | #define FMT_LONGDATE "%Y-%m-%d %H:%M:%S (%Z)" |
27 | #define FMT_SHORTDATE "%Y-%m-%d" | 28 | #define FMT_SHORTDATE "%Y-%m-%d" |
28 | #define FMT_ATOMDATE "%Y-%m-%dT%H:%M:%SZ" | 29 | #define FMT_ATOMDATE "%Y-%m-%dT%H:%M:%SZ" |
29 | 30 | ||
30 | 31 | ||
31 | /* | 32 | /* |
32 | * Limits used for relative dates | 33 | * Limits used for relative dates |
33 | */ | 34 | */ |
34 | #define TM_MIN 60 | 35 | #define TM_MIN 60 |
35 | #define TM_HOUR (TM_MIN * 60) | 36 | #define TM_HOUR (TM_MIN * 60) |
36 | #define TM_DAY (TM_HOUR * 24) | 37 | #define TM_DAY (TM_HOUR * 24) |
37 | #define TM_WEEK (TM_DAY * 7) | 38 | #define TM_WEEK (TM_DAY * 7) |
38 | #define TM_YEAR (TM_DAY * 365) | 39 | #define TM_YEAR (TM_DAY * 365) |
39 | #define TM_MONTH (TM_YEAR / 12.0) | 40 | #define TM_MONTH (TM_YEAR / 12.0) |
40 | 41 | ||
41 | 42 | ||
@@ -153,48 +154,49 @@ struct cgit_config { | |||
153 | int cache_size; | 154 | int cache_size; |
154 | int cache_dynamic_ttl; | 155 | int cache_dynamic_ttl; |
155 | int cache_max_create_time; | 156 | int cache_max_create_time; |
156 | int cache_repo_ttl; | 157 | int cache_repo_ttl; |
157 | int cache_root_ttl; | 158 | int cache_root_ttl; |
158 | int cache_static_ttl; | 159 | int cache_static_ttl; |
159 | int embedded; | 160 | int embedded; |
160 | int enable_index_links; | 161 | int enable_index_links; |
161 | int enable_log_filecount; | 162 | int enable_log_filecount; |
162 | int enable_log_linecount; | 163 | int enable_log_linecount; |
163 | int local_time; | 164 | int local_time; |
164 | int max_repo_count; | 165 | int max_repo_count; |
165 | int max_commit_count; | 166 | int max_commit_count; |
166 | int max_lock_attempts; | 167 | int max_lock_attempts; |
167 | int max_msg_len; | 168 | int max_msg_len; |
168 | int max_repodesc_len; | 169 | int max_repodesc_len; |
169 | int max_stats; | 170 | int max_stats; |
170 | int nocache; | 171 | int nocache; |
171 | int noheader; | 172 | int noheader; |
172 | int renamelimit; | 173 | int renamelimit; |
173 | int snapshots; | 174 | int snapshots; |
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 | ||
179 | struct cgit_page { | 181 | struct cgit_page { |
180 | time_t modified; | 182 | time_t modified; |
181 | time_t expires; | 183 | time_t expires; |
182 | size_t size; | 184 | size_t size; |
183 | char *mimetype; | 185 | char *mimetype; |
184 | char *charset; | 186 | char *charset; |
185 | char *filename; | 187 | char *filename; |
186 | char *etag; | 188 | char *etag; |
187 | char *title; | 189 | char *title; |
188 | int status; | 190 | int status; |
189 | char *statusmsg; | 191 | char *statusmsg; |
190 | }; | 192 | }; |
191 | 193 | ||
192 | struct cgit_context { | 194 | struct cgit_context { |
193 | struct cgit_query qry; | 195 | struct cgit_query qry; |
194 | struct cgit_config cfg; | 196 | struct cgit_config cfg; |
195 | struct cgit_repo *repo; | 197 | struct cgit_repo *repo; |
196 | struct cgit_page page; | 198 | struct cgit_page page; |
197 | }; | 199 | }; |
198 | 200 | ||
199 | struct cgit_snapshot_format { | 201 | struct cgit_snapshot_format { |
200 | const char *suffix; | 202 | const char *suffix; |
diff --git a/cgitrc.5.txt b/cgitrc.5.txt index a207fe0..7256ec0 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt | |||
@@ -126,48 +126,52 @@ logo-link:: | |||
126 | calculated url of the repository index page will be used. Default | 126 | calculated url of the repository index page will be used. Default |
127 | value: none. | 127 | value: none. |
128 | 128 | ||
129 | max-commit-count:: | 129 | max-commit-count:: |
130 | Specifies the number of entries to list per page in "log" view. Default | 130 | Specifies the number of entries to list per page in "log" view. Default |
131 | value: "50". | 131 | value: "50". |
132 | 132 | ||
133 | max-message-length:: | 133 | max-message-length:: |
134 | Specifies the maximum number of commit message characters to display in | 134 | Specifies the maximum number of commit message characters to display in |
135 | "log" view. Default value: "80". | 135 | "log" view. Default value: "80". |
136 | 136 | ||
137 | max-repo-count:: | 137 | max-repo-count:: |
138 | Specifies the number of entries to list per page on therepository | 138 | Specifies the number of entries to list per page on therepository |
139 | index page. Default value: "50". | 139 | index page. Default value: "50". |
140 | 140 | ||
141 | max-repodesc-length:: | 141 | max-repodesc-length:: |
142 | Specifies the maximum number of repo description characters to display | 142 | Specifies the maximum number of repo description characters to display |
143 | on the repository index page. Default value: "80". | 143 | on the repository index page. Default value: "80". |
144 | 144 | ||
145 | max-stats:: | 145 | max-stats:: |
146 | Set the default maximum statistics period. Valid values are "week", | 146 | Set the default maximum statistics period. Valid values are "week", |
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 | ||
150 | mimetype.<ext>:: | ||
151 | Set the mimetype for the specified filename extension. This is used | ||
152 | by the `plain` command when returning blob content. | ||
153 | |||
150 | module-link:: | 154 | module-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 |
153 | formatstring are the path and SHA1 of the submodule commit. Default | 157 | formatstring are the path and SHA1 of the submodule commit. Default |
154 | value: "./?repo=%s&page=commit&id=%s" | 158 | value: "./?repo=%s&page=commit&id=%s" |
155 | 159 | ||
156 | nocache:: | 160 | nocache:: |
157 | If set to the value "1" caching will be disabled. This settings is | 161 | If set to the value "1" caching will be disabled. This settings is |
158 | deprecated, and will not be honored starting with cgit-1.0. Default | 162 | deprecated, and will not be honored starting with cgit-1.0. Default |
159 | value: "0". | 163 | value: "0". |
160 | 164 | ||
161 | noheader:: | 165 | noheader:: |
162 | Flag which, when set to "1", will make cgit omit the standard header | 166 | Flag which, when set to "1", will make cgit omit the standard header |
163 | on all pages. Default value: none. See also: "embedded". | 167 | on all pages. Default value: none. See also: "embedded". |
164 | 168 | ||
165 | renamelimit:: | 169 | renamelimit:: |
166 | Maximum number of files to consider when detecting renames. The value | 170 | Maximum number of files to consider when detecting renames. The value |
167 | "-1" uses the compiletime value in git (for further info, look at | 171 | "-1" uses the compiletime value in git (for further info, look at |
168 | `man git-diff`). Default value: "-1". | 172 | `man git-diff`). Default value: "-1". |
169 | 173 | ||
170 | repo.group:: | 174 | repo.group:: |
171 | A value for the current repository group, which all repositories | 175 | A value for the current repository group, which all repositories |
172 | specified after this setting will inherit. Default value: none. | 176 | specified after this setting will inherit. Default value: none. |
173 | 177 | ||
@@ -304,48 +308,61 @@ favicon=/favicon.ico | |||
304 | logo=/img/mylogo.png | 308 | logo=/img/mylogo.png |
305 | 309 | ||
306 | 310 | ||
307 | # Enable statistics per week, month and quarter | 311 | # Enable statistics per week, month and quarter |
308 | max-stats=quarter | 312 | max-stats=quarter |
309 | 313 | ||
310 | 314 | ||
311 | # Set the title and heading of the repository index page | 315 | # Set the title and heading of the repository index page |
312 | root-title=foobar.com git repositories | 316 | root-title=foobar.com git repositories |
313 | 317 | ||
314 | 318 | ||
315 | # Set a subheading for the repository index page | 319 | # Set a subheading for the repository index page |
316 | root-desc=tracking the foobar development | 320 | root-desc=tracking the foobar development |
317 | 321 | ||
318 | 322 | ||
319 | # Include some more info about foobar.com on the index page | 323 | # Include some more info about foobar.com on the index page |
320 | root-readme=/var/www/htdocs/about.html | 324 | root-readme=/var/www/htdocs/about.html |
321 | 325 | ||
322 | 326 | ||
323 | # Allow download of tar.gz, tar.bz2 and zip-files | 327 | # Allow download of tar.gz, tar.bz2 and zip-files |
324 | snapshots=tar.gz tar.bz2 zip | 328 | snapshots=tar.gz tar.bz2 zip |
325 | 329 | ||
326 | 330 | ||
327 | ## | 331 | ## |
332 | ## List of common mimetypes | ||
333 | ## | ||
334 | |||
335 | mimetype.git=image/git | ||
336 | mimetype.html=text/html | ||
337 | mimetype.jpg=image/jpeg | ||
338 | mimetype.jpeg=image/jpeg | ||
339 | mimetype.pdf=application/pdf | ||
340 | mimetype.png=image/png | ||
341 | mimetype.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 |
331 | ## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos') | 348 | ## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos') |
332 | ## and included like this: | 349 | ## and included like this: |
333 | ## include=/etc/cgitrepos | 350 | ## include=/etc/cgitrepos |
334 | ## | 351 | ## |
335 | 352 | ||
336 | 353 | ||
337 | repo.url=foo | 354 | repo.url=foo |
338 | repo.path=/pub/git/foo.git | 355 | repo.path=/pub/git/foo.git |
339 | repo.desc=the master foo repository | 356 | repo.desc=the master foo repository |
340 | repo.owner=fooman@foobar.com | 357 | repo.owner=fooman@foobar.com |
341 | repo.readme=info/web/about.html | 358 | repo.readme=info/web/about.html |
342 | 359 | ||
343 | 360 | ||
344 | repo.url=bar | 361 | repo.url=bar |
345 | repo.path=/pub/git/bar.git | 362 | repo.path=/pub/git/bar.git |
346 | repo.desc=the bars for your foo | 363 | repo.desc=the bars for your foo |
347 | repo.owner=barman@foobar.com | 364 | repo.owner=barman@foobar.com |
348 | repo.readme=info/web/about.html | 365 | repo.readme=info/web/about.html |
349 | 366 | ||
350 | 367 | ||
351 | # The next repositories will be displayed under the 'extras' heading | 368 | # The next repositories will be displayed under the 'extras' heading |
@@ -1,61 +1,71 @@ | |||
1 | /* ui-plain.c: functions for output of plain blobs by path | 1 | /* ui-plain.c: functions for output of plain blobs by path |
2 | * | 2 | * |
3 | * Copyright (C) 2008 Lars Hjemli | 3 | * Copyright (C) 2008 Lars Hjemli |
4 | * | 4 | * |
5 | * Licensed under GNU General Public License v2 | 5 | * Licensed under GNU General Public License v2 |
6 | * (see COPYING for full license text) | 6 | * (see COPYING for full license text) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include "cgit.h" | 9 | #include "cgit.h" |
10 | #include "html.h" | 10 | #include "html.h" |
11 | #include "ui-shared.h" | 11 | #include "ui-shared.h" |
12 | 12 | ||
13 | char *curr_rev; | 13 | char *curr_rev; |
14 | char *match_path; | 14 | char *match_path; |
15 | int match; | 15 | int match; |
16 | 16 | ||
17 | static void print_object(const unsigned char *sha1, const char *path) | 17 | static 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) { |
25 | html_status(404, "Not found", 0); | 26 | html_status(404, "Not found", 0); |
26 | return; | 27 | return; |
27 | } | 28 | } |
28 | 29 | ||
29 | buf = read_sha1_file(sha1, &type, &size); | 30 | buf = read_sha1_file(sha1, &type, &size); |
30 | if (!buf) { | 31 | if (!buf) { |
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); |
41 | cgit_print_http_headers(&ctx); | 51 | cgit_print_http_headers(&ctx); |
42 | html_raw(buf, size); | 52 | html_raw(buf, size); |
43 | match = 1; | 53 | match = 1; |
44 | } | 54 | } |
45 | 55 | ||
46 | static int walk_tree(const unsigned char *sha1, const char *base, int baselen, | 56 | static int walk_tree(const unsigned char *sha1, const char *base, int baselen, |
47 | const char *pathname, unsigned mode, int stage, | 57 | const char *pathname, unsigned mode, int stage, |
48 | void *cbdata) | 58 | void *cbdata) |
49 | { | 59 | { |
50 | if (S_ISDIR(mode)) | 60 | if (S_ISDIR(mode)) |
51 | return READ_TREE_RECURSIVE; | 61 | return READ_TREE_RECURSIVE; |
52 | 62 | ||
53 | if (S_ISREG(mode)) | 63 | if (S_ISREG(mode)) |
54 | print_object(sha1, pathname); | 64 | print_object(sha1, pathname); |
55 | 65 | ||
56 | return 0; | 66 | return 0; |
57 | } | 67 | } |
58 | 68 | ||
59 | void cgit_print_plain(struct cgit_context *ctx) | 69 | void cgit_print_plain(struct cgit_context *ctx) |
60 | { | 70 | { |
61 | const char *rev = ctx->qry.sha1; | 71 | const char *rev = ctx->qry.sha1; |