diff --git a/src/base.h b/src/base.h index 9276169..9506b25 100644 --- a/src/base.h +++ b/src/base.h @@ -31,6 +31,7 @@ struct connection { action_stack action_stack; request request; + physical physical; }; #endif diff --git a/src/condition.c b/src/condition.c index e17d319..5242b56 100644 --- a/src/condition.c +++ b/src/condition.c @@ -81,19 +81,22 @@ static condition* cond_new_socket(config_cond_t cond, comp_key_t comp, GString * static condition* condition_new_from_string(config_cond_t cond, comp_key_t comp, GString *str) { switch (comp) { case COMP_SERVER_SOCKET: - case COMP_HTTP_REMOTE_IP: + case COMP_REQUEST_REMOTE_IP: return cond_new_socket(cond, comp, str); - case COMP_HTTP_PATH: - case COMP_HTTP_HOST: - case COMP_HTTP_REFERER: - case COMP_HTTP_USER_AGENT: - case COMP_HTTP_COOKIE: - case COMP_HTTP_SCHEME: - case COMP_HTTP_QUERY_STRING: - case COMP_HTTP_REQUEST_METHOD: + case COMP_REQUEST_PATH: + case COMP_REQUEST_HOST: + case COMP_REQUEST_REFERER: + case COMP_REQUEST_USER_AGENT: + case COMP_REQUEST_COOKIE: + case COMP_REQUEST_SCHEME: + case COMP_REQUEST_QUERY_STRING: + case COMP_REQUEST_METHOD: case COMP_PHYSICAL_PATH: case COMP_PHYSICAL_PATH_EXISTS: return cond_new_string(cond, comp, str); + default: + // TODO: die with error + break; } return NULL; } @@ -183,35 +186,39 @@ static gboolean condition_check_eval_string(server *srv, connection *con, condit /* TODO: get values */ case COMP_SERVER_SOCKET: break; - case COMP_HTTP_PATH: + case COMP_REQUEST_PATH: value = con->request.uri.path->str; break; - case COMP_HTTP_HOST: + case COMP_REQUEST_HOST: value = con->request.host->str; break; - case COMP_HTTP_REFERER: + case COMP_REQUEST_REFERER: break; - case COMP_HTTP_USER_AGENT: + case COMP_REQUEST_USER_AGENT: break; - case COMP_HTTP_COOKIE: + case COMP_REQUEST_COOKIE: break; - case COMP_HTTP_SCHEME: + case COMP_REQUEST_SCHEME: /* TODO: check for ssl */ value = "http"; /* ssl ? "https" : "http" */ break; - case COMP_HTTP_REMOTE_IP: + case COMP_REQUEST_REMOTE_IP: value = con->dst_addr_str->str; break; - case COMP_HTTP_QUERY_STRING: + case COMP_REQUEST_QUERY_STRING: value = con->request.uri.query->str; break; - case COMP_HTTP_REQUEST_METHOD: + case COMP_REQUEST_METHOD: value = con->request.http_method_str->str; break; case COMP_PHYSICAL_PATH: case COMP_PHYSICAL_PATH_EXISTS: break; + default: + // TODO: die with error + break; } + if (value) switch (cond->cond) { case CONFIG_COND_EQ: /** == */ result = 0 == strcmp(value, cond->value.string->str); @@ -230,6 +237,42 @@ static gboolean condition_check_eval_string(server *srv, connection *con, condit return result; } + +static gboolean condition_check_eval_int(server *srv, connection *con, condition *cond) { + UNUSED(srv); + UNUSED(con); + gint64 value; + + switch (cond->comp) { + case COMP_REQUEST_SIZE: + value = con->request.size; + case COMP_PHYSICAL_SIZE: + value = con->physical.size; + break; + default: + value = -1; + } + + if (value > 0) switch (cond->cond) { + case CONFIG_COND_EQ: /** == */ + return (value == cond->value.i); + case CONFIG_COND_NE: /** != */ + return (value != cond->value.i); + case CONFIG_COND_LT: /** < */ + return (value < cond->value.i); + case CONFIG_COND_LE: /** <= */ + return (value <= cond->value.i); + case CONFIG_COND_GT: /** > */ + return (value > cond->value.i); + case CONFIG_COND_GE: /** >= */ + return (value >= cond->value.i); + default: + // TODO: die with error + return FALSE; + } +} + + static gboolean ipv4_in_ipv4_net(guint32 target, guint32 match, guint32 networkmask) { return (target & networkmask) == (match & networkmask); } @@ -254,6 +297,8 @@ static gboolean condition_check_eval(server *srv, connection *con, condition *co switch (cond->value_type) { case COND_VALUE_STRING: return condition_check_eval_string(srv, con, cond); + case COND_VALUE_INT: + return condition_check_eval_int(srv, con, cond); /* TODO: implement checks */ default: return FALSE; diff --git a/src/condition.h b/src/condition.h index c6d2ab3..0de6d47 100644 --- a/src/condition.h +++ b/src/condition.h @@ -25,17 +25,19 @@ typedef enum { */ typedef enum { COMP_SERVER_SOCKET, - COMP_HTTP_PATH, - COMP_HTTP_HOST, - COMP_HTTP_REFERER, - COMP_HTTP_USER_AGENT, - COMP_HTTP_COOKIE, - COMP_HTTP_SCHEME, - COMP_HTTP_REMOTE_IP, - COMP_HTTP_QUERY_STRING, - COMP_HTTP_REQUEST_METHOD, + COMP_REQUEST_PATH, + COMP_REQUEST_HOST, + COMP_REQUEST_REFERER, + COMP_REQUEST_USER_AGENT, + COMP_REQUEST_COOKIE, + COMP_REQUEST_SCHEME, + COMP_REQUEST_REMOTE_IP, + COMP_REQUEST_QUERY_STRING, + COMP_REQUEST_METHOD, + COMP_REQUEST_SIZE, COMP_PHYSICAL_PATH, - COMP_PHYSICAL_PATH_EXISTS + COMP_PHYSICAL_PATH_EXISTS, + COMP_PHYSICAL_SIZE } comp_key_t; typedef enum { @@ -68,7 +70,7 @@ struct condition { pcre_extra *regex_study; }; #endif - gint i; + gint64 i; struct { guint32 addr; guint32 networkmask; diff --git a/src/request.h b/src/request.h index 5474c9b..975b575 100644 --- a/src/request.h +++ b/src/request.h @@ -40,6 +40,9 @@ typedef struct request request; struct request_uri; typedef struct request_uri request_uri; +struct physical; +typedef struct physical physical; + struct request_uri { GString *uri, *orig_uri; @@ -48,7 +51,7 @@ struct request_uri { GString *query; }; -struct pyhsical { +struct physical { GString *path; GString *basedir; @@ -56,6 +59,8 @@ struct pyhsical { GString *rel_path; GString *pathinfo; + + guint64 size; }; struct request { @@ -69,6 +74,7 @@ struct request { /* Parsed headers: */ GString *host; goffset content_length; + guint64 size; }; #endif