2008-11-16 20:33:53 +00:00
|
|
|
#include <lighttpd/base.h>
|
2008-06-29 15:48:28 +00:00
|
|
|
|
2009-12-19 16:41:55 +00:00
|
|
|
#if 0
|
|
|
|
static const liConditionValueType cond_value_hints[] = {
|
|
|
|
/* LI_COMP_REQUEST_LOCALIP: */ LI_COND_VALUE_HINT_SOCKADDR,
|
2010-02-21 12:45:20 +00:00
|
|
|
/* LI_COMP_REQUEST_LOCALPORT: */ LI_COND_VALUE_HINT_NUMBER,
|
2009-12-19 16:41:55 +00:00
|
|
|
/* LI_COMP_REQUEST_REMOTEIP: */ LI_COND_VALUE_HINT_SOCKADDR,
|
2010-02-21 12:45:20 +00:00
|
|
|
/* LI_COMP_REQUEST_REMOTEPORT: */ LI_COND_VALUE_HINT_NUMBER,
|
2009-12-19 16:41:55 +00:00
|
|
|
/* LI_COMP_REQUEST_PATH: */ LI_COND_VALUE_HINT_STRING,
|
2014-06-06 09:16:22 +00:00
|
|
|
/* LI_COMP_REQUEST_RAW_PATH: */ LI_COND_VALUE_HINT_STRING,
|
2009-12-19 16:41:55 +00:00
|
|
|
/* LI_COMP_REQUEST_HOST: */ LI_COND_VALUE_HINT_ANY,
|
|
|
|
/* LI_COMP_REQUEST_SCHEME: */ LI_COND_VALUE_HINT_STRING,
|
|
|
|
/* LI_COMP_REQUEST_QUERY_STRING: */ LI_COND_VALUE_HINT_ANY,
|
|
|
|
/* LI_COMP_REQUEST_METHOD: */ LI_COND_VALUE_HINT_STRING,
|
|
|
|
/* LI_COMP_REQUEST_CONTENT_LENGTH: */ LI_COND_VALUE_HINT_NUMBER,
|
|
|
|
/* LI_COMP_REQUEST_IS_HANDLED: */ LI_COND_VALUE_HINT_BOOL,
|
|
|
|
/* LI_COMP_PHYSICAL_PATH: */ LI_COND_VALUE_HINT_STRING,
|
|
|
|
/* LI_COMP_PHYSICAL_EXISTS: */ LI_COND_VALUE_HINT_BOOL,
|
|
|
|
/* LI_COMP_PHYSICAL_SIZE: */ LI_COND_VALUE_HINT_NUMBER,
|
|
|
|
/* LI_COMP_PHYSICAL_ISDIR: */ LI_COND_VALUE_HINT_BOOL,
|
|
|
|
/* LI_COMP_PHYSICAL_ISFILE: */ LI_COND_VALUE_HINT_BOOL,
|
|
|
|
/* LI_COMP_RESPONSE_STATUS: */ LI_COND_VALUE_HINT_NUMBER,
|
2010-10-05 11:57:26 +00:00
|
|
|
/* LI_COMP_PHYSICAL_DOCROOT: */ LI_COND_VALUE_HINT_STRING,
|
|
|
|
/* LI_COMP_PHYSICAL_PATHINFO: */ LI_COND_VALUE_HINT_STRING,
|
2009-12-19 16:41:55 +00:00
|
|
|
|
|
|
|
/* LI_COMP_REQUEST_HEADER: */ LI_COND_VALUE_HINT_ANY,
|
|
|
|
/* LI_COMP_RESPONSE_HEADER: */ LI_COND_VALUE_HINT_ANY,
|
|
|
|
/* LI_COMP_ENVIRONMENT: */ LI_COND_VALUE_HINT_ANY,
|
|
|
|
|
|
|
|
/* LI_COMP_UNKNOWN: */ LI_COND_VALUE_HINT_ANY
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2010-10-07 13:58:46 +00:00
|
|
|
/* uses tmpstr for temporary (and returned) strings */
|
|
|
|
liHandlerResult li_condition_get_value(GString *tmpstr, liVRequest *vr, liConditionLValue *lvalue, liConditionValue *res, liConditionValueType prefer) {
|
2010-07-31 12:44:45 +00:00
|
|
|
liConInfo *coninfo = vr->coninfo;
|
2009-12-19 16:41:55 +00:00
|
|
|
liHandlerResult r;
|
|
|
|
struct stat st;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_ANY;
|
|
|
|
res->data.str = "";
|
|
|
|
|
|
|
|
switch (lvalue->type) {
|
|
|
|
case LI_COMP_REQUEST_LOCALIP:
|
|
|
|
if (prefer == LI_COND_VALUE_HINT_STRING) {
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.str = coninfo->local_addr_str->str;
|
2009-12-19 16:41:55 +00:00
|
|
|
} else {
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_SOCKADDR;
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.addr = coninfo->local_addr;
|
2009-12-19 16:41:55 +00:00
|
|
|
}
|
|
|
|
break;
|
2010-02-21 12:45:20 +00:00
|
|
|
case LI_COMP_REQUEST_LOCALPORT:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_NUMBER;
|
2010-07-31 12:44:45 +00:00
|
|
|
switch (coninfo->local_addr.addr->plain.sa_family) {
|
2010-02-21 12:45:20 +00:00
|
|
|
case AF_INET:
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.number = ntohs(coninfo->local_addr.addr->ipv4.sin_port);
|
2010-02-21 12:45:20 +00:00
|
|
|
break;
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
case AF_INET6:
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.number = ntohs(coninfo->local_addr.addr->ipv6.sin6_port);
|
2010-02-21 12:45:20 +00:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
res->data.number = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COMP_REQUEST_REMOTEIP:
|
|
|
|
if (prefer == LI_COND_VALUE_HINT_STRING) {
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.str = coninfo->remote_addr_str->str;
|
2009-12-19 16:41:55 +00:00
|
|
|
} else {
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_SOCKADDR;
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.addr = coninfo->remote_addr;
|
2009-12-19 16:41:55 +00:00
|
|
|
}
|
|
|
|
break;
|
2010-02-21 12:45:20 +00:00
|
|
|
case LI_COMP_REQUEST_REMOTEPORT:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_NUMBER;
|
2010-07-31 12:44:45 +00:00
|
|
|
switch (coninfo->remote_addr.addr->plain.sa_family) {
|
2010-02-21 12:45:20 +00:00
|
|
|
case AF_INET:
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.number = ntohs(coninfo->remote_addr.addr->ipv4.sin_port);
|
2010-02-21 12:45:20 +00:00
|
|
|
break;
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
case AF_INET6:
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.number = ntohs(coninfo->remote_addr.addr->ipv6.sin6_port);
|
2010-02-21 12:45:20 +00:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
res->data.number = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COMP_REQUEST_PATH:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
|
|
|
res->data.str = vr->request.uri.path->str;
|
|
|
|
break;
|
2014-06-06 09:16:22 +00:00
|
|
|
case LI_COMP_REQUEST_RAW_PATH:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
|
|
|
res->data.str = vr->request.uri.raw_path->str;
|
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COMP_REQUEST_HOST:
|
2010-08-08 21:54:08 +00:00
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
2009-12-19 16:41:55 +00:00
|
|
|
res->data.str = vr->request.uri.host->str;
|
|
|
|
break;
|
|
|
|
case LI_COMP_REQUEST_SCHEME:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
2010-07-31 12:44:45 +00:00
|
|
|
res->data.str = coninfo->is_ssl ? "https" : "http";
|
2009-12-19 16:41:55 +00:00
|
|
|
break;
|
|
|
|
case LI_COMP_REQUEST_QUERY_STRING:
|
|
|
|
res->data.str = vr->request.uri.query->str;
|
|
|
|
break;
|
|
|
|
case LI_COMP_REQUEST_METHOD:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
|
|
|
res->data.str = vr->request.http_method_str->str;
|
|
|
|
break;
|
|
|
|
case LI_COMP_REQUEST_CONTENT_LENGTH:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_NUMBER;
|
|
|
|
res->data.number = vr->request.content_length;
|
|
|
|
break;
|
|
|
|
case LI_COMP_REQUEST_IS_HANDLED:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_BOOL;
|
|
|
|
res->data.bool = li_vrequest_is_handled(vr);
|
|
|
|
break;
|
|
|
|
case LI_COMP_PHYSICAL_PATH:
|
2010-08-08 21:54:08 +00:00
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
2009-12-19 16:41:55 +00:00
|
|
|
res->data.str = vr->physical.path->str;
|
|
|
|
break;
|
|
|
|
case LI_COMP_PHYSICAL_EXISTS:
|
|
|
|
case LI_COMP_PHYSICAL_ISDIR:
|
|
|
|
case LI_COMP_PHYSICAL_ISFILE:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_BOOL;
|
|
|
|
res->data.bool = FALSE;
|
|
|
|
if (vr->physical.path->len == 0) {
|
|
|
|
/* no file, return FALSE */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = li_stat_cache_get(vr, vr->physical.path, &st, &err, NULL);
|
|
|
|
if (r == LI_HANDLER_WAIT_FOR_EVENT) return r;
|
|
|
|
|
|
|
|
/* not found, return FALSE */
|
|
|
|
if (r != LI_HANDLER_GO_ON) break;
|
|
|
|
if (lvalue->type == LI_COMP_PHYSICAL_ISFILE) {
|
|
|
|
res->data.bool = S_ISREG(st.st_mode);
|
|
|
|
} else if (lvalue->type == LI_COMP_PHYSICAL_ISDIR) {
|
|
|
|
res->data.bool = S_ISDIR(st.st_mode);
|
|
|
|
} else {
|
|
|
|
res->data.bool = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case LI_COMP_PHYSICAL_SIZE:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_NUMBER;
|
|
|
|
res->data.number = -1;
|
|
|
|
if (vr->physical.path->len == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = li_stat_cache_get(vr, vr->physical.path, &st, &err, NULL);
|
|
|
|
if (r == LI_HANDLER_WAIT_FOR_EVENT) return r;
|
|
|
|
|
|
|
|
if (r == LI_HANDLER_GO_ON) { /* not found -> size "-1" */
|
|
|
|
res->data.number = (gint64) st.st_size;
|
|
|
|
}
|
|
|
|
break;
|
2010-10-05 11:57:26 +00:00
|
|
|
case LI_COMP_PHYSICAL_DOCROOT:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
|
|
|
res->data.str = vr->physical.doc_root->str;
|
|
|
|
break;
|
|
|
|
case LI_COMP_PHYSICAL_PATHINFO:
|
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
|
|
|
res->data.str = vr->physical.pathinfo->str;
|
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COMP_RESPONSE_STATUS:
|
2013-05-22 16:42:21 +00:00
|
|
|
LI_VREQUEST_WAIT_FOR_RESPONSE_HEADERS(vr);
|
2009-12-19 16:41:55 +00:00
|
|
|
res->match_type = LI_COND_VALUE_HINT_NUMBER;
|
|
|
|
res->data.number = vr->response.http_status;
|
|
|
|
break;
|
|
|
|
case LI_COMP_REQUEST_HEADER:
|
2010-08-08 21:54:08 +00:00
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
2010-10-07 13:58:46 +00:00
|
|
|
li_http_header_get_all(tmpstr, vr->request.headers, GSTR_LEN(lvalue->key));
|
|
|
|
res->data.str = tmpstr->str;
|
2009-12-19 16:41:55 +00:00
|
|
|
break;
|
|
|
|
case LI_COMP_RESPONSE_HEADER:
|
2013-05-22 16:42:21 +00:00
|
|
|
LI_VREQUEST_WAIT_FOR_RESPONSE_HEADERS(vr);
|
2010-08-08 21:54:08 +00:00
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
2010-10-07 13:58:46 +00:00
|
|
|
li_http_header_get_all(tmpstr, vr->response.headers, GSTR_LEN(lvalue->key));
|
|
|
|
res->data.str = tmpstr->str;
|
2009-12-19 16:41:55 +00:00
|
|
|
break;
|
|
|
|
case LI_COMP_ENVIRONMENT:
|
2010-08-08 21:54:08 +00:00
|
|
|
res->match_type = LI_COND_VALUE_HINT_STRING;
|
2009-12-19 16:41:55 +00:00
|
|
|
{
|
|
|
|
GString *eval = li_environment_get(&vr->env, GSTR_LEN(lvalue->key));
|
|
|
|
if (eval) res->data.str = eval->str;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
VR_ERROR(vr, "couldn't get value for '%s'", li_cond_lvalue_to_string(lvalue->type));
|
|
|
|
return LI_HANDLER_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LI_HANDLER_GO_ON;
|
|
|
|
}
|
|
|
|
|
2010-10-07 13:58:46 +00:00
|
|
|
gchar const* li_condition_value_to_string(GString *tmpstr, liConditionValue *value) {
|
2009-12-19 16:41:55 +00:00
|
|
|
switch (value->match_type) {
|
|
|
|
case LI_COND_VALUE_HINT_ANY:
|
|
|
|
case LI_COND_VALUE_HINT_STRING:
|
|
|
|
return value->data.str;
|
|
|
|
case LI_COND_VALUE_HINT_BOOL:
|
|
|
|
return value->data.bool ? "TRUE" : "FALSE";
|
|
|
|
case LI_COND_VALUE_HINT_NUMBER:
|
2013-05-22 16:42:21 +00:00
|
|
|
g_string_printf(tmpstr, "%"LI_GOFFSET_FORMAT, value->data.number);
|
2010-10-07 13:58:46 +00:00
|
|
|
return tmpstr->str;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COND_VALUE_HINT_SOCKADDR:
|
2010-10-07 13:58:46 +00:00
|
|
|
li_sockaddr_to_string(value->data.addr, tmpstr, TRUE);
|
|
|
|
return tmpstr->str;
|
2009-12-19 16:41:55 +00:00
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
static gboolean condition_parse_ip(liConditionRValue *val, const char *txt) {
|
2009-07-09 20:17:24 +00:00
|
|
|
if (li_parse_ipv4(txt, &val->ipv4.addr, NULL, NULL)) {
|
2009-07-08 19:06:07 +00:00
|
|
|
val->type = LI_COND_VALUE_SOCKET_IPV4;
|
2008-07-25 22:42:08 +00:00
|
|
|
val->ipv4.networkmask = 0xFFFFFFFF;
|
|
|
|
return TRUE;
|
|
|
|
}
|
2009-07-09 20:17:24 +00:00
|
|
|
if (li_parse_ipv6(txt, val->ipv6.addr, NULL, NULL)) {
|
2009-07-08 19:06:07 +00:00
|
|
|
val->type = LI_COND_VALUE_SOCKET_IPV6;
|
2008-07-25 22:42:08 +00:00
|
|
|
val->ipv6.network = 128;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
static gboolean condition_parse_ip_net(liConditionRValue *val, const char *txt) {
|
2009-07-09 20:17:24 +00:00
|
|
|
if (li_parse_ipv4(txt, &val->ipv4.addr, &val->ipv4.networkmask, NULL)) {
|
2009-07-08 19:06:07 +00:00
|
|
|
val->type = LI_COND_VALUE_SOCKET_IPV4;
|
2008-07-25 22:42:08 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2009-07-09 20:17:24 +00:00
|
|
|
if (li_parse_ipv6(txt, val->ipv6.addr, &val->ipv6.network, NULL)) {
|
2009-07-08 19:06:07 +00:00
|
|
|
val->type = LI_COND_VALUE_SOCKET_IPV6;
|
2008-07-25 22:42:08 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
static gboolean condition_ip_from_socket(liConditionRValue *val, liSockAddr *addr) {
|
2008-07-25 22:42:08 +00:00
|
|
|
switch (addr->plain.sa_family) {
|
|
|
|
case AF_INET:
|
2009-07-08 19:06:07 +00:00
|
|
|
val->type = LI_COND_VALUE_SOCKET_IPV4;
|
2008-07-25 22:42:08 +00:00
|
|
|
val->ipv4.addr = addr->ipv4.sin_addr.s_addr;
|
|
|
|
val->ipv4.networkmask = 0xFFFFFFFF;
|
|
|
|
return TRUE;
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
case AF_INET6:
|
2009-07-08 19:06:07 +00:00
|
|
|
val->type = LI_COND_VALUE_SOCKET_IPV6;
|
2008-07-25 22:42:08 +00:00
|
|
|
memcpy(val->ipv6.addr, addr->ipv6.sin6_addr.s6_addr, 16);
|
|
|
|
val->ipv6.network = 128;
|
|
|
|
return TRUE;
|
|
|
|
#endif
|
2008-11-19 23:13:51 +00:00
|
|
|
}
|
2008-07-25 22:42:08 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
liConditionLValue* li_condition_lvalue_new(liCondLValue type, GString *key) {
|
2009-07-08 19:06:07 +00:00
|
|
|
liConditionLValue *lvalue = g_slice_new0(liConditionLValue);
|
2009-09-28 19:30:06 +00:00
|
|
|
if (type == LI_COMP_REQUEST_HEADER || type == LI_COMP_RESPONSE_HEADER) g_string_ascii_down(key);
|
2008-07-25 12:09:03 +00:00
|
|
|
lvalue->type = type;
|
|
|
|
lvalue->key = key;
|
|
|
|
lvalue->refcount = 1;
|
|
|
|
return lvalue;
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
void li_condition_lvalue_acquire(liConditionLValue *lvalue) {
|
2014-04-10 16:08:59 +00:00
|
|
|
LI_FORCE_ASSERT(g_atomic_int_get(&lvalue->refcount) > 0);
|
2008-09-09 14:41:02 +00:00
|
|
|
g_atomic_int_inc(&lvalue->refcount);
|
2008-07-25 12:09:03 +00:00
|
|
|
}
|
2008-06-29 15:48:28 +00:00
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
void li_condition_lvalue_release(liConditionLValue *lvalue) {
|
2008-08-06 18:46:42 +00:00
|
|
|
if (!lvalue) return;
|
2014-04-10 16:08:59 +00:00
|
|
|
LI_FORCE_ASSERT(g_atomic_int_get(&lvalue->refcount) > 0);
|
2008-09-09 14:41:02 +00:00
|
|
|
if (g_atomic_int_dec_and_test(&lvalue->refcount)) {
|
2008-07-25 12:09:03 +00:00
|
|
|
if (lvalue->key) g_string_free(lvalue->key, TRUE);
|
2009-07-08 19:06:07 +00:00
|
|
|
g_slice_free(liConditionLValue, lvalue);
|
2008-07-25 12:09:03 +00:00
|
|
|
}
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
static liCondition* condition_new(liCompOperator op, liConditionLValue *lvalue) {
|
|
|
|
liCondition *c = g_slice_new0(liCondition);
|
2008-06-29 15:48:28 +00:00
|
|
|
c->refcount = 1;
|
2008-07-17 17:32:11 +00:00
|
|
|
c->op = op;
|
2008-07-25 12:09:03 +00:00
|
|
|
c->lvalue = lvalue;
|
2008-06-29 15:48:28 +00:00
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2008-07-25 20:38:42 +00:00
|
|
|
/* only EQ and NE */
|
2009-07-08 19:06:07 +00:00
|
|
|
static liCondition* cond_new_string(liCompOperator op, liConditionLValue *lvalue, GString *str) {
|
|
|
|
liCondition *c;
|
2008-07-25 20:38:42 +00:00
|
|
|
c = condition_new(op, lvalue);
|
2009-07-08 19:06:07 +00:00
|
|
|
c->rvalue.type = LI_COND_VALUE_STRING;
|
2008-07-25 20:38:42 +00:00
|
|
|
c->rvalue.string = str;
|
2008-06-29 15:48:28 +00:00
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2008-07-25 20:38:42 +00:00
|
|
|
/* only MATCH and NOMATCH */
|
2009-07-08 19:06:07 +00:00
|
|
|
static liCondition* cond_new_match(liServer *srv, liCompOperator op, liConditionLValue *lvalue, GString *str) {
|
|
|
|
liCondition *c;
|
2009-06-05 17:07:48 +00:00
|
|
|
GRegex *regex;
|
|
|
|
GError *err = NULL;
|
|
|
|
|
|
|
|
regex = g_regex_new(str->str, G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err);
|
|
|
|
|
|
|
|
if (!regex || err) {
|
|
|
|
ERROR(srv, "failed to compile regex \"%s\": %s", str->str, err->message);
|
|
|
|
g_error_free(err);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
c = condition_new(op, lvalue);
|
2009-07-08 19:06:07 +00:00
|
|
|
c->rvalue.type = LI_COND_VALUE_REGEXP;
|
2009-06-05 17:07:48 +00:00
|
|
|
c->rvalue.regex = regex;
|
|
|
|
|
2009-06-05 20:03:25 +00:00
|
|
|
g_string_free(str, TRUE);
|
2009-06-05 17:07:48 +00:00
|
|
|
|
|
|
|
return c;
|
2008-07-25 20:38:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* only IP and NOTIP */
|
2009-07-08 19:06:07 +00:00
|
|
|
static liCondition* cond_new_ip(liServer *srv, liCompOperator op, liConditionLValue *lvalue, GString *str) {
|
|
|
|
liCondition *c;
|
2008-07-25 22:42:08 +00:00
|
|
|
c = condition_new(op, lvalue);
|
|
|
|
if (!condition_parse_ip_net(&c->rvalue, str->str)) {
|
|
|
|
ERROR(srv, "Invalid ip address '%s'", str->str);
|
2009-07-09 20:17:24 +00:00
|
|
|
li_condition_release(srv, c);
|
2008-07-25 22:42:08 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return c;
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
liCondition* li_condition_new_bool(liServer *srv, liConditionLValue *lvalue, gboolean b) {
|
2009-07-08 19:06:07 +00:00
|
|
|
liCondition *c;
|
2009-01-06 00:33:20 +00:00
|
|
|
UNUSED(srv);
|
2009-07-08 19:06:07 +00:00
|
|
|
c = condition_new(LI_CONFIG_COND_EQ, lvalue);
|
|
|
|
c->rvalue.type = LI_COND_VALUE_BOOL;
|
2009-01-06 00:33:20 +00:00
|
|
|
c->rvalue.b = b;
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
liCondition* li_condition_new_string(liServer *srv, liCompOperator op, liConditionLValue *lvalue, GString *str) {
|
2008-07-25 20:38:42 +00:00
|
|
|
switch (op) {
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_EQ:
|
|
|
|
case LI_CONFIG_COND_NE:
|
|
|
|
case LI_CONFIG_COND_PREFIX:
|
|
|
|
case LI_CONFIG_COND_NOPREFIX:
|
|
|
|
case LI_CONFIG_COND_SUFFIX:
|
|
|
|
case LI_CONFIG_COND_NOSUFFIX:
|
2008-07-25 12:09:03 +00:00
|
|
|
return cond_new_string(op, lvalue, str);
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_MATCH:
|
|
|
|
case LI_CONFIG_COND_NOMATCH:
|
2008-07-25 20:38:42 +00:00
|
|
|
return cond_new_match(srv, op, lvalue, str);
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_IP:
|
|
|
|
case LI_CONFIG_COND_NOTIP:
|
2008-07-25 20:38:42 +00:00
|
|
|
return cond_new_ip(srv, op, lvalue, str);
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_GT:
|
|
|
|
case LI_CONFIG_COND_GE:
|
|
|
|
case LI_CONFIG_COND_LT:
|
|
|
|
case LI_CONFIG_COND_LE:
|
2009-07-09 20:17:24 +00:00
|
|
|
ERROR(srv, "Cannot compare strings with '%s'", li_comp_op_to_string(op));
|
2008-07-25 20:38:42 +00:00
|
|
|
return NULL;
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
2009-07-12 10:29:14 +00:00
|
|
|
ERROR(srv, "Condition creation failed: %s %s '%s'",
|
2009-07-09 20:17:24 +00:00
|
|
|
li_cond_lvalue_to_string(lvalue->type), li_comp_op_to_string(op),
|
2008-07-25 20:38:42 +00:00
|
|
|
str->str);
|
2008-06-30 10:25:01 +00:00
|
|
|
return NULL;
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
liCondition* li_condition_new_int(liServer *srv, liCompOperator op, liConditionLValue *lvalue, gint64 i) {
|
2009-07-08 19:06:07 +00:00
|
|
|
liCondition *c;
|
2008-07-25 20:38:42 +00:00
|
|
|
switch (op) {
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_PREFIX:
|
|
|
|
case LI_CONFIG_COND_NOPREFIX:
|
|
|
|
case LI_CONFIG_COND_SUFFIX:
|
|
|
|
case LI_CONFIG_COND_NOSUFFIX:
|
|
|
|
case LI_CONFIG_COND_MATCH:
|
|
|
|
case LI_CONFIG_COND_NOMATCH:
|
|
|
|
case LI_CONFIG_COND_IP:
|
|
|
|
case LI_CONFIG_COND_NOTIP:
|
2009-07-09 20:17:24 +00:00
|
|
|
ERROR(srv, "Cannot compare integers with '%s'", li_comp_op_to_string(op));
|
2008-07-19 10:56:44 +00:00
|
|
|
return NULL;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_EQ:
|
|
|
|
case LI_CONFIG_COND_NE:
|
|
|
|
case LI_CONFIG_COND_GT:
|
|
|
|
case LI_CONFIG_COND_GE:
|
|
|
|
case LI_CONFIG_COND_LT:
|
|
|
|
case LI_CONFIG_COND_LE:
|
2008-07-25 20:38:42 +00:00
|
|
|
c = condition_new(op, lvalue);
|
2009-07-08 19:06:07 +00:00
|
|
|
c->rvalue.type = LI_COND_VALUE_NUMBER;
|
2008-07-25 20:38:42 +00:00
|
|
|
c->rvalue.i = i;
|
|
|
|
return c;
|
2008-07-19 10:56:44 +00:00
|
|
|
}
|
2009-07-12 10:29:14 +00:00
|
|
|
ERROR(srv, "Condition creation failed: %s %s %"G_GINT64_FORMAT,
|
2009-07-09 20:17:24 +00:00
|
|
|
li_cond_lvalue_to_string(lvalue->type), li_comp_op_to_string(op),
|
2008-07-25 20:38:42 +00:00
|
|
|
i);
|
|
|
|
return NULL;
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
|
|
|
|
2008-07-25 20:38:42 +00:00
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
static void condition_free(liCondition *c) {
|
2009-07-09 20:17:24 +00:00
|
|
|
li_condition_lvalue_release(c->lvalue);
|
2008-07-25 12:09:03 +00:00
|
|
|
switch (c->rvalue.type) {
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COND_VALUE_BOOL:
|
|
|
|
case LI_COND_VALUE_NUMBER:
|
2008-06-30 10:25:01 +00:00
|
|
|
/* nothing to free */
|
2008-06-29 15:48:28 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COND_VALUE_STRING:
|
2008-07-25 20:38:42 +00:00
|
|
|
g_string_free(c->rvalue.string, TRUE);
|
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COND_VALUE_REGEXP:
|
2009-06-05 17:07:48 +00:00
|
|
|
g_regex_unref(c->rvalue.regex);
|
2008-07-25 20:38:42 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COND_VALUE_SOCKET_IPV4:
|
|
|
|
case LI_COND_VALUE_SOCKET_IPV6:
|
2008-07-25 20:38:42 +00:00
|
|
|
/* nothing to free */
|
2008-06-29 15:48:28 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-07-08 19:06:07 +00:00
|
|
|
g_slice_free(liCondition, c);
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
void li_condition_acquire(liCondition *c) {
|
2014-04-10 16:08:59 +00:00
|
|
|
LI_FORCE_ASSERT(g_atomic_int_get(&c->refcount) > 0);
|
2008-09-09 14:41:02 +00:00
|
|
|
g_atomic_int_inc(&c->refcount);
|
2008-07-24 11:25:40 +00:00
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
void li_condition_release(liServer *srv, liCondition* c) {
|
2008-07-24 11:25:40 +00:00
|
|
|
UNUSED(srv);
|
2008-08-06 18:46:42 +00:00
|
|
|
if (!c) return;
|
2014-04-10 16:08:59 +00:00
|
|
|
LI_FORCE_ASSERT(g_atomic_int_get(&c->refcount) > 0);
|
2008-09-09 14:41:02 +00:00
|
|
|
if (g_atomic_int_dec_and_test(&c->refcount)) {
|
2008-06-29 15:48:28 +00:00
|
|
|
condition_free(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
const char* li_comp_op_to_string(liCompOperator op) {
|
2008-07-17 17:32:11 +00:00
|
|
|
switch (op) {
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_EQ: return "==";
|
|
|
|
case LI_CONFIG_COND_NE: return "!=";
|
|
|
|
case LI_CONFIG_COND_PREFIX: return "=^";
|
|
|
|
case LI_CONFIG_COND_NOPREFIX: return "=^";
|
|
|
|
case LI_CONFIG_COND_SUFFIX: return "=$";
|
|
|
|
case LI_CONFIG_COND_NOSUFFIX: return "!$";
|
|
|
|
case LI_CONFIG_COND_MATCH: return "=~";
|
|
|
|
case LI_CONFIG_COND_NOMATCH: return "!~";
|
|
|
|
case LI_CONFIG_COND_IP: return "=/";
|
|
|
|
case LI_CONFIG_COND_NOTIP: return "!/";
|
|
|
|
case LI_CONFIG_COND_GT: return ">";
|
|
|
|
case LI_CONFIG_COND_GE: return ">=";
|
|
|
|
case LI_CONFIG_COND_LT: return "<";
|
|
|
|
case LI_CONFIG_COND_LE: return "<=";
|
2008-07-17 17:32:11 +00:00
|
|
|
}
|
2008-06-29 15:48:28 +00:00
|
|
|
|
2008-07-17 17:32:11 +00:00
|
|
|
return "<unkown>";
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
const char* li_cond_lvalue_to_string(liCondLValue t) {
|
2008-07-25 12:09:03 +00:00
|
|
|
switch (t) {
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COMP_REQUEST_LOCALIP: return "request.localip";
|
2010-02-21 12:45:20 +00:00
|
|
|
case LI_COMP_REQUEST_LOCALPORT: return "request.localport";
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COMP_REQUEST_REMOTEIP: return "request.remoteip";
|
2010-02-21 12:45:20 +00:00
|
|
|
case LI_COMP_REQUEST_REMOTEPORT: return "request.remoteport";
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COMP_REQUEST_PATH: return "request.path";
|
2014-06-06 09:16:22 +00:00
|
|
|
case LI_COMP_REQUEST_RAW_PATH: return "request.raw_path";
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COMP_REQUEST_HOST: return "request.host";
|
|
|
|
case LI_COMP_REQUEST_SCHEME: return "request.scheme";
|
|
|
|
case LI_COMP_REQUEST_QUERY_STRING: return "request.query";
|
|
|
|
case LI_COMP_REQUEST_METHOD: return "request.method";
|
|
|
|
case LI_COMP_REQUEST_CONTENT_LENGTH: return "request.length";
|
2009-10-03 14:47:57 +00:00
|
|
|
case LI_COMP_REQUEST_IS_HANDLED: return "request.is_handled";
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COMP_PHYSICAL_PATH: return "physical.path";
|
2009-09-15 17:08:13 +00:00
|
|
|
case LI_COMP_PHYSICAL_EXISTS: return "physical.exist";
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COMP_PHYSICAL_SIZE: return "physical.size";
|
|
|
|
case LI_COMP_PHYSICAL_ISDIR: return "physical.is_dir";
|
|
|
|
case LI_COMP_PHYSICAL_ISFILE: return "physical.is_file";
|
2010-10-05 11:57:26 +00:00
|
|
|
case LI_COMP_PHYSICAL_DOCROOT: return "physical.docroot";
|
|
|
|
case LI_COMP_PHYSICAL_PATHINFO: return "physical.pathinfo";
|
2009-09-28 19:30:06 +00:00
|
|
|
case LI_COMP_RESPONSE_STATUS: return "response.status";
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COMP_REQUEST_HEADER: return "request.header";
|
2009-09-28 19:30:06 +00:00
|
|
|
case LI_COMP_RESPONSE_HEADER: return "response.header";
|
2009-12-12 23:36:47 +00:00
|
|
|
case LI_COMP_ENVIRONMENT: return "request.environment";
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_COMP_UNKNOWN: return "<unknown>";
|
2008-07-25 12:09:03 +00:00
|
|
|
}
|
2008-06-29 15:48:28 +00:00
|
|
|
|
2009-06-01 15:58:48 +00:00
|
|
|
return "<unkown>";
|
|
|
|
}
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
liCondLValue li_cond_lvalue_from_string(const gchar *str, guint len) {
|
2009-06-01 15:58:48 +00:00
|
|
|
gchar *c = (gchar*)str;
|
|
|
|
|
2010-02-21 13:32:58 +00:00
|
|
|
if (g_str_has_prefix(c, "req")) {
|
|
|
|
if (g_str_has_prefix(c, "req.")) {
|
|
|
|
c += sizeof("req.")-1;
|
|
|
|
len -= sizeof("req.")-1;
|
|
|
|
} else if (g_str_has_prefix(c, "request.")) {
|
|
|
|
c += sizeof("request.")-1;
|
|
|
|
len -= sizeof("request.")-1;
|
|
|
|
} else {
|
|
|
|
return LI_COMP_UNKNOWN;
|
|
|
|
}
|
2009-06-01 15:58:48 +00:00
|
|
|
|
|
|
|
if (strncmp(c, "localip", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_LOCALIP;
|
2010-02-21 12:45:20 +00:00
|
|
|
else if (strncmp(c, "localport", len) == 0)
|
|
|
|
return LI_COMP_REQUEST_LOCALPORT;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "remoteip", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_REMOTEIP;
|
2010-02-21 12:45:20 +00:00
|
|
|
else if (strncmp(c, "remoteport", len) == 0)
|
|
|
|
return LI_COMP_REQUEST_REMOTEPORT;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "path", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_PATH;
|
2014-06-06 09:16:22 +00:00
|
|
|
else if (strncmp(c, "raw_path", len) == 0)
|
|
|
|
return LI_COMP_REQUEST_RAW_PATH;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "host", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_HOST;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "scheme", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_SCHEME;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "query", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_QUERY_STRING;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "method", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_METHOD;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "length", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_CONTENT_LENGTH;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "header", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_REQUEST_HEADER;
|
2009-12-12 23:36:47 +00:00
|
|
|
else if (strncmp(c, "environment", len) == 0 || strncmp(c, "env", len) == 0)
|
|
|
|
return LI_COMP_ENVIRONMENT;
|
2009-10-03 14:47:57 +00:00
|
|
|
else if (strncmp(c, "is_handled", len) == 0)
|
|
|
|
return LI_COMP_REQUEST_IS_HANDLED;
|
2010-02-21 13:32:58 +00:00
|
|
|
} else if (g_str_has_prefix(c, "phys")) {
|
|
|
|
if (g_str_has_prefix(c, "phys.")) {
|
|
|
|
c += sizeof("phys.")-1;
|
|
|
|
len -= sizeof("phys.")-1;
|
|
|
|
} else if (g_str_has_prefix(c, "physical.")) {
|
|
|
|
c += sizeof("physical.")-1;
|
|
|
|
len -= sizeof("physical.")-1;
|
|
|
|
} else {
|
|
|
|
return LI_COMP_UNKNOWN;
|
|
|
|
}
|
2009-06-01 15:58:48 +00:00
|
|
|
|
|
|
|
if (strncmp(c, "path", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_PHYSICAL_PATH;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "exists", len) == 0)
|
2009-09-15 17:08:13 +00:00
|
|
|
return LI_COMP_PHYSICAL_EXISTS;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "size", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_PHYSICAL_SIZE;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "is_file", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_PHYSICAL_ISFILE;
|
2009-06-01 15:58:48 +00:00
|
|
|
else if (strncmp(c, "is_dir", len) == 0)
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_PHYSICAL_ISDIR;
|
2010-10-05 11:57:26 +00:00
|
|
|
else if (strncmp(c, "docroot", len) == 0)
|
|
|
|
return LI_COMP_PHYSICAL_DOCROOT;
|
|
|
|
else if (strncmp(c, "pathinfo", len) == 0)
|
|
|
|
return LI_COMP_PHYSICAL_PATHINFO;
|
2010-02-21 13:32:58 +00:00
|
|
|
} else if (g_str_has_prefix(c, "resp")) {
|
|
|
|
if (g_str_has_prefix(c, "resp.")) {
|
|
|
|
c += sizeof("resp.")-1;
|
|
|
|
len -= sizeof("resp.")-1;
|
|
|
|
} else if (g_str_has_prefix(c, "response.")) {
|
|
|
|
c += sizeof("response.")-1;
|
|
|
|
len -= sizeof("response.")-1;
|
|
|
|
} else {
|
|
|
|
return LI_COMP_UNKNOWN;
|
|
|
|
}
|
2009-09-28 19:30:06 +00:00
|
|
|
|
|
|
|
if (strncmp(c, "status", len) == 0)
|
|
|
|
return LI_COMP_RESPONSE_STATUS;
|
|
|
|
else if (strncmp(c, "header", len) == 0)
|
|
|
|
return LI_COMP_RESPONSE_HEADER;
|
2009-06-01 15:58:48 +00:00
|
|
|
}
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_COMP_UNKNOWN;
|
2008-06-29 15:48:28 +00:00
|
|
|
}
|
2008-06-30 10:25:01 +00:00
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
static liHandlerResult li_condition_check_eval_bool(liVRequest *vr, liCondition *cond, gboolean *res) {
|
2009-12-19 16:41:55 +00:00
|
|
|
gboolean val;
|
|
|
|
liConditionValue match_val;
|
2009-09-15 17:08:13 +00:00
|
|
|
liHandlerResult r;
|
2009-12-19 16:41:55 +00:00
|
|
|
*res = FALSE;
|
2009-09-15 17:08:13 +00:00
|
|
|
|
2010-10-07 13:58:46 +00:00
|
|
|
r = li_condition_get_value(vr->wrk->tmp_str, vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_BOOL);
|
2009-12-19 16:41:55 +00:00
|
|
|
if (r != LI_HANDLER_GO_ON) return r;
|
2009-09-15 17:08:13 +00:00
|
|
|
|
2009-12-19 16:41:55 +00:00
|
|
|
switch (match_val.match_type) {
|
|
|
|
case LI_COND_VALUE_HINT_ANY:
|
|
|
|
case LI_COND_VALUE_HINT_STRING:
|
|
|
|
val = ('\0' != match_val.data.str[0]);
|
2009-09-15 17:08:13 +00:00
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COND_VALUE_HINT_BOOL:
|
|
|
|
val = match_val.data.bool;
|
2009-09-15 17:08:13 +00:00
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COND_VALUE_HINT_NUMBER:
|
|
|
|
val = match_val.data.number != 0;
|
2009-10-03 14:47:57 +00:00
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COND_VALUE_HINT_SOCKADDR:
|
|
|
|
val = TRUE; /* just.. don't do this. */
|
2009-01-06 00:33:20 +00:00
|
|
|
break;
|
2010-10-06 12:31:11 +00:00
|
|
|
default:
|
|
|
|
return LI_HANDLER_ERROR;
|
2009-01-06 00:33:20 +00:00
|
|
|
}
|
2009-12-19 16:41:55 +00:00
|
|
|
|
|
|
|
*res = !cond->rvalue.b ^ val;
|
2009-01-06 00:33:20 +00:00
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_GO_ON;
|
2009-01-06 00:33:20 +00:00
|
|
|
}
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
/* LI_COND_VALUE_STRING and LI_COND_VALUE_REGEXP only */
|
2009-07-09 20:17:24 +00:00
|
|
|
static liHandlerResult li_condition_check_eval_string(liVRequest *vr, liCondition *cond, gboolean *res) {
|
2009-07-08 19:06:07 +00:00
|
|
|
liActionRegexStackElement arse;
|
2009-12-19 16:41:55 +00:00
|
|
|
liConditionValue match_val;
|
|
|
|
liHandlerResult r;
|
2008-09-26 14:11:08 +00:00
|
|
|
const char *val = "";
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = FALSE;
|
2008-06-30 10:25:01 +00:00
|
|
|
|
2010-10-07 13:58:46 +00:00
|
|
|
r = li_condition_get_value(vr->wrk->tmp_str, vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_STRING);
|
2009-12-19 16:41:55 +00:00
|
|
|
if (r != LI_HANDLER_GO_ON) return r;
|
|
|
|
|
2010-10-07 13:58:46 +00:00
|
|
|
val = li_condition_value_to_string(vr->wrk->tmp_str, &match_val);
|
2008-06-30 11:38:52 +00:00
|
|
|
|
2008-07-25 22:42:08 +00:00
|
|
|
switch (cond->op) {
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_EQ:
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = g_str_equal(val, cond->rvalue.string->str);
|
2008-06-30 12:34:37 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_NE:
|
2008-12-09 21:38:37 +00:00
|
|
|
*res = !g_str_equal(val, cond->rvalue.string->str);
|
2008-08-13 20:10:20 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_PREFIX:
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = g_str_has_prefix(val, cond->rvalue.string->str);
|
2008-08-13 20:10:20 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_NOPREFIX:
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = !g_str_has_prefix(val, cond->rvalue.string->str);
|
2008-08-13 20:26:45 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_SUFFIX:
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = g_str_has_suffix(val, cond->rvalue.string->str);
|
2008-06-30 12:34:37 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_NOSUFFIX:
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = !g_str_has_suffix(val, cond->rvalue.string->str);
|
2008-08-13 20:26:45 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_MATCH:
|
2010-09-26 17:47:00 +00:00
|
|
|
arse.match_info = NULL;
|
|
|
|
arse.string = g_string_new(val); /* we have to copy the value, as match-info references it */
|
|
|
|
*res = g_regex_match(cond->rvalue.regex, arse.string->str, 0, &arse.match_info);
|
|
|
|
if (*res) {
|
|
|
|
g_array_append_val(vr->action_stack.regex_stack, arse);
|
|
|
|
} else {
|
|
|
|
g_match_info_free(arse.match_info);
|
|
|
|
g_string_free(arse.string, TRUE);
|
|
|
|
}
|
2009-06-05 17:07:48 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_NOMATCH:
|
2010-09-26 17:47:00 +00:00
|
|
|
arse.match_info = NULL;
|
|
|
|
arse.string = g_string_new(val); /* we have to copy the value, as match-info references it */
|
|
|
|
*res = !g_regex_match(cond->rvalue.regex, arse.string->str, 0, &arse.match_info);
|
|
|
|
if (*res) {
|
|
|
|
g_match_info_free(arse.match_info);
|
|
|
|
g_string_free(arse.string, TRUE);
|
|
|
|
} else {
|
|
|
|
g_array_append_val(vr->action_stack.regex_stack, arse);
|
|
|
|
}
|
2008-06-30 12:34:37 +00:00
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_IP:
|
|
|
|
case LI_CONFIG_COND_NOTIP:
|
|
|
|
case LI_CONFIG_COND_GE:
|
|
|
|
case LI_CONFIG_COND_GT:
|
|
|
|
case LI_CONFIG_COND_LE:
|
|
|
|
case LI_CONFIG_COND_LT:
|
2009-07-09 20:17:24 +00:00
|
|
|
VR_ERROR(vr, "cannot compare string/regexp with '%s'", li_comp_op_to_string(cond->op));
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_ERROR;
|
2008-06-30 10:25:01 +00:00
|
|
|
}
|
2008-06-30 12:01:53 +00:00
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_GO_ON;
|
2008-06-30 10:25:01 +00:00
|
|
|
}
|
|
|
|
|
2008-06-30 11:38:52 +00:00
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
static liHandlerResult li_condition_check_eval_int(liVRequest *vr, liCondition *cond, gboolean *res) {
|
2008-09-26 14:11:08 +00:00
|
|
|
gint64 val;
|
2009-12-19 16:41:55 +00:00
|
|
|
liConditionValue match_val;
|
|
|
|
liHandlerResult r;
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = FALSE;
|
2008-06-30 11:38:52 +00:00
|
|
|
|
2010-10-07 13:58:46 +00:00
|
|
|
r = li_condition_get_value(vr->wrk->tmp_str, vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_NUMBER);
|
2009-12-19 16:41:55 +00:00
|
|
|
if (r != LI_HANDLER_GO_ON) return r;
|
2009-09-15 17:08:13 +00:00
|
|
|
|
2009-12-19 16:41:55 +00:00
|
|
|
switch (match_val.match_type) {
|
|
|
|
case LI_COND_VALUE_HINT_ANY:
|
|
|
|
val = g_ascii_strtoll(match_val.data.str, NULL, 10);
|
|
|
|
errno = 0; /* ignore errors */
|
2008-06-30 12:34:37 +00:00
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COND_VALUE_HINT_NUMBER:
|
|
|
|
val = match_val.data.number;
|
2009-09-28 19:30:06 +00:00
|
|
|
break;
|
2008-06-30 12:34:37 +00:00
|
|
|
default:
|
2009-07-09 20:17:24 +00:00
|
|
|
VR_ERROR(vr, "couldn't get int value for '%s'", li_cond_lvalue_to_string(cond->lvalue->type));
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_ERROR;
|
2008-06-30 11:38:52 +00:00
|
|
|
}
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
switch (cond->op) {
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_EQ: /** == */
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = (val == cond->rvalue.i);
|
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_NE: /** != */
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = (val != cond->rvalue.i);
|
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_LT: /** < */
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = (val < cond->rvalue.i);
|
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_LE: /** <= */
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = (val <= cond->rvalue.i);
|
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_GT: /** > */
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = (val > cond->rvalue.i);
|
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_GE: /** >= */
|
2008-10-25 12:53:57 +00:00
|
|
|
*res = (val >= cond->rvalue.i);
|
|
|
|
break;
|
2009-07-08 19:06:07 +00:00
|
|
|
case LI_CONFIG_COND_PREFIX:
|
|
|
|
case LI_CONFIG_COND_NOPREFIX:
|
|
|
|
case LI_CONFIG_COND_SUFFIX:
|
|
|
|
case LI_CONFIG_COND_NOSUFFIX:
|
|
|
|
case LI_CONFIG_COND_MATCH:
|
|
|
|
case LI_CONFIG_COND_NOMATCH:
|
|
|
|
case LI_CONFIG_COND_IP:
|
|
|
|
case LI_CONFIG_COND_NOTIP:
|
2009-07-09 20:17:24 +00:00
|
|
|
VR_ERROR(vr, "cannot compare int with '%s'", li_comp_op_to_string(cond->op));
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_ERROR;
|
2008-06-30 11:38:52 +00:00
|
|
|
}
|
2008-07-01 18:56:59 +00:00
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_GO_ON;
|
2008-06-30 11:38:52 +00:00
|
|
|
}
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
static gboolean ip_in_net(liConditionRValue *target, liConditionRValue *network) {
|
|
|
|
if (target->type == LI_COND_VALUE_SOCKET_IPV4) {
|
|
|
|
if (network->type == LI_COND_VALUE_SOCKET_IPV4) {
|
2009-10-09 13:38:12 +00:00
|
|
|
return li_ipv4_in_ipv4_net(target->ipv4.addr, network->ipv4.addr, network->ipv4.networkmask);
|
2009-07-08 19:06:07 +00:00
|
|
|
} else if (network->type == LI_COND_VALUE_SOCKET_IPV6) {
|
2010-09-21 13:11:48 +00:00
|
|
|
/* strict matches only */
|
|
|
|
/* return li_ipv4_in_ipv6_net(target->ipv4.addr, network->ipv6.addr, network->ipv6.network); */
|
|
|
|
return FALSE;
|
2008-07-25 22:42:08 +00:00
|
|
|
}
|
2009-07-08 19:06:07 +00:00
|
|
|
} else if (target->type == LI_COND_VALUE_SOCKET_IPV6) {
|
|
|
|
if (network->type == LI_COND_VALUE_SOCKET_IPV4) {
|
2010-09-21 13:11:48 +00:00
|
|
|
/* strict matches only */
|
|
|
|
/* return li_ipv6_in_ipv4_net(target->ipv6.addr, network->ipv4.addr, network->ipv4.networkmask); */
|
|
|
|
return FALSE;
|
2009-07-08 19:06:07 +00:00
|
|
|
} else if (network->type == LI_COND_VALUE_SOCKET_IPV6) {
|
2009-10-09 13:38:12 +00:00
|
|
|
return li_ipv6_in_ipv6_net(target->ipv6.addr, network->ipv6.addr, network->ipv6.network);
|
2008-07-25 22:42:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
/* LI_CONFIG_COND_IP and LI_CONFIG_COND_NOTIP only */
|
2009-07-09 20:17:24 +00:00
|
|
|
static liHandlerResult li_condition_check_eval_ip(liVRequest *vr, liCondition *cond, gboolean *res) {
|
2009-12-19 16:41:55 +00:00
|
|
|
liConditionValue match_val;
|
|
|
|
liHandlerResult r;
|
2009-07-08 19:06:07 +00:00
|
|
|
liConditionRValue ipval;
|
2008-07-25 22:42:08 +00:00
|
|
|
|
2010-10-07 13:58:46 +00:00
|
|
|
r = li_condition_get_value(vr->wrk->tmp_str, vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_SOCKADDR);
|
2009-12-19 16:41:55 +00:00
|
|
|
if (r != LI_HANDLER_GO_ON) return r;
|
2008-07-25 22:42:08 +00:00
|
|
|
|
2009-12-19 16:41:55 +00:00
|
|
|
*res = (cond->op == LI_CONFIG_COND_NOTIP);
|
|
|
|
|
|
|
|
switch (match_val.match_type) {
|
|
|
|
case LI_COND_VALUE_HINT_ANY:
|
|
|
|
if (!condition_parse_ip(&ipval, match_val.data.str))
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_GO_ON;
|
2008-07-25 22:42:08 +00:00
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
case LI_COND_VALUE_HINT_SOCKADDR:
|
|
|
|
if (!condition_ip_from_socket(&ipval, match_val.data.addr.addr))
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_GO_ON;
|
2008-07-25 22:42:08 +00:00
|
|
|
break;
|
2009-12-19 16:41:55 +00:00
|
|
|
defa |