From cc68fe70fcb31b9acebab97ecad2c84c4c80fc02 Mon Sep 17 00:00:00 2001 From: Omar Polo Date: Wed, 7 Oct 2020 14:38:27 +0200 Subject: added support for mime types (by looking at file extension) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- gmid.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/gmid.c b/gmid.c index a65d4fc..3cc158e 100644 --- a/gmid.c +++ b/gmid.c @@ -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; } -- cgit v1.2.3