static liAction* redirect_create(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) {
	redirect_data *rd;
	UNUSED(wrk); UNUSED(userdata);

	val = li_value_get_single_argument(val);

	if (LI_VALUE_STRING != li_value_type(val) && LI_VALUE_LIST != li_value_type(val)) {
		ERROR(srv, "%s", "redirect expects a either a string, a tuple of strings or a list of string tuples");
		return NULL;
	}

	rd = g_slice_new(redirect_data);
	rd->p = p;
	rd->rules = g_array_new(FALSE, FALSE, sizeof(redirect_rule));

	if (LI_VALUE_STRING == li_value_type(val)) {
		redirect_rule rule;

		/* redirect "/foo/bar"; */
		if (!redirect_rule_parse(srv, NULL, val->data.string, &rule)) {
			redirect_free(NULL, rd);
			return NULL;
		}

		g_array_append_val(rd->rules, rule);
	} else if (li_value_list_has_len(val, 2) && LI_VALUE_STRING == li_value_list_type_at(val, 0) && LI_VALUE_STRING == li_value_list_type_at(val, 1)) {
		redirect_rule rule;

		/* only one rule */
		if (!redirect_rule_parse(srv, li_value_list_at(val, 0)->data.string, li_value_list_at(val, 1)->data.string, &rule)) {
			redirect_free(NULL, rd);
			return NULL;
		}

		g_array_append_val(rd->rules, rule);
	} else {
		/* probably multiple rules */
		LI_VALUE_FOREACH(v, val)
			redirect_rule rule;

			if (!li_value_list_has_len(v, 2)
					|| LI_VALUE_STRING != li_value_list_type_at(v, 0) || LI_VALUE_STRING != li_value_list_type_at(v, 1)) {
				redirect_free(NULL, rd);
				ERROR(srv, "%s", "redirect expects a either a tuple of strings or a list of those");
				return NULL;
			}

			if (!redirect_rule_parse(srv, li_value_list_at(v, 0)->data.string, li_value_list_at(v, 1)->data.string, &rule)) {
				redirect_free(NULL, rd);
				return NULL;
			}

			g_array_append_val(rd->rules, rule);
		LI_VALUE_END_FOREACH()
	}

	return li_action_new_function(redirect, NULL, redirect_free, rd);
}
Exemple #2
0
static liAction* mod_limit_action_create(liServer *srv, liPlugin *p, mod_limit_context_type type, liValue *val) {
	const char* act_names[] = { "limit.con", "limit.con_ip", "limit.req", "limit.req_ip" };
	mod_limit_context *ctx;
	gint limit = 0;
	liAction *action_limit_reached = NULL;

	val = li_value_get_single_argument(val);
	val = li_value_get_single_argument(val);

	if (LI_VALUE_NUMBER == li_value_type(val) && val->data.number > 0) {
		/* limit.* N; */
		limit = val->data.number;
		action_limit_reached = NULL;
	} else if (LI_VALUE_LIST == li_value_type(val)
			&& li_value_list_has_len(val, 2)
			&& LI_VALUE_NUMBER == li_value_list_type_at(val, 0)
			&& li_value_list_at(val, 0)->data.number > 0
			&& LI_VALUE_ACTION == li_value_list_type_at(val, 1)) {

		limit = li_value_list_at(val, 0)->data.number;
		action_limit_reached = li_value_extract_action(li_value_list_at(val, 1));
	} else {
		ERROR(srv, "%s expects either an integer > 0 as parameter, or a list of (int > 0,action)", act_names[type]);
		return NULL;
	}

	ctx = mod_limit_context_new(type, limit, action_limit_reached, p);

	return li_action_new_function(mod_limit_action_handle, NULL, mod_limit_action_free, ctx);
}
static liAction* core_throttle_connection(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) {
	liThrottleParam *param;
	guint64 rate, burst;
	UNUSED(wrk); UNUSED(p); UNUSED(userdata);

	val = li_value_get_single_argument(val);
	val = li_value_get_single_argument(val);

	if (li_value_list_has_len(val, 2)) {
		liValue *v1 = li_value_list_at(val, 0);
		liValue *v2 = li_value_list_at(val, 1);

		if (LI_VALUE_NUMBER != li_value_type(v1) || LI_VALUE_NUMBER != li_value_type(v2)) {
			ERROR(srv, "%s", "'io.throttle' action expects a positiv integer or a pair of those as parameter");
			return NULL;
		}

		rate = v2->data.number;
		burst = v1->data.number;
	} else if (LI_VALUE_NUMBER == li_value_type(val)) {
		rate = val->data.number;
		burst  = 2 * rate;
	} else {
		ERROR(srv, "'io.throttle' action expects a positiv integer or a pair of those as parameter, %s given", li_value_type_string(val));
		return NULL;
	}

	if ((rate != 0 || burst != 0) && !sanity_check(srv, rate, burst)) return NULL;

	param = g_slice_new(liThrottleParam);
	param->rate = rate;
	param->burst = burst;

	return li_action_new_function(core_handle_throttle_connection, NULL, core_throttle_connection_free, param);
}
Exemple #4
0
static gboolean balancer_fill_backends(balancer *b, liServer *srv, liValue *val) {
	val = li_value_get_single_argument(val);

	if (LI_VALUE_ACTION == li_value_type(val)) {
		backend be;
		be.act = val->data.val_action.action;
		be.load = 0; be.state = BE_ALIVE; be.wake = 0;
		assert(srv == val->data.val_action.srv);
		li_action_acquire(be.act);
		g_array_append_val(b->backends, be);
		return TRUE;
	} else if (LI_VALUE_LIST == li_value_type(val)) {
		if (li_value_list_has_len(val, 0)) {
			ERROR(srv, "%s", "expected non-empty list");
			return FALSE;
		}
		LI_VALUE_FOREACH(oa, val)
			if (LI_VALUE_ACTION != li_value_type(oa)) {
				ERROR(srv, "expected action at entry %u of list, got %s", _oa_i, li_value_type_string(oa));
				return FALSE;
			}
			assert(srv == oa->data.val_action.srv);
			{
				backend be;
				be.act = oa->data.val_action.action;
				be.load = 0; be.state = BE_ALIVE; be.wake = 0;
				li_action_acquire(be.act);
				g_array_append_val(b->backends, be);
			}
		LI_VALUE_END_FOREACH()
		return TRUE;
	} else {
Exemple #5
0
liValue* li_value_to_key_value_list(liValue *val) {
	if (NULL == val) return NULL;

	if (LI_VALUE_LIST == val->type) {
		if (li_value_list_has_len(val, 2) &&
				(LI_VALUE_STRING == li_value_list_type_at(val, 0) || LI_VALUE_NONE == li_value_list_type_at(val, 0))) {
			/* single key-value pair */
			li_value_wrap_in_list(val);
			return val;
		}

		/* verify key-value list properties */
		LI_VALUE_FOREACH(lentry, val)
			if (!li_value_list_has_len(lentry, 2)) return NULL;
			if (LI_VALUE_STRING != li_value_list_type_at(lentry, 0) && LI_VALUE_NONE != li_value_list_type_at(lentry, 0)) return NULL;
		LI_VALUE_END_FOREACH()
		return val;
	}
	return NULL;
}
Exemple #6
0
static liValue* option_value(liValue *val) {
	if (li_value_list_has_len(val, 1)) return li_value_list_at(val, 0);
	if (li_value_list_has_len(val, 0)) return NULL;
	return val;
}