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>
This commit is contained in:
vanhempi
286a905842
commit
c4d46c7035
11
cgit.c
11
cgit.c
@ -17,6 +17,14 @@
|
|||||||
|
|
||||||
const char *cgit_version = CGIT_VERSION;
|
const char *cgit_version = CGIT_VERSION;
|
||||||
|
|
||||||
|
void add_mimetype(const char *name, const char *value)
|
||||||
|
{
|
||||||
|
struct string_list_item *item;
|
||||||
|
|
||||||
|
item = string_list_insert(xstrdup(name), &ctx.cfg.mimetypes);
|
||||||
|
item->util = xstrdup(value);
|
||||||
|
}
|
||||||
|
|
||||||
void config_cb(const char *name, const char *value)
|
void config_cb(const char *name, const char *value)
|
||||||
{
|
{
|
||||||
if (!strcmp(name, "root-title"))
|
if (!strcmp(name, "root-title"))
|
||||||
@ -101,6 +109,8 @@ void config_cb(const char *name, const char *value)
|
|||||||
ctx.cfg.clone_prefix = xstrdup(value);
|
ctx.cfg.clone_prefix = xstrdup(value);
|
||||||
else if (!strcmp(name, "local-time"))
|
else if (!strcmp(name, "local-time"))
|
||||||
ctx.cfg.local_time = atoi(value);
|
ctx.cfg.local_time = atoi(value);
|
||||||
|
else if (!prefixcmp(name, "mimetype."))
|
||||||
|
add_mimetype(name + 9, value);
|
||||||
else if (!strcmp(name, "repo.group"))
|
else if (!strcmp(name, "repo.group"))
|
||||||
ctx.cfg.repo_group = xstrdup(value);
|
ctx.cfg.repo_group = xstrdup(value);
|
||||||
else if (!strcmp(name, "repo.url"))
|
else if (!strcmp(name, "repo.url"))
|
||||||
@ -213,6 +223,7 @@ static void prepare_context(struct cgit_context *ctx)
|
|||||||
ctx->page.modified = time(NULL);
|
ctx->page.modified = time(NULL);
|
||||||
ctx->page.expires = ctx->page.modified;
|
ctx->page.expires = ctx->page.modified;
|
||||||
ctx->page.etag = NULL;
|
ctx->page.etag = NULL;
|
||||||
|
memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct refmatch {
|
struct refmatch {
|
||||||
|
2
cgit.h
2
cgit.h
@ -15,6 +15,7 @@
|
|||||||
#include <revision.h>
|
#include <revision.h>
|
||||||
#include <log-tree.h>
|
#include <log-tree.h>
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
|
#include <string-list.h>
|
||||||
#include <xdiff-interface.h>
|
#include <xdiff-interface.h>
|
||||||
#include <xdiff/xdiff.h>
|
#include <xdiff/xdiff.h>
|
||||||
#include <utf8.h>
|
#include <utf8.h>
|
||||||
@ -174,6 +175,7 @@ struct cgit_config {
|
|||||||
int summary_branches;
|
int summary_branches;
|
||||||
int summary_log;
|
int summary_log;
|
||||||
int summary_tags;
|
int summary_tags;
|
||||||
|
struct string_list mimetypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cgit_page {
|
struct cgit_page {
|
||||||
|
17
cgitrc.5.txt
17
cgitrc.5.txt
@ -147,6 +147,10 @@ max-stats::
|
|||||||
"month", "quarter" and "year". If unspecified, statistics are
|
"month", "quarter" and "year". If unspecified, statistics are
|
||||||
disabled. Default value: none. See also: "repo.max-stats".
|
disabled. Default value: none. See also: "repo.max-stats".
|
||||||
|
|
||||||
|
mimetype.<ext>::
|
||||||
|
Set the mimetype for the specified filename extension. This is used
|
||||||
|
by the `plain` command when returning blob content.
|
||||||
|
|
||||||
module-link::
|
module-link::
|
||||||
Text which will be used as the formatstring for a hyperlink when a
|
Text which will be used as the formatstring for a hyperlink when a
|
||||||
submodule is printed in a directory listing. The arguments for the
|
submodule is printed in a directory listing. The arguments for the
|
||||||
@ -324,6 +328,19 @@ root-readme=/var/www/htdocs/about.html
|
|||||||
snapshots=tar.gz tar.bz2 zip
|
snapshots=tar.gz tar.bz2 zip
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## List of common mimetypes
|
||||||
|
##
|
||||||
|
|
||||||
|
mimetype.git=image/git
|
||||||
|
mimetype.html=text/html
|
||||||
|
mimetype.jpg=image/jpeg
|
||||||
|
mimetype.jpeg=image/jpeg
|
||||||
|
mimetype.pdf=application/pdf
|
||||||
|
mimetype.png=image/png
|
||||||
|
mimetype.svg=image/svg+xml
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## List of repositories.
|
## List of repositories.
|
||||||
## PS: Any repositories listed when repo.group is unset will not be
|
## PS: Any repositories listed when repo.group is unset will not be
|
||||||
|
12
ui-plain.c
12
ui-plain.c
@ -17,8 +17,9 @@ int match;
|
|||||||
static void print_object(const unsigned char *sha1, const char *path)
|
static void print_object(const unsigned char *sha1, const char *path)
|
||||||
{
|
{
|
||||||
enum object_type type;
|
enum object_type type;
|
||||||
char *buf;
|
char *buf, *ext;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
struct string_list_item *mime;
|
||||||
|
|
||||||
type = sha1_object_info(sha1, &size);
|
type = sha1_object_info(sha1, &size);
|
||||||
if (type == OBJ_BAD) {
|
if (type == OBJ_BAD) {
|
||||||
@ -31,10 +32,19 @@ static void print_object(const unsigned char *sha1, const char *path)
|
|||||||
html_status(404, "Not found", 0);
|
html_status(404, "Not found", 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ctx.page.mimetype = NULL;
|
||||||
|
ext = strrchr(path, '.');
|
||||||
|
if (ext && *(++ext)) {
|
||||||
|
mime = string_list_lookup(ext, &ctx.cfg.mimetypes);
|
||||||
|
if (mime)
|
||||||
|
ctx.page.mimetype = (char *)mime->util;
|
||||||
|
}
|
||||||
|
if (!ctx.page.mimetype) {
|
||||||
if (buffer_is_binary(buf, size))
|
if (buffer_is_binary(buf, size))
|
||||||
ctx.page.mimetype = "application/octet-stream";
|
ctx.page.mimetype = "application/octet-stream";
|
||||||
else
|
else
|
||||||
ctx.page.mimetype = "text/plain";
|
ctx.page.mimetype = "text/plain";
|
||||||
|
}
|
||||||
ctx.page.filename = fmt("%s", path);
|
ctx.page.filename = fmt("%s", path);
|
||||||
ctx.page.size = size;
|
ctx.page.size = size;
|
||||||
ctx.page.etag = sha1_to_hex(sha1);
|
ctx.page.etag = sha1_to_hex(sha1);
|
||||||
|
Ladataan…
Viittaa uudesa ongelmassa
Block a user