[plugin_core] Enable 'docroot' action to use patterns and even traverse a list of these

personal/stbuehler/wip
Thomas Porzelt 13 years ago
parent 3668ef97ab
commit 7409b2ef63

@ -151,14 +151,79 @@ static gboolean core_setup_set(liServer *srv, liPlugin* p, liValue *val, gpointe
return li_plugin_set_default_option(srv, val_name->data.string->str, val_val);
}
static void core_docroot_nth_cb(GString *pattern_result, guint8 nth_ndx, gpointer data) {
/* $n means n-th part of hostname from end divided by dots */
gchar *c, *end;
guint i = 0;
GString *str = data;
if (nth_ndx == 0) {
g_string_append_len(pattern_result, GSTR_LEN(str));
return;
}
end = str->str + str->len - 1;
for (c = end; c > str->str; c--) {
if (*c == '.') {
i++;
if (i == nth_ndx) {
g_string_append_len(pattern_result, c+1, end - c);
return;
}
end = c-1;
}
}
}
static liHandlerResult core_handle_docroot(liVRequest *vr, gpointer param, gpointer *context) {
UNUSED(context);
guint i;
GMatchInfo *match_info = NULL;
GArray *arr = param;
g_string_truncate(vr->physical.doc_root, 0);
g_string_append_len(vr->physical.doc_root, GSTR_LEN((GString*) param));
if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
VR_DEBUG(vr, "docroot: %s", vr->physical.doc_root->str);
if (vr->action_stack.regex_stack->len) {
GArray *rs = vr->action_stack.regex_stack;
match_info = g_array_index(rs, liActionRegexStackElement, rs->len - 1).match_info;
}
/* resume from last stat check */
if (*context) {
i = GPOINTER_TO_INT(*context);
} else {
i = 0;
}
/* loop over all the patterns until we find an existing path */
for (; i < arr->len; i++) {
struct stat st;
gint err;
g_string_truncate(vr->physical.doc_root, 0);
li_pattern_eval(vr, vr->physical.doc_root, g_array_index(arr, liPattern*, i), core_docroot_nth_cb, vr->request.uri.host, li_pattern_regex_cb, match_info);
/* check if path exists */
switch (li_stat_cache_get(vr, vr->physical.doc_root, &st, &err, NULL)) {
case LI_HANDLER_GO_ON: break;
case LI_HANDLER_WAIT_FOR_EVENT:
*context = GINT_TO_POINTER(i);
if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
VR_DEBUG(vr, "docroot: waiting for async: \"%s\"", vr->physical.doc_root->str);
}
return LI_HANDLER_WAIT_FOR_EVENT;
default:
/* not found, try next pattern */
if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
VR_DEBUG(vr, "docroot: not found: \"%s\", trying next", vr->physical.doc_root->str);
}
continue;
}
*context = NULL;
}
/* build physical path: docroot + uri.path */
@ -169,25 +234,57 @@ static liHandlerResult core_handle_docroot(liVRequest *vr, gpointer param, gpoin
g_string_append_len(vr->physical.path, GSTR_LEN(vr->request.uri.path));
if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
VR_DEBUG(vr, "physical path: %s", vr->physical.path->str);
VR_DEBUG(vr, "docroot: \"%s\"", vr->physical.doc_root->str);
VR_DEBUG(vr, "physical path: \"%s\"", vr->physical.path->str);
}
return LI_HANDLER_GO_ON;
}
static void core_docroot_free(liServer *srv, gpointer param) {
guint i;
GArray *arr = param;
UNUSED(srv);
g_string_free(param, TRUE);
for (i = 0; i < arr->len; i++) {
li_pattern_free(g_array_index(arr, liPattern*, i));
}
}
static liAction* core_docroot(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) {
GArray *arr;
guint i;
liValue *v;
liPattern *pattern;
UNUSED(wrk); UNUSED(p); UNUSED(userdata);
if (!val || val->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "docroot action expects a string parameter");
if (!val || (val->type != LI_VALUE_STRING && val->type != LI_VALUE_LIST)) {
ERROR(srv, "%s", "docroot action expects a string or list of strings as parameter");
return NULL;
}
return li_action_new_function(core_handle_docroot, NULL, core_docroot_free, li_value_extract_string(val));
arr = g_array_new(FALSE, TRUE, sizeof(liPattern*));
if (val->type == LI_VALUE_STRING) {
pattern = li_pattern_new(val->data.string->str);
g_array_append_val(arr, pattern);
} else {
for (i = 0; i < val->data.list->len; i++) {
v = g_array_index(val->data.list, liValue*, i);
if (v->type != LI_VALUE_STRING) {
core_docroot_free(srv, arr);
return NULL;
}
pattern = li_pattern_new(v->data.string->str);
g_array_append_val(arr, pattern);
}
}
return li_action_new_function(core_handle_docroot, NULL, core_docroot_free, arr);
}
typedef struct {

Loading…
Cancel
Save