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.
This commit is contained in:
Omar Polo 2020-10-07 14:38:27 +02:00
parent 592fd62453
commit cc68fe70fc
No known key found for this signature in database
GPG Key ID: 35F98C96A1786F0D
1 changed files with 56 additions and 2 deletions

58
gmid.c
View File

@ -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;
}