Skip to content

Commit

Permalink
Also infer MIME type by file extension
Browse files Browse the repository at this point in the history
  • Loading branch information
esote committed Feb 1, 2020
1 parent e6be0b6 commit 50a4bfe
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 7 deletions.
2 changes: 0 additions & 2 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
TODO:
handle content range requests

(optionally) infer mime types by file extensions
2 changes: 1 addition & 1 deletion filesrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
#define FILESRV_H

void respond(int, char *, size_t);
char * sniff(int);
char * sniff(int, char *);

#endif
68 changes: 65 additions & 3 deletions mime.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* MIME sniffing implementation based on Go's http.DetectContentType(). */
/* MIME sniffing implementation based on Go's http.DetectContentType() and
* mime.TypeByExtension(). */

#include <stddef.h>
#include <stdint.h>
Expand All @@ -23,7 +24,10 @@ static char * masked(uint8_t *, size_t, size_t, union ds *);
static char * mp4(uint8_t *, size_t, size_t, union ds *);
static char * text(uint8_t *, size_t, size_t, union ds *);

struct sig sigs[] = {
static char * sniff_ext(char *);
static char * ext(char *);

static struct sig sigs[] = {
{ html, {{"<!DOCTYPE HTML"}, {.s = 14}} },
{ html, {{"<HTML"}, {.s = 5}} },
{ html, {{"<HEAD"}, {.s = 5}} },
Expand Down Expand Up @@ -213,14 +217,18 @@ struct sig sigs[] = {
#define ISTT(X) ((X) == ' ' || (X) == '>')

char *
sniff(int fd)
sniff(int fd, char *path)
{
uint8_t buf[512];
size_t nonws;
ssize_t len;
ssize_t i;
char *mime;

if ((mime = sniff_ext(path)) != NULL) {
return mime;
}

if ((len = read(fd, buf, 512)) == -1) {
goto err;
}
Expand All @@ -244,6 +252,60 @@ sniff(int fd)
return mime;
}

struct ext_map {
char *ext;
char *mime;
};

static struct ext_map ext_map[] = {
{ ".css", "text/css; charset=utf-8" },
{ ".gif", "image/gif" },
{ ".htm", "text/html; charset=utf-8" },
{ ".html", "text/html; charset=utf-8" },
{ ".jpeg", "image/jpeg" },
{ ".jpg", "image/jpeg" },
{ ".js", "application/javascript" },
{ ".mjs", "application/javascript" },
{ ".pdf", "application/pdf" },
{ ".png", "image/png" },
{ ".svg", "image/svg+xml" },
{ ".wasm", "application/wasm" },
{ ".webp", "image/webp" },
{ ".xml", "text/xml; charset=utf-8" },
{ NULL, NULL }
};

static char *
sniff_ext(char *path)
{
size_t i;
if ((path = ext(path)) == NULL) {
return NULL;
}

for (i = 0; ext_map[i].ext != NULL; i++) {
if (strcmp(ext_map[i].ext, path) == 0) {
return ext_map[i].mime;
}
}

return NULL;
}

static char *
ext(char *path)
{
int i;

for (i = (int)strlen(path) - 1; i >= 0 && path[i] != '/'; i--) {
if (path[i] == '.') {
return path + i;
}
}

return NULL;
}

/* argv[0] = exact signature
* argv[1] = signature length
* argv[2] = mime
Expand Down
2 changes: 1 addition & 1 deletion respond.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ writefile(int afd, char *wbuf, char *path, char *time, off_t size, int head)
"Content-Length: %zd\r\n"
"Content-Type: %s\r\n"
"Last-Modified: %s\r\n"
"\r\n", (ssize_t)size, sniff(fd), time);
"\r\n", (ssize_t)size, sniff(fd, path), time);

if (n < 0) {
warnx("snprintf");
Expand Down

0 comments on commit 50a4bfe

Please sign in to comment.