diff --git a/include/lighttpd/mimetype.h b/include/lighttpd/mimetype.h index 3a2e17d..82e1799 100644 --- a/include/lighttpd/mimetype.h +++ b/include/lighttpd/mimetype.h @@ -11,7 +11,7 @@ typedef struct liMimetypeNode liMimetypeNode; LI_API liMimetypeNode *li_mimetype_node_new(void); LI_API void li_mimetype_node_free(liMimetypeNode *node); -LI_API void li_mimetype_insert(liMimetypeNode *node, GString *suffix, GString *mimetype, guint depth); +LI_API void li_mimetype_insert(liMimetypeNode *node, GString *suffix, GString *mimetype); /* looks up the mimetype for a filename by comparing suffixes. longest match is returned. do not free the result */ LI_API GString *li_mimetype_get(liVRequest *vr, GString *filename); diff --git a/src/main/mimetype.c b/src/main/mimetype.c index c6c3c16..ce296b9 100644 --- a/src/main/mimetype.c +++ b/src/main/mimetype.c @@ -9,11 +9,11 @@ #define MIME_UNMARK_NODE(x) ((gpointer)((uintptr_t)x & (~1))) #define MIME_IS_NODE(x) (1 == ((uintptr_t)x & 1)) -LI_API liMimetypeNode *li_mimetype_node_new(void) { +liMimetypeNode *li_mimetype_node_new(void) { return g_slice_new0(liMimetypeNode); } -LI_API void li_mimetype_node_free(liMimetypeNode *node) { +void li_mimetype_node_free(liMimetypeNode *node) { guint i; gpointer ptr; @@ -39,7 +39,7 @@ LI_API void li_mimetype_node_free(liMimetypeNode *node) { g_slice_free(liMimetypeNode, node); } -LI_API void li_mimetype_insert(liMimetypeNode *node, GString *suffix, GString *mimetype, guint depth) { +static void mimetype_insert(liMimetypeNode *node, GString *suffix, GString *mimetype, guint depth) { guchar c, cdiff; gpointer ptr; liMimetypeNode *next_node; @@ -60,8 +60,7 @@ LI_API void li_mimetype_insert(liMimetypeNode *node, GString *suffix, GString *m if (NULL == node->children) { node->cmin = node->cmax = c; node->children = g_malloc(sizeof(gpointer)); - node->children[0] = mimetype; - return; + node->children[0] = NULL; } else if (c < node->cmin) { cdiff = node->cmin - c; /* how much space we need in front */ node->children = g_realloc(node->children, sizeof(gpointer) * (MIME_COUNT_CHILDREN(node) + cdiff)); /* make room for more children */ @@ -77,17 +76,11 @@ LI_API void li_mimetype_insert(liMimetypeNode *node, GString *suffix, GString *m ptr = node->children[c - node->cmin]; - /* slot not used yet, just point to mimetype */ - if (ptr == NULL) { - node->children[c - node->cmin] = mimetype; - return; - } - - /* slot contains another node */ - if (MIME_IS_NODE(ptr)) { + if (NULL != ptr && MIME_IS_NODE(ptr)) { + /* slot contains another node */ next_node = MIME_UNMARK_NODE(ptr); } else { - /* slot contains a mimetype, split into node */ + /* slot not used yet or contains a mimetype, split into node */ next_node = g_slice_new(liMimetypeNode); next_node->mimetype = ptr; next_node->cmax = next_node->cmin = 0; @@ -95,10 +88,14 @@ LI_API void li_mimetype_insert(liMimetypeNode *node, GString *suffix, GString *m node->children[c - node->cmin] = MIME_MARK_NODE(next_node); } - li_mimetype_insert(next_node, suffix, mimetype, depth+1); + mimetype_insert(next_node, suffix, mimetype, depth+1); +} + +void li_mimetype_insert(liMimetypeNode *node, GString *suffix, GString *mimetype) { + mimetype_insert(node, suffix, mimetype, 0); } -LI_API GString *li_mimetype_get(liVRequest *vr, GString *filename) { +GString *li_mimetype_get(liVRequest *vr, GString *filename) { /* search in mime_types option for the longest suffix match */ GString *mimetype; liMimetypeNode *node; diff --git a/src/main/plugin_core.c b/src/main/plugin_core.c index a45ac5c..0fbc0f1 100644 --- a/src/main/plugin_core.c +++ b/src/main/plugin_core.c @@ -1404,7 +1404,7 @@ static gboolean core_option_mime_types_parse(liServer *srv, liWorker *wrk, liPlu return FALSE; } - li_mimetype_insert(node, v1->data.string, li_value_extract_string(v2), 0); + li_mimetype_insert(node, v1->data.string, li_value_extract_string(v2)); } return TRUE; diff --git a/tests/requests.py b/tests/requests.py index bc71b68..c00de73 100644 --- a/tests/requests.py +++ b/tests/requests.py @@ -121,7 +121,7 @@ class CurlRequest(TestBase): raise CurlRequestException("Didn't get wanted response header '%s'" % (k)) v1 = self.resp_headers[k] if v1 != v: - raise CurlRequestException("Unexpected response header '%s' = '%s' (wanted '%s')" % (k, v, v1)) + raise CurlRequestException("Unexpected response header '%s' = '%s' (wanted '%s')" % (k, v1, v)) return True diff --git a/tests/t-mime-type.py b/tests/t-mime-type.py new file mode 100644 index 0000000..5ad73ae --- /dev/null +++ b/tests/t-mime-type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +from base import * +from requests import * + + +class TestMimeType1(CurlRequest): + URL = "/test.txt" + EXPECT_RESPONSE_BODY = "" + EXPECT_RESPONSE_CODE = 200 + EXPECT_RESPONSE_HEADERS = [ ("Content-Type", "text/plain; charset=utf-8") ] + +class TestMimeType2(CurlRequest): + URL = "/test.xt" + EXPECT_RESPONSE_BODY = "" + EXPECT_RESPONSE_CODE = 200 + EXPECT_RESPONSE_HEADERS = [ ("Content-Type", "text/plain") ] + +class TestMimeType3(CurlRequest): + URL = "/test.rxt" + EXPECT_RESPONSE_BODY = "" + EXPECT_RESPONSE_CODE = 200 + EXPECT_RESPONSE_HEADERS = [ ("Content-Type", "text/strange") ] + +class Test(GroupTest): + group = [TestMimeType1,TestMimeType2,TestMimeType3] + + def Prepare(self): + self.PrepareVHostFile("test.txt", "") + self.PrepareVHostFile("test.xt", "") + self.PrepareVHostFile("test.rxt", "") + self.config = """ +mime_types = ( + ".txt" => "text/plain; charset=utf-8", + ".xt" => "text/plain", + ".rxt" => "text/strange", + "xt" => "should-not-trigger" +); +"""