From f176e1ae598c8ca008af4c3f9810614009e332a8 Mon Sep 17 00:00:00 2001 From: cpq Date: Tue, 15 Dec 2020 11:58:30 +0000 Subject: [PATCH] Handle more mime types --- mongoose.c | 62 +++++++++++++++++++++++++++++++++++++++++++--- src/http.c | 62 +++++++++++++++++++++++++++++++++++++++++++--- test/data/empty.js | 0 test/unit_test.c | 10 ++++++++ 4 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 test/data/empty.js diff --git a/mongoose.c b/mongoose.c index 37358246..48ed58cb 100644 --- a/mongoose.c +++ b/mongoose.c @@ -655,10 +655,64 @@ static void static_cb(struct mg_connection *c, int ev, void *ev_data, } static const char *guess_content_type(const char *filename) { - int n = (int) strlen(filename); - if (mg_globmatch("#.html", 6, filename, n)) return "text/html"; - if (mg_globmatch("#.css", 5, filename, n)) return "text/css"; - if (mg_globmatch("#.js", 4, filename, n)) return "text/javascript"; + size_t n = strlen(filename); +#define MIME_ENTRY(_ext, _type) \ + { _ext, sizeof(_ext) - 1, _type } + const struct { + const char *ext; + size_t ext_len; + const char *type; + } * t, types[] = { + MIME_ENTRY("html", "text/html"), + MIME_ENTRY("shtml", "text/html"), + MIME_ENTRY("css", "text/css"), + MIME_ENTRY("js", "text/javascript"), + MIME_ENTRY("mjs", "text/javascript"), + MIME_ENTRY("json", "application/json"), + MIME_ENTRY("ico", "image/x-icon"), + MIME_ENTRY("gif", "image/gif"), + MIME_ENTRY("jpg", "image/jpeg"), + MIME_ENTRY("jpeg", "image/jpeg"), + MIME_ENTRY("png", "image/png"), + MIME_ENTRY("svg", "image/svg+xml"), + MIME_ENTRY("txt", "text/plain"), + MIME_ENTRY("torrent", "application/x-bittorrent"), + MIME_ENTRY("wav", "audio/wav"), + MIME_ENTRY("mp3", "audio/mpeg"), + MIME_ENTRY("mid", "audio/mid"), + MIME_ENTRY("ogg", "application/ogg"), + MIME_ENTRY("xml", "application/xml"), + MIME_ENTRY("ttf", "font/ttf"), + MIME_ENTRY("json", "application/json"), + MIME_ENTRY("xsl", "application/xml"), + MIME_ENTRY("doc", "application/msword"), + MIME_ENTRY("exe", "application/octet-stream"), + MIME_ENTRY("zip", "application/zip"), + MIME_ENTRY("xls", "application/excel"), + MIME_ENTRY("tgz", "application/tar-gz"), + MIME_ENTRY("tar", "application/tar"), + MIME_ENTRY("gz", "application/gzip"), + MIME_ENTRY("rar", "application/rar"), + MIME_ENTRY("rtf", "application/rtf"), + MIME_ENTRY("pdf", "application/pdf"), + MIME_ENTRY("mpg", "video/mpeg"), + MIME_ENTRY("webm", "video/webm"), + MIME_ENTRY("mpeg", "video/mpeg"), + MIME_ENTRY("mov", "video/quicktime"), + MIME_ENTRY("mp4", "video/mp4"), + MIME_ENTRY("m4v", "video/x-m4v"), + MIME_ENTRY("asf", "video/x-ms-asf"), + MIME_ENTRY("avi", "video/x-msvideo"), + MIME_ENTRY("bmp", "image/bmp"), + MIME_ENTRY("wasm", "application/wasm"), + {NULL, 0, NULL}, + }; + + for (t = types; t->ext != NULL; t++) { + if (n < t->ext_len + 2) continue; + if (mg_ncasecmp(t->ext, &filename[n - t->ext_len], t->ext_len)) continue; + return t->type; + } return "text/plain"; } diff --git a/src/http.c b/src/http.c index c6562819..3659b649 100644 --- a/src/http.c +++ b/src/http.c @@ -294,10 +294,64 @@ static void static_cb(struct mg_connection *c, int ev, void *ev_data, } static const char *guess_content_type(const char *filename) { - int n = (int) strlen(filename); - if (mg_globmatch("#.html", 6, filename, n)) return "text/html"; - if (mg_globmatch("#.css", 5, filename, n)) return "text/css"; - if (mg_globmatch("#.js", 4, filename, n)) return "text/javascript"; + size_t n = strlen(filename); +#define MIME_ENTRY(_ext, _type) \ + { _ext, sizeof(_ext) - 1, _type } + const struct { + const char *ext; + size_t ext_len; + const char *type; + } * t, types[] = { + MIME_ENTRY("html", "text/html"), + MIME_ENTRY("htm", "text/html"), + MIME_ENTRY("shtml", "text/html"), + MIME_ENTRY("css", "text/css"), + MIME_ENTRY("js", "text/javascript"), + MIME_ENTRY("mjs", "text/javascript"), + MIME_ENTRY("json", "application/json"), + MIME_ENTRY("ico", "image/x-icon"), + MIME_ENTRY("gif", "image/gif"), + MIME_ENTRY("jpg", "image/jpeg"), + MIME_ENTRY("jpeg", "image/jpeg"), + MIME_ENTRY("png", "image/png"), + MIME_ENTRY("svg", "image/svg+xml"), + MIME_ENTRY("txt", "text/plain"), + MIME_ENTRY("wav", "audio/wav"), + MIME_ENTRY("mp3", "audio/mpeg"), + MIME_ENTRY("mid", "audio/mid"), + MIME_ENTRY("ogg", "application/ogg"), + MIME_ENTRY("xml", "application/xml"), + MIME_ENTRY("ttf", "font/ttf"), + MIME_ENTRY("json", "application/json"), + MIME_ENTRY("xsl", "application/xml"), + MIME_ENTRY("doc", "application/msword"), + MIME_ENTRY("exe", "application/octet-stream"), + MIME_ENTRY("zip", "application/zip"), + MIME_ENTRY("xls", "application/excel"), + MIME_ENTRY("tgz", "application/tar-gz"), + MIME_ENTRY("tar", "application/tar"), + MIME_ENTRY("gz", "application/gzip"), + MIME_ENTRY("rar", "application/rar"), + MIME_ENTRY("rtf", "application/rtf"), + MIME_ENTRY("pdf", "application/pdf"), + MIME_ENTRY("mpg", "video/mpeg"), + MIME_ENTRY("webm", "video/webm"), + MIME_ENTRY("mpeg", "video/mpeg"), + MIME_ENTRY("mov", "video/quicktime"), + MIME_ENTRY("mp4", "video/mp4"), + MIME_ENTRY("avi", "video/x-msvideo"), + MIME_ENTRY("csv", "text/csv"), + MIME_ENTRY("bmp", "image/bmp"), + MIME_ENTRY("bin", "application/octet-stream"), + MIME_ENTRY("wasm", "application/wasm"), + {NULL, 0, NULL}, + }; + + for (t = types; t->ext != NULL; t++) { + if (n < t->ext_len + 2) continue; + if (mg_ncasecmp(t->ext, &filename[n - t->ext_len], t->ext_len)) continue; + return t->type; + } return "text/plain"; } diff --git a/test/data/empty.js b/test/data/empty.js new file mode 100644 index 00000000..e69de29b diff --git a/test/unit_test.c b/test/unit_test.c index 5ebb0278..752c4fb1 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -484,6 +484,16 @@ static void test_http_server(void) { free(data); } + { + // Test mime type + struct mg_http_message hm; + ASSERT(fetch(&mgr, buf, url, "GET /empty.js HTTP/1.0\r\n\n") == 200); + mg_http_parse(buf, strlen(buf), &hm); + ASSERT(mg_http_get_header(&hm, "Content-Type") != NULL); + ASSERT(mg_strcmp(*mg_http_get_header(&hm, "Content-Type"), + mg_str("text/javascript")) == 0); + } + { // Test connection refused int i, errored = 0;