diff --git a/mongoose.c b/mongoose.c index cf0eb4be..cbcffa7b 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2737,7 +2737,7 @@ static struct mg_str s_known_types[] = { // clang-format on static struct mg_str guess_content_type(struct mg_str path, const char *extra) { - struct mg_str entry, k, v, s = mg_str(extra); + struct mg_str entry, k, v, s = mg_str(extra), asterisk = mg_str_n("*", 1); size_t i = 0; // Shrink path to its extension only @@ -2747,7 +2747,9 @@ static struct mg_str guess_content_type(struct mg_str path, const char *extra) { // Process user-provided mime type overrides, if any while (mg_span(s, &entry, &s, ',')) { - if (mg_span(entry, &k, &v, '=') && mg_strcmp(path, k) == 0) return v; + if (mg_span(entry, &k, &v, '=') && + (mg_strcmp(asterisk, k) == 0 || mg_strcmp(path, k) == 0)) + return v; } // Process built-in mime types diff --git a/src/http.c b/src/http.c index 044426ef..1c027bd2 100644 --- a/src/http.c +++ b/src/http.c @@ -1,7 +1,7 @@ -#include "http.h" #include "arch.h" #include "base64.h" #include "fmt.h" +#include "http.h" #include "json.h" #include "log.h" #include "net.h" @@ -521,7 +521,7 @@ static struct mg_str s_known_types[] = { // clang-format on static struct mg_str guess_content_type(struct mg_str path, const char *extra) { - struct mg_str entry, k, v, s = mg_str(extra); + struct mg_str entry, k, v, s = mg_str(extra), asterisk = mg_str_n("*", 1); size_t i = 0; // Shrink path to its extension only @@ -531,7 +531,9 @@ static struct mg_str guess_content_type(struct mg_str path, const char *extra) { // Process user-provided mime type overrides, if any while (mg_span(s, &entry, &s, ',')) { - if (mg_span(entry, &k, &v, '=') && mg_strcmp(path, k) == 0) return v; + if (mg_span(entry, &k, &v, '=') && + (mg_strcmp(asterisk, k) == 0 || mg_strcmp(path, k) == 0)) + return v; } // Process built-in mime types diff --git a/test/unit_test.c b/test/unit_test.c index 0d55b3eb..9e0e853f 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -696,6 +696,11 @@ static void eh1(struct mg_connection *c, int ev, void *ev_data) { memset(&sopts, 0, sizeof(sopts)); sopts.mime_types = "foo=a/b,txt=c/d"; mg_http_serve_file(c, hm, "data/a.txt", &sopts); + } else if (mg_match(hm->uri, mg_str("/servefile2"), NULL)) { + struct mg_http_serve_opts sopts; + memset(&sopts, 0, sizeof(sopts)); + sopts.mime_types = "*=a/b,txt=c/d"; + mg_http_serve_file(c, hm, "data/a.txt", &sopts); } else { struct mg_http_serve_opts sopts; memset(&sopts, 0, sizeof(sopts)); @@ -1023,10 +1028,20 @@ static void test_http_server(void) { ASSERT(cmpbody(buf, "hello\n") == 0); { struct mg_http_message hm; + struct mg_str *s; 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("c/d")) == - 0); + ASSERT((s = mg_http_get_header(&hm, "Content-Type")) != NULL); + ASSERT(mg_strcmp(*s, mg_str("c/d")) == 0); + } + + ASSERT(fetch(&mgr, buf, url, "GET /servefile2 HTTP/1.0\n\n") == 200); + ASSERT(cmpbody(buf, "hello\n") == 0); + { + struct mg_http_message hm; + struct mg_str *s; + mg_http_parse(buf, strlen(buf), &hm); + ASSERT((s = mg_http_get_header(&hm, "Content-Type")) != NULL); + ASSERT(mg_strcmp(*s, mg_str("a/b")) == 0); } ASSERT(fetch(&mgr, buf, url, "GET /foo/1 HTTP/1.0\r\n\n") == 200);