commit cc68fe70fcb31b9acebab97ecad2c84c4c80fc02 from: Omar Polo date: Wed Oct 07 12:41:32 2020 UTC added support for mime types (by looking at file extension) 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. commit - 592fd6245350595319e338ef49984a443b818f16 commit + cc68fe70fcb31b9acebab97ecad2c84c4c80fc02 blob - a65d4fc2971b5567fafb6b7c21758cce88161c31 blob + 3cc158e760e3cd1814083427f1070f750ba074ba --- gmid.c +++ 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*); @@ -219,6 +242,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 @@ -254,8 +309,7 @@ send_file(char *path, struct pollfd *fds, struct clien 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; }