char *name; /* default backend name during config parse */
} defbe;
struct list acl; /* ACL declared on this proxy */
+ struct list block_cond; /* early blocking conditions (chained) */
struct server *srv; /* known servers */
int srv_act, srv_bck; /* # of running servers */
int tot_wact, tot_wbck; /* total weights of active and backup servers */
proxy = curproxy;
LIST_INIT(&curproxy->pendconns);
LIST_INIT(&curproxy->acl);
+ LIST_INIT(&curproxy->block_cond);
curproxy->id = strdup(args[1]);
curproxy->cap = rc;
}
curproxy->conn_retries = atol(args[1]);
}
+ else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
+ int pol = ACL_COND_NONE;
+ struct acl_cond *cond;
+
+ if (!strcmp(args[1], "if"))
+ pol = ACL_COND_IF;
+ else if (!strcmp(args[1], "unless"))
+ pol = ACL_COND_UNLESS;
+
+ if (pol == ACL_COND_NONE) {
+ Alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
+ file, linenum, args[0]);
+ return -1;
+ }
+
+ if ((cond = parse_acl_cond((const char **)args + 2, &curproxy->acl, pol)) == NULL) {
+ Alert("parsing [%s:%d] : error detected while parsing blocking condition.\n",
+ file, linenum);
+ return -1;
+ }
+ LIST_ADDQ(&curproxy->block_cond, &cond->list);
+ }
else if (!strcmp(args[0], "stats")) {
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
return 0;
*/
do {
+ struct acl_cond *cond;
struct proxy *rule_set = t->be;
cur_proxy = t->be;
+ /* first check whether we have some ACLs set to block this request */
+ list_for_each_entry(cond, &cur_proxy->block_cond, list) {
+ int ret = acl_exec_cond(cond, cur_proxy, t, txn);
+ if (cond->pol == ACL_COND_UNLESS)
+ ret = !ret;
+
+ if (ret) {
+ txn->status = 403;
+ /* let's log the request time */
+ t->logs.t_request = tv_ms_elapsed(&t->logs.tv_accept, &now);
+ client_retnclose(t, error_message(t, HTTP_ERR_403));
+ goto return_prx_cond;
+ }
+ }
+
/* try headers filters */
if (rule_set->req_exp != NULL) {
if (apply_filters_to_request(t, req, rule_set->req_exp) < 0)