Browse Source

Split options into two categories: simple (int, bool) and ref-counted pointers

personal/stbuehler/wip
Stefan Bühler 12 years ago
parent
commit
f14103bc2c
  1. 2
      include/lighttpd/actions.h
  2. 28
      include/lighttpd/options.h
  3. 54
      include/lighttpd/plugin.h
  4. 18
      include/lighttpd/plugin_core.h
  5. 4
      include/lighttpd/server.h
  6. 11
      include/lighttpd/typedefs.h
  7. 2
      include/lighttpd/value.h
  8. 1
      include/lighttpd/virtualrequest.h
  9. 13
      src/main/actions.c
  10. 2
      src/main/lighttpd-glue.c
  11. 36
      src/main/log.c
  12. 33
      src/main/options.c
  13. 272
      src/main/plugin.c
  14. 60
      src/main/plugin_core.c
  15. 4
      src/main/response.c
  16. 17
      src/main/server.c
  17. 33
      src/main/value.c
  18. 35
      src/main/virtualrequest.c
  19. 25
      src/modules/mod_access.c
  20. 45
      src/modules/mod_accesslog.c
  21. 4
      src/modules/mod_auth.c
  22. 2
      src/modules/mod_balancer.c
  23. 2
      src/modules/mod_cache_disk_etag.c
  24. 2
      src/modules/mod_debug.c
  25. 4
      src/modules/mod_deflate.c
  26. 6
      src/modules/mod_dirlist.c
  27. 2
      src/modules/mod_expire.c
  28. 6
      src/modules/mod_fastcgi.c
  29. 2
      src/modules/mod_fortune.c
  30. 4
      src/modules/mod_lua.c
  31. 2
      src/modules/mod_openssl.c
  32. 2
      src/modules/mod_proxy.c
  33. 4
      src/modules/mod_redirect.c
  34. 4
      src/modules/mod_rewrite.c
  35. 4
      src/modules/mod_scgi.c
  36. 8
      src/modules/mod_status.c
  37. 4
      src/modules/mod_vhost.c

2
include/lighttpd/actions.h

@ -57,6 +57,8 @@ struct liAction {
union {
liOptionSet setting;
liOptionPtrSet settingptr;
struct {
liCondition *cond;
liAction *target; /** action target to jump to if condition is fulfilled */

28
include/lighttpd/options.h

@ -6,25 +6,35 @@
#endif
union liOptionValue {
gpointer ptr;
gint64 number;
gboolean boolean;
};
struct liOptionPtrValue {
gint refcount;
union {
gpointer ptr;
/* some common pointer types */
GString *string;
GArray *list;
GHashTable *hash;
liAction *action;
liCondition *cond;
GString *string;
GArray *list;
GHashTable *hash;
liAction *action;
liCondition *cond;
} data;
liServerOptionPtr *sopt;
};
struct liOptionSet {
size_t ndx;
liOptionValue value;
liServerOption *sopt;
};
/* Extract content from value, value set to none */
LI_API liOptionValue li_value_extract(liValue *val);
struct liOptionPtrSet {
size_t ndx;
liOptionPtrValue *value;
};
#endif

54
include/lighttpd/plugin.h

@ -8,14 +8,11 @@
#define INIT_FUNC(x) \
LI_EXPORT void * x(server *srv, plugin *)
#define PLUGIN_DATA \
size_t id; \
ssize_t option_base_ndx
typedef void (*liPluginInitCB) (liServer *srv, liPlugin *p, gpointer userdata);
typedef void (*liPluginFreeCB) (liServer *srv, liPlugin *p);
typedef gboolean (*liPluginParseOptionCB) (liServer *srv, liPlugin *p, size_t ndx, liValue *val, liOptionValue *oval);
typedef void (*liPluginFreeOptionCB) (liServer *srv, liPlugin *p, size_t ndx, liOptionValue oval);
typedef gboolean (*liPluginParseOptionPtrCB)(liServer *srv, liPlugin *p, size_t ndx, liValue *val, gpointer *oval);
typedef void (*liPluginFreeOptionPtrCB) (liServer *srv, liPlugin *p, size_t ndx, gpointer oval);
typedef liAction*(*liPluginCreateActionCB) (liServer *srv, liPlugin *p, liValue *val, gpointer userdata);
typedef gboolean (*liPluginSetupCB) (liServer *srv, liPlugin *p, liValue *val, gpointer userdata);
typedef void (*liPluginAngelCB) (liServer *srv, liPlugin *p, gint32 id, GString *data);
@ -48,6 +45,7 @@ struct liPlugin {
liPluginHandleVRCloseCB handle_vrclose;
const liPluginOption *options;
const liPluginOptionPtr *optionptrs;
const liPluginAction *actions;
const liPluginSetup *setups;
const liPluginAngel *angelcbs;
@ -57,9 +55,17 @@ struct liPluginOption {
const gchar *name;
liValueType type;
gpointer default_value;
gint64 default_value;
liPluginParseOptionCB parse_option;
liPluginFreeOptionCB free_option;
};
struct liPluginOptionPtr {
const gchar *name;
liValueType type;
gpointer default_value;
liPluginParseOptionPtrCB parse_option;
liPluginFreeOptionPtrCB free_option;
};
struct liPluginAction {
@ -92,16 +98,33 @@ struct liServerOption {
*/
liPluginParseOptionCB parse_option;
/** if parse_option is NULL, the default_value is used */
gint64 default_value;
size_t index, module_index;
liValueType type;
};
struct liServerOptionPtr {
liPlugin *p;
/** the value is freed with li_value_free after the parse call, so you
* probably want to extract pointers via li_value_extract_*
* val is zero to get the global default value if nothing is specified
* save result in value
*
* Default behaviour (NULL) is to extract the inner value from val
*/
liPluginParseOptionPtrCB parse_option;
/** the free_option handler has to free all allocated resources;
* it may get called with 0 initialized options, so you have to
* check the value.
*/
liPluginFreeOptionCB free_option;
liPluginFreeOptionPtrCB free_option;
/** if li_parse_option is NULL, the default_value is used; it is only used
/** if parse_option is NULL, the default_value is used; it is only used
* for the following value types:
* - BOOLEAN, NUMBER: casted with GPOINTER_TO_INT, i.e. set it with GINT_TO_POINTER
* the numbers are limited to the 32-bit range according to the glib docs
* - STRING: used for g_string_new, i.e. a const char*
*/
gpointer default_value;
@ -129,9 +152,7 @@ LI_API liPlugin *li_plugin_register(liServer *srv, const gchar *name, liPluginIn
LI_API void li_plugin_free(liServer *srv, liPlugin *p);
LI_API void li_server_plugins_free(liServer *srv);
/** free val after call (val may be modified by parser) */
LI_API gboolean li_parse_option(liServer *srv, const char *name, liValue *val, liOptionSet *mark);
LI_API void li_release_option(liServer *srv, liOptionSet *mark); /**< Does not free the option_set memory */
LI_API void li_release_optionptr(liServer *srv, liOptionPtrValue *value);
LI_API void li_plugins_prepare_callbacks(liServer *srv);
@ -162,9 +183,14 @@ LI_API gboolean li_call_setup(liServer *srv, const char *name, liValue *val);
/** free val after call */
LI_API gboolean li_plugin_set_default_option(liServer *srv, const gchar* name, liValue *val);
extern liOptionPtrValue li_option_ptr_zero;
/* needs vrequest *vr and plugin *p */
#define OPTION(idx) _OPTION(vr, p, idx)
#define _OPTION(vr, p, idx) (vr->options[p->opt_base_index + idx])
#define _OPTION_ABS(vr, idx) (vr->options[idx])
#define OPTIONPTR(idx) _OPTIONPTR(vr, p, idx)
#define _OPTIONPTR(vr, p, idx) (vr->optionptrs[p->opt_base_index + idx] ? vr->optionptrs[p->opt_base_index + idx]->data : li_option_ptr_zero.data)
#define _OPTIONPTR_ABS(vr, idx) (vr->optionptrs[idx] ? vr->optionptrs[idx]->data : li_option_ptr_zero.data)
#endif

18
include/lighttpd/plugin_core.h

@ -8,25 +8,31 @@ typedef enum { LI_ETAG_USE_INODE = 1, LI_ETAG_USE_MTIME = 2, LI_ETAG_USE_SIZE =
enum liCoreOptions {
LI_CORE_OPTION_DEBUG_REQUEST_HANDLING = 0,
LI_CORE_OPTION_LOG_TS_FORMAT,
LI_CORE_OPTION_STATIC_RANGE_REQUESTS,
LI_CORE_OPTION_MAX_KEEP_ALIVE_IDLE,
LI_CORE_OPTION_MAX_KEEP_ALIVE_REQUESTS,
LI_CORE_OPTION_ETAG_FLAGS
};
enum liCoreOptionPtrs {
LI_CORE_OPTION_LOG_TS_FORMAT = 0,
LI_CORE_OPTION_LOG,
LI_CORE_OPTION_STATIC_FILE_EXCLUDE_EXTENSIONS,
LI_CORE_OPTION_STATIC_RANGE_REQUESTS,
LI_CORE_OPTION_SERVER_NAME,
LI_CORE_OPTION_SERVER_TAG,
LI_CORE_OPTION_MAX_KEEP_ALIVE_IDLE,
LI_CORE_OPTION_MAX_KEEP_ALIVE_REQUESTS,
LI_CORE_OPTION_MIME_TYPES,
LI_CORE_OPTION_ETAG_FLAGS
};
/* the core plugin always has base index 0, as it is the first plugin loaded */
#define CORE_OPTION(idx) _CORE_OPTION(vr, idx)
#define _CORE_OPTION(vr, idx) _OPTION_ABS(vr, idx)
#define CORE_OPTIONPTR(idx) _CORE_OPTIONPTR(vr, idx)
#define _CORE_OPTIONPTR(vr, idx) _OPTIONPTR_ABS(vr, idx)
LI_API void li_plugin_core_init(liServer *srv, liPlugin *p, gpointer userdata);

4
include/lighttpd/server.h

@ -72,13 +72,15 @@ struct liServer {
/* registered by plugins */
GHashTable *options; /**< const gchar* => (liServerOption*) */
GHashTable *optionptrs; /**< const gchar* => (liServerOptionPtr*) */
GHashTable *actions; /**< const gchar* => (liServerAction*) */
GHashTable *setups; /**< const gchar* => (liServerSetup*) */
GArray *li_plugins_handle_close; /** list of handle_close callbacks */
GArray *li_plugins_handle_vrclose; /** list of handle_vrclose callbacks */
GArray *option_def_values;/** array of option_value */
GArray *option_def_values;/** array of liOptionValue */
GArray *optionptr_def_values;/** array of liOptionPtrValue* */
liAction *mainaction;
gboolean exiting; /** atomic access */

11
include/lighttpd/typedefs.h

@ -34,6 +34,7 @@ typedef struct liBalancerFunc liBalancerFunc;
typedef enum {
ACTION_TSETTING,
ACTION_TSETTINGPTR,
ACTION_TFUNCTION,
ACTION_TCONDITION,
ACTION_TLIST,
@ -125,9 +126,13 @@ typedef enum {
/* options.h */
typedef union liOptionValue liOptionValue;
typedef struct liOptionPtrValue liOptionPtrValue;
typedef struct liOptionSet liOptionSet;
typedef union liOptionValue liOptionValue;
typedef struct liOptionPtrSet liOptionPtrSet;
/* plugin.h */
typedef struct liPlugin liPlugin;
@ -136,6 +141,10 @@ typedef struct liPluginOption liPluginOption;
typedef struct liServerOption liServerOption;
typedef struct liPluginOptionPtr liPluginOptionPtr;
typedef struct liServerOptionPtr liServerOptionPtr;
typedef struct liPluginAction liPluginAction;
typedef struct liServerAction liServerAction;

2
include/lighttpd/value.h

@ -46,7 +46,9 @@ LI_API void li_value_list_free(GArray *vallist);
/* extracts the pointer of a; set val->type to none (so a free on the value doesn't free the previous content)
* returns NULL (and doesn't modify val->type) if the type doesn't match
* there is no need to extract scalar values - just copy them
*/
LI_API gpointer li_value_extract_ptr(liValue *val);
LI_API GString* li_value_extract_string(liValue *val);
LI_API GArray* li_value_extract_list(liValue *val);
LI_API GHashTable* li_value_extract_hash(liValue *val);

1
include/lighttpd/virtualrequest.h

@ -62,6 +62,7 @@ struct liVRequest {
liVRequestRef *ref;
liOptionValue *options;
liOptionPtrValue **optionptrs;
liVRequestState state;

13
src/main/actions.c

@ -19,7 +19,9 @@ void li_action_release(liServer *srv, liAction *a) {
if (g_atomic_int_dec_and_test(&a->refcount)) {
switch (a->type) {
case ACTION_TSETTING:
li_release_option(srv, &a->data.setting);
break;
case ACTION_TSETTINGPTR:
li_release_optionptr(srv, a->data.settingptr.value);
break;
case ACTION_TFUNCTION:
if (a->data.function.free) {
@ -123,6 +125,7 @@ static void action_stack_element_release(liServer *srv, liVRequest *vr, action_s
switch (a->type) {
case ACTION_TSETTING:
case ACTION_TSETTINGPTR:
break;
case ACTION_TFUNCTION:
if (ase->data.context && a->data.function.cleanup) {
@ -261,6 +264,14 @@ liHandlerResult li_action_execute(liVRequest *vr) {
vr->options[a->data.setting.ndx] = a->data.setting.value;
action_stack_pop(srv, vr, as);
break;
case ACTION_TSETTINGPTR:
if (vr->optionptrs[a->data.settingptr.ndx] != a->data.settingptr.value) {
g_atomic_int_inc(&a->data.settingptr.value->refcount);
li_release_optionptr(srv, vr->optionptrs[a->data.settingptr.ndx]);
vr->optionptrs[a->data.settingptr.ndx] = a->data.settingptr.value;
}
action_stack_pop(srv, vr, as);
break;
case ACTION_TFUNCTION:
res = a->data.function.func(vr, a->data.function.param, &ase->data.context);
switch (res) {

2
src/main/lighttpd-glue.c

@ -136,7 +136,7 @@ GString *li_mimetype_get(liVRequest *vr, GString *filename) {
if (!vr || !filename || !filename->len)
return NULL;
arr = CORE_OPTION(LI_CORE_OPTION_MIME_TYPES).list;
arr = CORE_OPTIONPTR(LI_CORE_OPTION_MIME_TYPES).list;
for (guint i = 0; i < arr->len; i++) {
gint k, j;

36
src/main/log.c

@ -42,31 +42,37 @@ gboolean li_log_write_(liServer *srv, liVRequest *vr, liLogLevel log_level, guin
liLog *log = NULL;
liLogEntry *log_entry;
liLogTimestamp *ts = NULL;
GArray *logs = NULL;
if (vr != NULL) {
if (!srv) srv = vr->wrk->srv;
/* get log from connection */
log = g_array_index(CORE_OPTION(LI_CORE_OPTION_LOG).list, liLog*, log_level);
if (log == NULL)
return TRUE;
ts = CORE_OPTION(LI_CORE_OPTION_LOG_TS_FORMAT).ptr;
if (!ts)
ts = g_array_index(srv->logs.timestamps, liLogTimestamp*, 0);
logs = CORE_OPTIONPTR(LI_CORE_OPTION_LOG).list;
ts = CORE_OPTIONPTR(LI_CORE_OPTION_LOG_TS_FORMAT).ptr;
}
else {
log = g_array_index(g_array_index(srv->option_def_values, liOptionValue, 0 + LI_CORE_OPTION_LOG).list, liLog*, log_level);
if (log == NULL)
return TRUE;
liOptionPtrValue *ologval;
ologval = g_array_index(srv->optionptr_def_values, liOptionPtrValue*, 0 + LI_CORE_OPTION_LOG);
if (ologval != NULL) logs = ologval->data.list;
}
if (logs != NULL && log_level < logs->len) {
log = g_array_index(logs, liLog*, log_level);
/* if (log == NULL)
return TRUE;*/
}
if (!ts) {
ts = g_array_index(srv->logs.timestamps, liLogTimestamp*, 0);
}
li_log_ref(srv, log);
if (log) li_log_ref(srv, log);
log_line = g_string_sized_new(0);
va_start(ap, fmt);
g_string_vprintf(log_line, fmt, ap);
va_end(ap);
if (!(flags & LOG_FLAG_NOLOCK))
if (log && !(flags & LOG_FLAG_NOLOCK))
log_lock(log);
#if 0
@ -135,11 +141,16 @@ gboolean li_log_write_(liServer *srv, liVRequest *vr, liLogLevel log_level, guin
g_mutex_unlock(srv->logs.mutex);
}
if (!(flags & LOG_FLAG_NOLOCK))
if (log && !(flags & LOG_FLAG_NOLOCK))
log_unlock(log);
g_string_append_len(log_line, CONST_STR_LEN("\r\n"));
if (!log) {
li_angel_log(srv, log_line);
return TRUE;
}
switch (g_atomic_int_get(&srv->state)) {
case LI_SERVER_INIT:
case LI_SERVER_LOADING:
@ -153,6 +164,7 @@ gboolean li_log_write_(liServer *srv, liVRequest *vr, liLogLevel log_level, guin
default:
break;
}
log_entry = g_slice_new(liLogEntry);
log_entry->log = log;
log_entry->msg = log_line;

33
src/main/options.c

@ -1,36 +1,3 @@
#include <lighttpd/base.h>
/* Extract ovalue from ovalue, ovalue set to none */
liOptionValue li_value_extract(liValue *val) {
liOptionValue oval = {0};
if (!val) return oval;
switch (val->type) {
case LI_VALUE_NONE:
break;
case LI_VALUE_BOOLEAN:
oval.boolean = val->data.boolean;
break;
case LI_VALUE_NUMBER:
oval.number = val->data.number;
break;
case LI_VALUE_STRING:
oval.string = val->data.string;
break;
case LI_VALUE_LIST:
oval.list = val->data.list;
break;
case LI_VALUE_HASH:
oval.hash = val->data.hash;
break;
case LI_VALUE_ACTION:
oval.ptr = val->data.val_action.action;
break;
case LI_VALUE_CONDITION:
oval.ptr = val->data.val_action.action;
break;
}
val->type = LI_VALUE_NONE;
return oval;
}

272
src/main/plugin.c

@ -2,8 +2,11 @@
#include <lighttpd/base.h>
static gboolean plugin_load_default_option(liServer *srv, liServerOption *sopt);
static gboolean plugin_load_default_optionptr(liServer *srv, liServerOptionPtr *sopt);
static void li_plugin_free_default_options(liServer *srv, liPlugin *p);
liOptionPtrValue li_option_ptr_zero = { 0 };
static liPlugin* plugin_new(const gchar *name) {
liPlugin *p = g_slice_new0(liPlugin);
p->name = name;
@ -14,13 +17,20 @@ static void li_plugin_free_options(liServer *srv, liPlugin *p) {
size_t i;
const liPluginOption *po;
liServerOption *so;
const liPluginOptionPtr *pop;
liServerOptionPtr *sop;
if (!p->options) return;
for (i = 0; (po = &p->options[i])->name; i++) {
if (p->options) for (i = 0; (po = &p->options[i])->name; i++) {
if (NULL == (so = g_hash_table_lookup(srv->options, po->name))) break;
if (so->p != p) break;
g_hash_table_remove(srv->options, po->name);
}
if (p->optionptrs) for (i = 0; (pop = &p->optionptrs[i])->name; i++) {
if (NULL == (sop = g_hash_table_lookup(srv->optionptrs, pop->name))) break;
if (sop->p != p) break;
g_hash_table_remove(srv->optionptrs, pop->name);
}
}
static void li_plugin_free_actions(liServer *srv, liPlugin *p) {
@ -130,6 +140,7 @@ liPlugin *li_plugin_register(liServer *srv, const gchar *name, liPluginInitCB in
if (p->options) {
size_t i;
liServerOption *so;
liServerOptionPtr *sop;
const liPluginOption *po;
for (i = 0; (po = &p->options[i])->name; i++) {
@ -141,10 +152,17 @@ liPlugin *li_plugin_register(liServer *srv, const gchar *name, liPluginInitCB in
li_plugin_free(srv, p);
return NULL;
}
if (NULL != (sop = (liServerOptionPtr*)g_hash_table_lookup(srv->optionptrs, po->name))) {
ERROR(srv, "Option '%s' already registered by plugin '%s', unloading '%s'",
po->name,
sop->p ? sop->p->name : "<none>",
p->name);
li_plugin_free(srv, p);
return NULL;
}
so = g_slice_new0(liServerOption);
so->type = po->type;
so->parse_option = po->parse_option;
so->free_option = po->free_option;
so->index = g_hash_table_size(srv->options);
so->module_index = i;
so->p = p;
@ -154,6 +172,42 @@ liPlugin *li_plugin_register(liServer *srv, const gchar *name, liPluginInitCB in
}
}
if (p->optionptrs) {
size_t i;
liServerOption *so_;
liServerOptionPtr *so;
const liPluginOptionPtr *po;
for (i = 0; (po = &p->optionptrs[i])->name; i++) {
if (NULL != (so_ = (liServerOption*)g_hash_table_lookup(srv->options, po->name))) {
ERROR(srv, "Option '%s' already registered by plugin '%s', unloading '%s'",
po->name,
so_->p ? so_->p->name : "<none>",
p->name);
li_plugin_free(srv, p);
return NULL;
}
if (NULL != (so = (liServerOptionPtr*)g_hash_table_lookup(srv->optionptrs, po->name))) {
ERROR(srv, "Option '%s' already registered by plugin '%s', unloading '%s'",
po->name,
so->p ? so->p->name : "<none>",
p->name);
li_plugin_free(srv, p);
return NULL;
}
so = g_slice_new0(liServerOptionPtr);
so->type = po->type;
so->parse_option = po->parse_option;
so->free_option = po->free_option;
so->index = g_hash_table_size(srv->optionptrs);
so->module_index = i;
so->p = p;
so->default_value = po->default_value;
g_hash_table_insert(srv->optionptrs, (gchar*) po->name, so);
plugin_load_default_optionptr(srv, so);
}
}
if (p->actions) {
size_t i;
liServerAction *sa;
@ -206,17 +260,50 @@ static liServerOption* find_option(liServer *srv, const char *name) {
return (liServerOption*) g_hash_table_lookup(srv->options, name);
}
gboolean li_parse_option(liServer *srv, const char *name, liValue *val, liOptionSet *mark) {
liServerOption *sopt;
if (!srv || !name || !mark) return FALSE;
static gboolean li_parse_option(liServer *srv, liServerOption *sopt, const char *name, liValue *val, liOptionSet *mark) {
if (!srv || !name || !mark || !sopt) return FALSE;
sopt = find_option(srv, name);
if (!sopt) {
ERROR(srv, "Unknown option '%s'", name);
if (sopt->type != val->type && sopt->type != LI_VALUE_NONE) {
ERROR(srv, "Unexpected value type '%s', expected '%s' for option %s",
li_value_type_string(val->type), li_value_type_string(sopt->type), name);
return FALSE;
}
if (!sopt->parse_option) {
switch (sopt->type) {
case LI_VALUE_BOOLEAN:
mark->value.boolean = val->data.boolean;
break;
case LI_VALUE_NUMBER:
mark->value.number = val->data.number;
break;
default:
ERROR(srv, "Invalid scalar option type '%s' for option %s",
li_value_type_string(sopt->type), name);
return FALSE;
}
} else {
if (!sopt->parse_option(srv, sopt->p, sopt->module_index, val, &mark->value)) {
/* errors should be logged by parse function */
return FALSE;
}
}
mark->ndx = sopt->index;
return TRUE;
}
static liServerOptionPtr* find_optionptr(liServer *srv, const char *name) {
return (liServerOptionPtr*) g_hash_table_lookup(srv->optionptrs, name);
}
static gboolean li_parse_optionptr(liServer *srv, liServerOptionPtr *sopt, const char *name, liValue *val, liOptionPtrSet *mark) {
liOptionPtrValue *oval;
gpointer ptr = NULL;
if (!srv || !name || !mark || !sopt) return FALSE;
if (sopt->type != val->type && sopt->type != LI_VALUE_NONE) {
ERROR(srv, "Unexpected value type '%s', expected '%s' for option %s",
li_value_type_string(val->type), li_value_type_string(sopt->type), name);
@ -224,26 +311,39 @@ gboolean li_parse_option(liServer *srv, const char *name, liValue *val, liOption
}
if (!sopt->parse_option) {
mark->value = li_value_extract(val);
ptr = li_value_extract_ptr(val);
} else {
if (!sopt->parse_option(srv, sopt->p, sopt->module_index, val, &mark->value)) {
if (!sopt->parse_option(srv, sopt->p, sopt->module_index, val, &ptr)) {
/* errors should be logged by parse function */
return FALSE;
}
}
if (ptr) {
oval = g_slice_new0(liOptionPtrValue);
oval->refcount = 1;
oval->sopt = sopt;
oval->data.ptr = ptr;
} else {
oval = NULL;
}
mark->ndx = sopt->index;
mark->sopt = sopt;
mark->value = oval;
return TRUE;
}
void li_release_option(liServer *srv, liOptionSet *mark) { /** Does not free the option_set memory */
liServerOption *sopt;
if (!srv || !mark || !mark->sopt) return;
sopt = mark->sopt;
void li_release_optionptr(liServer *srv, liOptionPtrValue *value) {
liServerOptionPtr *sopt;
if (!srv || !value) return;
mark->sopt = NULL;
assert(g_atomic_int_get(&value->refcount) > 0);
if (!g_atomic_int_dec_and_test(&value->refcount)) return;
sopt = value->sopt;
value->sopt = NULL;
if (!sopt->free_option) {
switch (sopt->type) {
case LI_VALUE_NONE:
@ -252,39 +352,43 @@ void li_release_option(liServer *srv, liOptionSet *mark) { /** Does not free the
/* Nothing to free */
break;
case LI_VALUE_STRING:
if (mark->value.string)
g_string_free(mark->value.string, TRUE);
if (value->data.string)
g_string_free(value->data.string, TRUE);
break;
case LI_VALUE_LIST:
if (mark->value.list)
li_value_list_free(mark->value.list);
if (value->data.list)
li_value_list_free(value->data.list);
break;
case LI_VALUE_HASH:
if (mark->value.hash)
g_hash_table_destroy(mark->value.hash);
if (value->data.hash)
g_hash_table_destroy(value->data.hash);
break;
case LI_VALUE_ACTION:
if (mark->value.action)
li_action_release(srv, mark->value.action);
if (value->data.action)
li_action_release(srv, value->data.action);
break;
case LI_VALUE_CONDITION:
if (mark->value.cond)
li_condition_release(srv, mark->value.cond);
if (value->data.cond)
li_condition_release(srv, value->data.cond);
break;
}
} else {
sopt->free_option(srv, sopt->p, sopt->module_index, mark->value);
}
{
liOptionValue empty = {0};
mark->value = empty;
sopt->free_option(srv, sopt->p, sopt->module_index, value->data.ptr);
}
g_slice_free(liOptionPtrValue, value);
}
liAction* li_option_action(liServer *srv, const gchar *name, liValue *val) {
liOptionSet setting;
liServerOption *sopt;
sopt = find_option(srv, name);
if (!sopt) {
ERROR(srv, "Unknown option '%s'", name);
return FALSE;
}
if (!li_parse_option(srv, name, val, &setting)) {
if (!li_parse_option(srv, sopt, name, val, &setting)) {
return NULL;
}
@ -359,30 +463,30 @@ void li_plugins_handle_vrclose(liVRequest *vr) {
gboolean li_plugin_set_default_option(liServer *srv, const gchar* name, liValue *val) {
liServerOption *sopt;
liOptionSet setting;
liOptionValue v;
sopt = find_option(srv, name);
liServerOptionPtr *soptptr;
if (!sopt) {
ERROR(srv, "unknown option \"%s\"", name);
return FALSE;
}
if (NULL != (sopt = find_option(srv, name))) {
liOptionSet setting;
/* assign new value */
if (!li_parse_option(srv, name, val, &setting)) {
return FALSE;
}
/* assign new value */
if (!li_parse_option(srv, sopt, name, val, &setting)) {
return FALSE;
}
v = g_array_index(srv->option_def_values, liOptionValue, sopt->index);
g_array_index(srv->option_def_values, liOptionValue, sopt->index) = setting.value;
g_array_index(srv->option_def_values, liOptionValue, sopt->index) = setting.value;
} else if (NULL != (soptptr = find_optionptr(srv, name))) {
liOptionPtrSet setting;
/* free old value */
setting.sopt = sopt;
setting.ndx = sopt->index;
setting.value = v;
/* assign new value */
if (!li_parse_optionptr(srv, soptptr, name, val, &setting)) {
return FALSE;
}
li_release_option(srv, &setting);
g_array_index(srv->optionptr_def_values, liOptionPtrValue*, soptptr->index) = setting.value;
} else {
ERROR(srv, "unknown option \"%s\"", name);
return FALSE;
}
return TRUE;
}
@ -395,18 +499,16 @@ static gboolean plugin_load_default_option(liServer *srv, liServerOption *sopt)
if (!sopt->parse_option) {
switch (sopt->type) {
case LI_VALUE_NONE:
break;
case LI_VALUE_BOOLEAN:
oval.boolean = GPOINTER_TO_INT(sopt->default_value);
break;
case LI_VALUE_NUMBER:
oval.number = GPOINTER_TO_INT(sopt->default_value);
break;
case LI_VALUE_STRING:
oval.string = g_string_new((const char*) sopt->default_value);
break;
default:
oval.ptr = NULL;
ERROR(srv, "Invalid type '%s' for scalar option",
li_value_type_string(sopt->type));
return FALSE;
}
} else {
if (!sopt->parse_option(srv, sopt->p, sopt->module_index, NULL, &oval)) {
@ -423,25 +525,57 @@ static gboolean plugin_load_default_option(liServer *srv, liServerOption *sopt)
return TRUE;
}
static gboolean plugin_load_default_optionptr(liServer *srv, liServerOptionPtr *sopt) {
gpointer ptr = NULL;
liOptionPtrValue *oval = NULL;
if (!sopt)
return FALSE;
if (!sopt->parse_option) {
switch (sopt->type) {
case LI_VALUE_STRING:
ptr = g_string_new((const char*) sopt->default_value);
break;
default:
ptr = NULL;
}
} else {
if (!sopt->parse_option(srv, sopt->p, sopt->module_index, NULL, &ptr)) {
/* errors should be logged by parse function */
return FALSE;
}
}
if (ptr) {
oval = g_slice_new0(liOptionPtrValue);
oval->refcount = 1;
oval->data.ptr = ptr;
oval->sopt = sopt;
}
if (srv->optionptr_def_values->len <= sopt->index)
g_array_set_size(srv->optionptr_def_values, sopt->index + 1);
li_release_optionptr(srv, g_array_index(srv->optionptr_def_values, liOptionPtrValue*, sopt->index));
g_array_index(srv->optionptr_def_values, liOptionPtrValue*, sopt->index) = oval;
return TRUE;
}
static void li_plugin_free_default_options(liServer *srv, liPlugin *p) {
static const liOptionValue oempty = {0};
GHashTableIter iter;
gpointer k, v;
g_hash_table_iter_init(&iter, srv->options);
g_hash_table_iter_init(&iter, srv->optionptrs);
while (g_hash_table_iter_next(&iter, &k, &v)) {
liServerOption *sopt = v;
liOptionSet mark;
mark.sopt = sopt;
mark.ndx = sopt->index;
liServerOptionPtr *sopt = v;
if (sopt->p != p)
continue;
mark.value = g_array_index(srv->option_def_values, liOptionValue, sopt->index);
li_release_option(srv, &mark);
g_array_index(srv->option_def_values, liOptionValue, sopt->index) = oempty;
li_release_optionptr(srv, g_array_index(srv->optionptr_def_values, liOptionPtrValue*, sopt->index));
g_array_index(srv->optionptr_def_values, liOptionPtrValue*, sopt->index) = NULL;
}
}

60
src/main/plugin_core.c

@ -420,7 +420,7 @@ static liHandlerResult core_handle_static(liVRequest *vr, gpointer param, gpoint
struct stat st;
int err;
liHandlerResult res;
GArray *exclude_arr = CORE_OPTION(LI_CORE_OPTION_STATIC_FILE_EXCLUDE_EXTENSIONS).list;
GArray *exclude_arr = CORE_OPTIONPTR(LI_CORE_OPTION_STATIC_FILE_EXCLUDE_EXTENSIONS).list;
static const gchar boundary[] = "fkj49sn38dcn3";
UNUSED(param);
@ -822,7 +822,7 @@ static gboolean core_module_load(liServer *srv, liPlugin* p, liValue *val, gpoin
}
}
g_array_free(mods->data.list, TRUE);
mods->data.list = li_value_extract_ist(val);
mods->data.list = li_value_extract_list(val);
} else {
ERROR(srv, "module_load takes either a string or a list of strings as parameter, %s given", li_value_type_string(val->type));
return FALSE;
@ -880,7 +880,7 @@ static gboolean core_stat_cache_ttl(liServer *srv, liPlugin* p, liValue *val, gp
* OPTIONS
*/
static gboolean core_option_log_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, liOptionValue *oval) {
static gboolean core_option_log_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, gpointer *oval) {
GHashTableIter iter;
gpointer k, v;
liLogLevel level;
@ -890,7 +890,7 @@ static gboolean core_option_log_parse(liServer *srv, liPlugin *p, size_t ndx, li
UNUSED(p);
UNUSED(ndx);
oval->list = arr;
*oval = arr;
g_array_set_size(arr, 6);
/* default value */
@ -937,8 +937,8 @@ static gboolean core_option_log_parse(liServer *srv, liPlugin *p, size_t ndx, li
return TRUE;
}
static void core_option_log_free(liServer *srv, liPlugin *p, size_t ndx, liOptionValue oval) {
GArray *arr = oval.list;
static void core_option_log_free(liServer *srv, liPlugin *p, size_t ndx, gpointer oval) {
GArray *arr = oval;
UNUSED(p);
UNUSED(ndx);
@ -951,25 +951,25 @@ static void core_option_log_free(liServer *srv, liPlugin *p, size_t ndx, liOptio
g_array_free(arr, TRUE);
}
static gboolean core_option_log_timestamp_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, liOptionValue *oval) {
static gboolean core_option_log_timestamp_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, gpointer *oval) {
UNUSED(p);
UNUSED(ndx);
if (!val) return TRUE;
oval->ptr = li_log_timestamp_new(srv, li_value_extract_string(val));
*oval = li_log_timestamp_new(srv, li_value_extract_string(val));
return TRUE;
}
static void core_option_log_timestamp_free(liServer *srv, liPlugin *p, size_t ndx, liOptionValue oval) {
static void core_option_log_timestamp_free(liServer *srv, liPlugin *p, size_t ndx, gpointer oval) {
UNUSED(p);
UNUSED(ndx);
if (!oval.ptr) return;
li_log_timestamp_free(srv, oval.ptr);
if (!oval) return;
li_log_timestamp_free(srv, oval);
}
static gboolean core_option_static_exclude_exts_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, liOptionValue *oval) {
static gboolean core_option_static_exclude_exts_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, gpointer *oval) {
GArray *arr;
UNUSED(srv);
UNUSED(p);
@ -987,13 +987,13 @@ static gboolean core_option_static_exclude_exts_parse(liServer *srv, liPlugin *p
}
/* everything ok */
oval->list = li_value_extract_list(val);
*oval = li_value_extract_list(val);
return TRUE;
}
static gboolean core_option_mime_types_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, liOptionValue *oval) {
static gboolean core_option_mime_types_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, gpointer *oval) {
GArray *arr;
UNUSED(srv);
UNUSED(p);
@ -1002,7 +1002,7 @@ static gboolean core_option_mime_types_parse(liServer *srv, liPlugin *p, size_t
/* default value */
if (!val) {
oval->list = g_array_new(FALSE, TRUE, sizeof(liValue));
*oval = g_array_new(FALSE, TRUE, sizeof(liValue));
return TRUE;
}
@ -1030,20 +1030,21 @@ static gboolean core_option_mime_types_parse(liServer *srv, liPlugin *p, size_t
}
/* everything ok */
oval->list = li_value_extract_list(val);
*oval = li_value_extract_list(val);
return TRUE;
}
static void core_option_mime_types_free(liServer *srv, liPlugin *p, size_t ndx, liOptionValue oval) {
static void core_option_mime_types_free(liServer *srv, liPlugin *p, size_t ndx, gpointer oval) {
GArray *list = oval;
UNUSED(srv);
UNUSED(p);
UNUSED(ndx);
for (guint i = 0; i < oval.list->len; i++)
li_value_free(g_array_index(oval.list, liValue*, i));
for (guint i = 0; i < list->len; i++)
li_value_free(g_array_index(list, liValue*, i));
g_array_free(oval.list, TRUE);
g_array_free(list, TRUE);
}
static gboolean core_option_etag_use_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, liOptionValue *oval) {
@ -1489,23 +1490,29 @@ static void core_suspend(liServer *srv, liPlugin *p, gint32 id, GString *data) {
}
static const liPluginOption options[] = {
{ "debug.log_request_handling", LI_VALUE_BOOLEAN, GINT_TO_POINTER(FALSE), NULL, NULL },
{ "debug.log_request_handling", LI_VALUE_BOOLEAN, FALSE, NULL },
{ "static.range_requests", LI_VALUE_BOOLEAN, TRUE, NULL },
{ "keepalive.timeout", LI_VALUE_NUMBER, 5, NULL },
{ "keepalive.requests", LI_VALUE_NUMBER, 0, NULL },
{ "etag.use", LI_VALUE_NONE, 0, core_option_etag_use_parse }, /* type in config is list, internal type is number for flags */
{ NULL, 0, 0, NULL }
};
static const liPluginOptionPtr optionptrs[] = {
{ "log.timestamp", LI_VALUE_STRING, NULL, core_option_log_timestamp_parse, core_option_log_timestamp_free },
{ "log", LI_VALUE_HASH, NULL, core_option_log_parse, core_option_log_free },
{ "static.exclude_extensions", LI_VALUE_LIST, NULL, core_option_static_exclude_exts_parse, NULL },
{ "static.range_requests", LI_VALUE_BOOLEAN, GINT_TO_POINTER(TRUE), NULL, NULL },
{ "server.name", LI_VALUE_STRING, NULL, NULL, NULL },
{ "server.tag", LI_VALUE_STRING, PACKAGE_DESC, NULL, NULL },
{ "keepalive.timeout", LI_VALUE_NUMBER, GINT_TO_POINTER(5), NULL, NULL },
{ "keepalive.requests", LI_VALUE_NUMBER, GINT_TO_POINTER(0), NULL, NULL },
{ "mime_types", LI_VALUE_LIST, NULL, core_option_mime_types_parse, core_option_mime_types_free },
{ "etag.use", LI_VALUE_NONE, NULL, core_option_etag_use_parse, NULL }, /* type in config is list, internal type is number for flags */
{ NULL, 0, NULL, NULL, NULL }
};
@ -1564,6 +1571,7 @@ void li_plugin_core_init(liServer *srv, liPlugin *p, gpointer userdata) {
UNUSED(srv); UNUSED(userdata);
p->options = options;
p->optionptrs = optionptrs;
p->actions = actions;
p->setups = setups;
p->angelcbs = angelcbs;

4
src/main/response.c

@ -113,7 +113,7 @@ gboolean li_response_send_headers(liConnection *con) {
}
if (!have_server) {
GString *tag = CORE_OPTION(LI_CORE_OPTION_SERVER_TAG).string;
GString *tag = CORE_OPTIONPTR(LI_CORE_OPTION_SERVER_TAG).string;
if (tag->len) {
g_string_append_len(head, CONST_STR_LEN("Server: "));
@ -244,7 +244,7 @@ void li_response_send_error_page(liConnection *con) {
g_string_append_len(html, str, len);
g_string_append_len(html, CONST_STR_LEN(" <p id=\"footer\">"));
g_string_append_len(html, GSTR_LEN(CORE_OPTION(LI_CORE_OPTION_SERVER_TAG).string));
g_string_append_len(html, GSTR_LEN(CORE_OPTIONPTR(LI_CORE_OPTION_SERVER_TAG).string));
g_string_append_len(html, CONST_STR_LEN(
"</p>\n"
" </div>\n"

17
src/main/server.c

@ -41,10 +41,14 @@ void li_server_socket_acquire(liServerSocket* sock) {
g_atomic_int_inc(&sock->refcount);
}
static void server_value_free(gpointer _so) {
static void server_option_free(gpointer _so) {
g_slice_free(liServerOption, _so);
}
static void server_optionptr_free(gpointer _so) {
g_slice_free(liServerOptionPtr, _so);
}
static void server_action_free(gpointer _sa) {
g_slice_free(liServerAction, _sa);
}
@ -108,13 +112,15 @@ liServer* li_server_new(const gchar *module_dir) {
srv->modules = li_modules_new(srv, module_dir);
srv->plugins = g_hash_table_new(g_str_hash, g_str_equal);
srv->options = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, server_value_free);
srv->options = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, server_option_free);
srv->optionptrs = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, server_optionptr_free);
srv->actions = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, server_action_free);
srv->setups = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, server_setup_free);
srv->li_plugins_handle_close = g_array_new(FALSE, TRUE, sizeof(liPlugin*));
srv->li_plugins_handle_vrclose = g_array_new(FALSE, TRUE, sizeof(liPlugin*));
srv->option_def_values = g_array_new(FALSE, TRUE, sizeof(liOptionValue));
srv->optionptr_def_values = g_array_new(FALSE, TRUE, sizeof(liOptionPtrValue*));
srv->mainaction = NULL;
@ -246,6 +252,13 @@ void li_server_free(liServer* srv) {
}
g_array_free(srv->option_def_values, TRUE);
{
guint i;
for (i = 0; i < srv->optionptr_def_values->len; i++) {
li_release_optionptr(srv, g_array_index(srv->optionptr_def_values, liOptionPtrValue*, i));
}
}
g_array_free(srv->optionptr_def_values, TRUE);
li_server_plugins_free(srv);
g_array_free(srv->li_plugins_handle_close, TRUE);
g_array_free(srv->li_plugins_handle_vrclose, TRUE);

33
src/main/value.c

@ -236,6 +236,39 @@ GString *li_value_to_string(liValue *val) {
return str;
}
gpointer li_value_extract_ptr(liValue *val) {
gpointer ptr = NULL;
if (!val) return NULL;
switch (val->type) {
case LI_VALUE_NONE:
break;
case LI_VALUE_BOOLEAN:
break;
case LI_VALUE_NUMBER:
break;
case LI_VALUE_STRING:
ptr = val->data.string;
break;
case LI_VALUE_LIST:
ptr = val->data.list;
break;
case LI_VALUE_HASH:
ptr = val->data.hash;
break;
case LI_VALUE_ACTION:
ptr = val->data.val_action.action;
break;
case LI_VALUE_CONDITION:
ptr = val->data.val_action.action;
break;
}
val->type = LI_VALUE_NONE;
return ptr;
}
GString* li_value_extract_string(liValue *val) {
if (val->type != LI_VALUE_STRING) return NULL;
val->type = LI_VALUE_NONE;

35
src/main/virtualrequest.c

@ -155,6 +155,15 @@ liVRequest* li_vrequest_new(liConnection *con, liVRequestHandlerCB handle_respon
vr->plugin_ctx = g_ptr_array_new();
g_ptr_array_set_size(vr->plugin_ctx, g_hash_table_size(srv->plugins));
vr->options = g_slice_copy(srv->option_def_values->len * sizeof(liOptionValue), srv->option_def_values->data);
vr->optionptrs = g_slice_copy(srv->optionptr_def_values->len * sizeof(liOptionPtrValue*), srv->optionptr_def_values->data);
{
guint i;
for (i = 0; i < srv->optionptr_def_values->len; i++) {
if (vr->optionptrs[i]) {
g_atomic_int_inc(&vr->optionptrs[i]->refcount);
}
}
}
li_request_init(&vr->request);
li_physical_init(&vr->physical);
@ -188,6 +197,8 @@ liVRequest* li_vrequest_new(liConnection *con, liVRequestHandlerCB handle_respon
}
void li_vrequest_free(liVRequest* vr) {
liServer *srv = vr->wrk->srv;
li_action_stack_clear(vr, &vr->action_stack);
li_plugins_handle_vrclose(vr);
g_ptr_array_free(vr->plugin_ctx, TRUE);
@ -207,7 +218,14 @@ void li_vrequest_free(liVRequest* vr) {
g_atomic_int_set(&vr->queued, 0);
}
g_slice_free1(vr->wrk->srv->option_def_values->len * sizeof(liOptionValue), vr->options);
g_slice_free1(srv->option_def_values->len * sizeof(liOptionValue), vr->options);
{
guint i;
for (i = 0; i < srv->optionptr_def_values->len; i++) {
li_release_optionptr(srv, vr->optionptrs[i]);
}
}
g_slice_free1(srv->optionptr_def_values->len * sizeof(liOptionPtrValue*), vr->optionptrs);
while (vr->stat_cache_entries->len > 0 ) {
@ -225,6 +243,8 @@ void li_vrequest_free(liVRequest* vr) {
}
void li_vrequest_reset(liVRequest *vr, gboolean keepalive) {
liServer *srv = vr->wrk->srv;
li_action_stack_reset(vr, &vr->action_stack);
li_plugins_handle_vrclose(vr);
{
@ -266,7 +286,18 @@ void li_vrequest_reset(liVRequest *vr, gboolean keepalive) {
li_stat_cache_entry_release(vr, sce);
}
memcpy(vr->options, vr->wrk->srv->option_def_values->data, vr->wrk->srv->option_def_values->len * sizeof(liOptionValue));
memcpy(vr->options, srv->option_def_values->data, srv->option_def_values->len * sizeof(liOptionValue));
{
guint i;
for (i = 0; i < srv->optionptr_def_values->len; i++) {
liOptionPtrValue *oval = g_array_index(srv->optionptr_def_values, liOptionPtrValue*, i);
if (vr->optionptrs[i] != oval) {
li_release_optionptr(srv, vr->optionptrs[i]);
g_atomic_int_inc(&oval->refcount);
vr->optionptrs[i] = oval;
}
}
}
if (1 != g_atomic_int_get(&vr->ref->refcount)) {
/* If we are not the only user of vr->ref we have to get a new one and detach the old */

25
src/modules/mod_access.c

@ -55,14 +55,21 @@ struct access_check_data {
};
typedef struct access_check_data access_check_data;
enum { ACCESS_DENY = 1, ACCESS_ALLOW = 2 } access_values;
enum { ACCESS_DENY = 1, ACCESS_ALLOW = 2 };
enum {
OPTION_LOG_BLOCKED = 0
};
enum {
OPTION_REDIRECT_URL = 0
};
static liHandlerResult access_check(liVRequest *vr, gpointer param, gpointer *context) {
access_check_data *acd = param;
liSockAddr *addr = vr->con->remote_addr.addr;
gboolean log_blocked = _OPTION(vr, acd->p, 0).boolean;
GString *redirect_url = _OPTION(vr, acd->p, 1).string;
gboolean log_blocked = _OPTION(vr, acd->p, OPTION_LOG_BLOCKED).boolean;
GString *redirect_url = _OPTIONPTR(vr, acd->p, OPTION_REDIRECT_URL).string;
UNUSED(context);
UNUSED(redirect_url);
@ -202,8 +209,8 @@ failed_free_acd:
static liHandlerResult access_deny(liVRequest *vr, gpointer param, gpointer *context) {
gboolean log_blocked = _OPTION(vr, ((liPlugin*)param), 0).boolean;
GString *redirect_url = _OPTION(vr, ((liPlugin*)param), 1).string;
gboolean log_blocked = _OPTION(vr, ((liPlugin*)param), OPTION_LOG_BLOCKED).boolean;
GString *redirect_url = _OPTIONPTR(vr, ((liPlugin*)param), OPTION_REDIRECT_URL).string;
UNUSED(context);
UNUSED(redirect_url);
@ -233,7 +240,12 @@ static liAction* access_deny_create(liServer *srv, liPlugin* p, liValue *val, gp
static const liPluginOption options[] = {
{ "access.log_blocked", LI_VALUE_BOOLEAN, NULL, NULL, NULL },
{ "access.log_blocked", LI_VALUE_BOOLEAN, 0, NULL },
{ NULL, 0, 0, NULL }
};
static const liPluginOptionPtr optionptrs[] = {
{ "access.redirect_url", LI_VALUE_STRING, NULL, NULL, NULL },
{ NULL, 0, NULL, NULL, NULL }
@ -255,6 +267,7 @@ static void plugin_access_init(liServer *srv, liPlugin *p, gpointer userdata) {
UNUSED(srv); UNUSED(userdata);
p->options = options;
p->optionptrs = optionptrs;
p->actions = actions;
p->setups = setups;
}

45
src/modules/mod_accesslog.c

@ -43,7 +43,7 @@ struct al_data {
typedef struct al_data al_data;
enum {
AL_OPTION_ACCESSLOG,
AL_OPTION_ACCESSLOG = 0,
AL_OPTION_ACCESSLOG_FORMAT
};
@ -339,8 +339,8 @@ static GString *al_format_log(liVRequest *vr, al_data *ald, GArray *format) {
g_string_append_len(str, GSTR_LEN(req->uri.path));
break;
case AL_FORMAT_SERVER_NAME:
if (CORE_OPTION(LI_CORE_OPTION_SERVER_NAME).string)
g_string_append_len(str, GSTR_LEN(CORE_OPTION(LI_CORE_OPTION_SERVER_NAME).string));
if (CORE_OPTIONPTR(LI_CORE_OPTION_SERVER_NAME).string)
g_string_append_len(str, GSTR_LEN(CORE_OPTIONPTR(LI_CORE_OPTION_SERVER_NAME).string));
else
g_string_append_len(str, GSTR_LEN(req->uri.host));
break;
@ -386,8 +386,8 @@ static void al_handle_vrclose(liVRequest *vr, liPlugin *p) {
/* VRequest closed, log it */
GString *msg;
liResponse *resp = &vr->response;
liLog *log = OPTION(AL_OPTION_ACCESSLOG).ptr;
GArray *format = OPTION(AL_OPTION_ACCESSLOG_FORMAT).list;
liLog *log = OPTIONPTR(AL_OPTION_ACCESSLOG).ptr;
GArray *format = OPTIONPTR(AL_OPTION_ACCESSLOG_FORMAT).list;
UNUSED(p);
@ -403,16 +403,16 @@ static void al_handle_vrclose(liVRequest *vr, liPlugin *p) {
static void al_option_accesslog_free(liServer *srv, liPlugin *p, size_t ndx, liOptionValue oval) {
static void al_option_accesslog_free(liServer *srv, liPlugin *p, size_t ndx, gpointer oval) {
UNUSED(p);
UNUSED(ndx);
if (!oval.ptr) return;
if (!oval) return;
li_log_unref(srv, oval.ptr);
li_log_unref(srv, oval);
}
static gboolean al_option_accesslog_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, liOptionValue *oval) {
static gboolean al_option_accesslog_parse(liServer *srv, liPlugin *p, size_t ndx, liValue *val, gpointer *oval) {