2
0
Fork 0

Redo boolean conditionals (physical.*) as real actions.

personal/stbuehler/wip
Stefan Bühler 2009-01-10 14:46:11 +01:00
parent 587ee27cd0
commit 4a8ce0a63f
6 changed files with 160 additions and 11 deletions

View File

@ -26,6 +26,7 @@ struct value {
} data;
};
LI_API value* value_new_none();
LI_API value* value_new_bool(gboolean val);
LI_API value* value_new_number(gint64 val);
LI_API value* value_new_string(GString *val);

View File

@ -263,7 +263,7 @@ handler_t action_execute(vrequest *vr) {
case HANDLER_GO_ON:
action_stack_pop(srv, vr, as);
if (condres) {
action_enter(vr, a->data.condition.target);
if (a->data.condition.target) action_enter(vr, a->data.condition.target);
}
else if (a->data.condition.target_else) {
action_enter(vr, a->data.condition.target_else);

View File

@ -44,7 +44,7 @@ static action* core_list(server *srv, plugin* p, value *val) {
static action* core_when(server *srv, plugin* p, value *val) {
value *val_cond, *val_act, *val_act_else;
action *a, *act_else;
action *a, *act = NULL, *act_else = NULL;
UNUSED(p);
if (!val) {
@ -60,7 +60,6 @@ static action* core_when(server *srv, plugin* p, value *val) {
act_else = NULL;
} else if (val->data.list->len == 3) {
val_act_else = g_array_index(val->data.list, value*, 2);
act_else = val_act_else->data.val_action.action;
} else {
ERROR(srv, "expected list with length 2 or 3, has length %u", val->data.list->len);
return NULL;
@ -72,18 +71,28 @@ static action* core_when(server *srv, plugin* p, value *val) {
ERROR(srv, "expected condition as first parameter, got %s", value_type_string(val_cond->type));
return NULL;
}
if (val_act->type != VALUE_ACTION) {
if (val_act->type == VALUE_NONE) {
act = NULL;
} else if (val_act->type == VALUE_ACTION) {
act = val_act->data.val_action.action;
} else {
ERROR(srv, "expected action as second parameter, got %s", value_type_string(val_act->type));
return NULL;
}
if (val_act_else && val_act_else->type != VALUE_ACTION) {
ERROR(srv, "expected action as third parameter, got %s", value_type_string(val_act_else->type));
return NULL;
if (val_act_else) {
if (val_act_else->type == VALUE_NONE) {
act_else = NULL;
} else if (val_act_else->type == VALUE_ACTION) {
act_else = val_act_else->data.val_action.action;
} else {
ERROR(srv, "expected action as third parameter, got %s", value_type_string(val_act_else->type));
return NULL;
}
}
condition_acquire(val_cond->data.val_cond.cond);
action_acquire(val_act->data.val_action.action);
if (act) action_acquire(act);
if (act_else) action_acquire(act_else);
a = action_new_condition(val_cond->data.val_cond.cond, val_act->data.val_action.action, act_else);
a = action_new_condition(val_cond->data.val_cond.cond, act, act_else);
return a;
}
@ -782,6 +791,125 @@ static action* core_header_overwrite(server *srv, plugin* p, value *val) {
return action_new_function(core_handle_header_overwrite, NULL, core_header_free, value_extract(val).list);
}
typedef struct {
action *target_true, *target_false;
} core_conditional;
static core_conditional* core_conditional_create(server *srv, value *val, guint idx) {
core_conditional *cc;
value *val_true = NULL, *val_false = NULL;
action *act_true = NULL, *act_false = NULL;
GArray *l;
if (idx == 0 && val->type == VALUE_ACTION) {
cc = g_slice_new0(core_conditional);
act_true = val->data.val_action.action;
action_acquire(act_true);
cc->target_true = act_true;
return cc;
}
if (val->type != VALUE_LIST) {
ERROR(srv, "unexpected parameter of type %s, expected list", value_type_string(val->type));
return NULL;
}
l = val->data.list;
if (idx >= l->len) {
ERROR(srv, "expected at least %u parameters, %u given", idx+1, l->len);
}
val_true = g_array_index(l, value*, idx);
if (idx + 1 < l->len) val_false = g_array_index(l, value*, idx+1);
if (val_true->type == VALUE_NONE) {
act_true = NULL;
} else if (val_true->type == VALUE_ACTION) {
act_true = val_true->data.val_action.action;
} else {
ERROR(srv, "expected action at entry %u of list, got %s", idx, value_type_string(val_true->type));
}
if (val_false) {
if (val_false->type == VALUE_NONE) {
act_false = NULL;
} else if (val_false->type == VALUE_ACTION) {
act_false = val_false->data.val_action.action;
} else {
ERROR(srv, "expected action at entry %u of list, got %s", idx+1, value_type_string(val_false->type));
}
} else {
act_false = NULL;
}
cc = g_slice_new0(core_conditional);
if (act_true) action_acquire(act_true);
if (act_false) action_acquire(act_false);
cc->target_true = act_true;
cc->target_false = act_false;
return cc;
}
static void core_conditional_free(struct server *srv, gpointer param) {
core_conditional *cc = (core_conditional*) param;
if (!cc) return;
action_release(srv, cc->target_true);
action_release(srv, cc->target_false);
g_slice_free(core_conditional, cc);
}
static handler_t core_conditional_do(vrequest *vr, gpointer param, gboolean way) {
core_conditional *cc = (core_conditional*)param;
if (way) { if (cc->target_true) action_enter(vr, cc->target_true); }
else { if (cc->target_false) action_enter(vr, cc->target_false); }
return HANDLER_GO_ON;
}
static handler_t core_handle_physical_exists(vrequest *vr, gpointer param, gpointer *context) {
UNUSED(context);
if (0 == vr->physical.path->len) return core_conditional_do(vr, param, FALSE);
vrequest_stat(vr);
return core_conditional_do(vr, param, vr->physical.have_stat);
}
static action* core_physical_exists(server *srv, plugin* p, value *val) {
core_conditional *cc = core_conditional_create(srv, val, 0);
UNUSED(p);
if (!cc) return NULL;
return action_new_function(core_handle_physical_exists, NULL, core_conditional_free, cc);
}
static handler_t core_handle_physical_is_file(vrequest *vr, gpointer param, gpointer *context) {
UNUSED(context);
if (0 == vr->physical.path->len) return core_conditional_do(vr, param, FALSE);
vrequest_stat(vr);
return core_conditional_do(vr, param, vr->physical.have_stat && S_ISREG(vr->physical.stat.st_mode));
}
static action* core_physical_is_file(server *srv, plugin* p, value *val) {
core_conditional *cc = core_conditional_create(srv, val, 0);
UNUSED(p);
if (!cc) return NULL;
return action_new_function(core_handle_physical_is_file, NULL, core_conditional_free, cc);
}
static handler_t core_handle_physical_is_dir(vrequest *vr, gpointer param, gpointer *context) {
UNUSED(context);
if (0 == vr->physical.path->len) return core_conditional_do(vr, param, FALSE);
vrequest_stat(vr);
return core_conditional_do(vr, param, vr->physical.have_stat && S_ISDIR(vr->physical.stat.st_mode));
}
static action* core_physical_is_dir(server *srv, plugin* p, value *val) {
core_conditional *cc = core_conditional_create(srv, val, 0);
UNUSED(p);
if (!cc) return NULL;
return action_new_function(core_handle_physical_is_dir, NULL, core_conditional_free, cc);
}
static const plugin_option options[] = {
{ "debug.log_request_handling", VALUE_BOOLEAN, NULL, NULL, NULL },
@ -821,6 +949,10 @@ static const plugin_action actions[] = {
{ "header_append", core_header_append },
{ "header_overwrite", core_header_overwrite },
{ "physical.exists", core_physical_exists },
{ "physical.is_file", core_physical_is_file },
{ "physical.is_dir", core_physical_is_dir },
{ NULL, NULL }
};

View File

@ -1,5 +1,11 @@
#include <lighttpd/base.h>
value* value_new_none() {
value *v = g_slice_new0(value);
v->type = VALUE_NONE;
return v;
}
value* value_new_bool(gboolean val) {
value *v = g_slice_new0(value);
v->data.boolean = val;

View File

@ -86,7 +86,7 @@ value* value_from_lua(server *srv, lua_State *L) {
switch (lua_type(L, -1)) {
case LUA_TNIL:
lua_pop(L, 1);
return NULL;
return value_new_none();
case LUA_TBOOLEAN:
val = value_new_bool(lua_toboolean(L, -1));

View File

@ -352,11 +352,21 @@ void vrequest_joblist_append(vrequest *vr) {
}
gboolean vrequest_stat(vrequest *vr) {
/* Do not stat again */
if (vr->physical.have_stat || vr->physical.have_errno) return vr->physical.have_stat;
if (-1 == stat(vr->physical.path->str, &vr->physical.stat)) {
vr->physical.have_stat = FALSE;
vr->physical.have_errno = TRUE;
vr->physical.stat_errno = errno;
VR_DEBUG(vr, "stat(%s) failed: %s (%d)", vr->physical.path->str, g_strerror(vr->physical.stat_errno), vr->physical.stat_errno);
switch (errno) {
case EACCES:
case ENOENT:
case ENOTDIR:
break;
default:
VR_DEBUG(vr, "stat(%s) failed: %s (%d)", vr->physical.path->str, g_strerror(vr->physical.stat_errno), vr->physical.stat_errno);
}
return FALSE;
}