aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2020-10-07 14:38:27 +0200
committerOmar Polo <op@omarpolo.com>2020-10-07 14:41:32 +0200
commitcc68fe70fcb31b9acebab97ecad2c84c4c80fc02 (patch)
tree388c1299b55599df87e700270049037611fbdbfc
parent592fd6245350595319e338ef49984a443b818f16 (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.
-rw-r--r--gmid.c58
1 files 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;
}