diff options
author | Omar Polo <op@omarpolo.com> | 2020-10-07 14:38:27 +0200 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2020-10-07 14:41:32 +0200 |
commit | cc68fe70fcb31b9acebab97ecad2c84c4c80fc02 (patch) | |
tree | 388c1299b55599df87e700270049037611fbdbfc /gmid.c | |
parent | 592fd6245350595319e338ef49984a443b818f16 (diff) |
added support for mime types (by looking at file extension)1.0
At the moment there is an hardcoded table that maps mime types to
extensions. For the time being this can be OK, as I don’t even
currently serve all those types of file, but in the future I’d like to
let user pass a file with the mapping, like /usr/share/misc/mime.types
on OpenBSD, to map. However, even in this case, we should hardcode
text/gemini IMHO, since most mime.types listing doesn’t have it yet.
Diffstat (limited to 'gmid.c')
-rw-r--r-- | gmid.c | 58 |
1 files changed, 56 insertions, 2 deletions
@@ -69,6 +69,27 @@ struct client { int fd; }; +struct etm { /* file extension to mime */ + const char *mime; + const char *ext; +} filetypes[] = { + {"application/pdf", "pdf"}, + + {"image/gif", "gif"}, + {"image/jpeg", "jpg"}, + {"image/jpeg", "jpeg"}, + {"image/png", "png"}, + {"image/svg+xml", "svg"}, + + {"text/gemini", "gemini"}, + {"text/gemini", "gmi"}, + {"text/markdown", "markdown"}, + {"text/markdown", "md"}, + {"text/plain", "txt"}, + + {NULL, NULL} +}; + int dirfd; char *url_after_proto(char*); @@ -79,6 +100,8 @@ int path_isdir(char*); int start_reply(struct pollfd*, struct client*, int, const char*); int isdir(int); +const char *path_ext(const char*); +const char *mime(const char*); void send_file(char*, struct pollfd*, struct client*); void send_dir(char*, struct pollfd*, struct client*); void handle(struct pollfd*, struct client*); @@ -221,6 +244,38 @@ isdir(int fd) return S_ISDIR(sb.st_mode); } +const char * +path_ext(const char *path) +{ + const char *end; + + end = path + strlen(path)-1; /* the last byte before the NUL */ + for (; end != path; --end) { + if (*end == '.') + return end+1; + if (*end == '/') + break; + } + + return NULL; +} + +const char * +mime(const char *path) +{ + const char *ext, *def = "application/octet-stream"; + struct etm *t; + + if ((ext = path_ext(path)) == NULL) + return def; + + for (t = filetypes; t->mime != NULL; ++t) + if (!strcmp(ext, t->ext)) + return t->mime; + + return def; +} + void send_file(char *path, struct pollfd *fds, struct client *client) { @@ -254,8 +309,7 @@ send_file(char *path, struct pollfd *fds, struct client *client) return; } - /* assume it's a text/gemini file */ - if (!start_reply(fds, client, SUCCESS, "text/gemini")) + if (!start_reply(fds, client, SUCCESS, mime(fpath))) return; } |