add mime_types option and mimetype_get() function

personal/stbuehler/wip
Thomas Porzelt 15 years ago
parent 107798b883
commit 29c962fe06

@ -48,6 +48,7 @@ typedef struct connection connection;
#include "connection.h"
#include "utils.h"
#define SERVER_VERSION ((guint) 0x01FF0000)

@ -510,8 +510,10 @@
a = option_action(srv, name->data.string->str, val);
value_free(val);
if (a == NULL)
if (a == NULL) {
value_free(name);
return FALSE;
}
al = g_queue_peek_head(ctx->action_list_stack);
g_array_append_val(al->data.list, a);

@ -520,6 +520,60 @@ static void core_option_log_timestamp_free(server *srv, plugin *p, size_t ndx, o
log_timestamp_free(srv, oval.ptr);
}
static gboolean core_option_mime_types_parse(server *srv, plugin *p, size_t ndx, value *val, option_value *oval) {
UNUSED(srv);
UNUSED(p);
UNUSED(ndx);
GArray *arr;
/* default value */
if (!val) {
oval->list = g_array_new(FALSE, TRUE, sizeof(value));
return TRUE;
}
/* check if the passed val is of type (("a", "b"), ("x", y")) */
arr = val->data.list;
for (guint i = 0; i < arr->len; i++) {
value *v = g_array_index(arr, value*, i);
value *v1, *v2;
if (v->type != VALUE_LIST) {
ERROR(srv, "mime_types option expects a list of string tuples, entry #%u is of type %s", i, value_type_string(v->type));
return FALSE;
}
if (v->data.list->len != 2) {
ERROR(srv, "mime_types option expects a list of string tuples, entry #%u is not a tuple", i);
return FALSE;
}
v1 = g_array_index(v->data.list, value*, 0);
v2 = g_array_index(v->data.list, value*, 1);
if (v1->type != VALUE_STRING || v2->type != VALUE_STRING) {
ERROR(srv, "mime_types option expects a list of string tuples, entry #%u is a (%s,%s) tuple", i, value_type_string(v1->type), value_type_string(v2->type));
return FALSE;
}
}
/* everything ok */
oval->list = value_extract(val).list;
return TRUE;
}
static void core_option_mime_types_free(server *srv, plugin *p, size_t ndx, option_value oval) {
UNUSED(srv);
UNUSED(p);
UNUSED(ndx);
for (guint i = 0; i < oval.list->len; i++)
value_free(g_array_index(oval.list, value*, i));
g_array_free(oval.list, TRUE);
}
static const plugin_option options[] = {
{ "debug.log_request_handling", VALUE_BOOLEAN, NULL, NULL, NULL },
@ -530,6 +584,8 @@ static const plugin_option options[] = {
{ "server.tag", VALUE_STRING, "lighttpd-2.0~sandbox", NULL, NULL },
{ "server.max_keep_alive_idle", VALUE_NUMBER, GINT_TO_POINTER(5), NULL, NULL },
{ "mime_types", VALUE_LIST, NULL, core_option_mime_types_parse, core_option_mime_types_free },
{ NULL, 0, NULL, NULL, NULL }
};

@ -10,7 +10,9 @@ enum core_options_t {
CORE_OPTION_STATIC_FILE_EXCLUDE,
CORE_OPTION_SERVER_TAG,
CORE_OPTION_MAX_KEEP_ALIVE_IDLE
CORE_OPTION_MAX_KEEP_ALIVE_IDLE,
CORE_OPTION_MIME_TYPES
};
/* the core plugin always has base index 0, as it is the first plugin loaded */

@ -1,5 +1,7 @@
#include "utils.h"
#include "base.h"
#include "plugin_core.h"
#include <stdio.h>
#include <stdlib.h>
@ -297,3 +299,38 @@ guint hash_ipv6(gconstpointer key) {
guint *i = ((guint*)key);
return i[0] ^ i[1] ^ i[2] ^ i[3];
}
GString *mimetype_get(connection *con, GString *filename) {
/* search in mime_types option for the first match */
GArray *arr;
if (!con || !filename || !filename->len)
return NULL;
arr = CORE_OPTION(CORE_OPTION_MIME_TYPES).list;
for (guint i = 0; i < arr->len; i++) {
value *tuple = g_array_index(arr, value*, i);
GString *ext = g_array_index(tuple->data.list, value*, 0)->data.string;
if (ext->len > filename->len)
continue;
/* "" extension matches everything, used for default mimetype */
if (!ext->len)
return g_array_index(tuple->data.list, value*, 1)->data.string;
gint k = filename->len - 1;
gint j = ext->len - 1;
for (; j >= 0; j--) {
if (ext->str[j] != filename->str[k])
break;
k--;
}
if (j == -1)
return g_array_index(tuple->data.list, value*, 1)->data.string;
}
return NULL;
}

@ -34,4 +34,7 @@ LI_API guint hash_ipv4(gconstpointer key);
/* expects a pointer to a 128bit value */
LI_API guint hash_ipv6(gconstpointer key);
/* looks up the mimetype for a filename by comparing suffixes. first match is returned. do not free the result */
LI_API GString *mimetype_get(connection *con, GString *filename);
#endif

@ -23,7 +23,7 @@ struct value {
gboolean boolean;
gint64 number;
GString *string;
/* array of value */
/* array of (value*) */
GArray *list;
/* hash GString => value */
GHashTable *hash;

Loading…
Cancel
Save