"listen", "frontend", "backend", "defaults", "server",
"default-server", "server-template", "bind",
"cookie", "email-alert",
- "stick", "stats", "option",
+ "stats", "option",
NULL /* must be last */
};
/* Indicate that the email_alert is at least partially configured */
curproxy->email_alert.flags |= PR_EMAIL_ALERT_SET;
}/* end else if (!strcmp(args[0], "email-alert")) */
- else if (strcmp(args[0], "stick") == 0) {
- struct sticking_rule *rule;
- struct sample_expr *expr;
- int myidx = 0;
- const char *name = NULL;
- int flags;
-
- if (curproxy->cap & PR_CAP_DEF) {
- ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
- err_code |= ERR_ALERT | ERR_FATAL;
- goto out;
- }
-
- if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
- err_code |= ERR_WARN;
- goto out;
- }
-
- myidx++;
- if ((strcmp(args[myidx], "store") == 0) ||
- (strcmp(args[myidx], "store-request") == 0)) {
- myidx++;
- flags = STK_IS_STORE;
- }
- else if (strcmp(args[myidx], "store-response") == 0) {
- myidx++;
- flags = STK_IS_STORE | STK_ON_RSP;
- }
- else if (strcmp(args[myidx], "match") == 0) {
- myidx++;
- flags = STK_IS_MATCH;
- }
- else if (strcmp(args[myidx], "on") == 0) {
- myidx++;
- flags = STK_IS_MATCH | STK_IS_STORE;
- }
- else {
- ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
- err_code |= ERR_ALERT | ERR_FATAL;
- goto out;
- }
-
- if (*(args[myidx]) == 0) {
- ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
- err_code |= ERR_ALERT | ERR_FATAL;
- goto out;
- }
-
- curproxy->conf.args.ctx = ARGC_STK;
- expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args, NULL);
- if (!expr) {
- ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
- err_code |= ERR_ALERT | ERR_FATAL;
- goto out;
- }
-
- if (flags & STK_ON_RSP) {
- if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
- ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
- file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
- err_code |= ERR_ALERT | ERR_FATAL;
- free(expr);
- goto out;
- }
- } else {
- if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
- ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
- file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
- err_code |= ERR_ALERT | ERR_FATAL;
- free(expr);
- goto out;
- }
- }
-
- /* check if we need to allocate an http_txn struct for HTTP parsing */
- curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
-
- if (strcmp(args[myidx], "table") == 0) {
- myidx++;
- name = args[myidx++];
- }
-
- if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
- if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
- ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
- file, linenum, args[0], errmsg);
- err_code |= ERR_ALERT | ERR_FATAL;
- free(expr);
- goto out;
- }
- }
- else if (*(args[myidx])) {
- ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
- file, linenum, args[0], args[myidx]);
- err_code |= ERR_ALERT | ERR_FATAL;
- free(expr);
- goto out;
- }
- if (flags & STK_ON_RSP)
- err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, &errmsg);
- else
- err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, &errmsg);
- if (errmsg)
- ha_warning("parsing [%s:%d] : '%s'.\n", file, linenum, errmsg);
-
- rule = calloc(1, sizeof(*rule));
- if (!rule) {
- free_acl_cond(cond);
- goto alloc_error;
- }
- rule->cond = cond;
- rule->expr = expr;
- rule->flags = flags;
- rule->table.name = name ? strdup(name) : NULL;
- LIST_INIT(&rule->list);
- if (flags & STK_ON_RSP)
- LIST_APPEND(&curproxy->storersp_rules, &rule->list);
- else
- LIST_APPEND(&curproxy->sticking_rules, &rule->list);
- }
else if (strcmp(args[0], "stats") == 0) {
if (!(curproxy->cap & PR_CAP_DEF) && curproxy->uri_auth == curr_defproxy->uri_auth) {
/* we must detach from the default config */
return -1;
}
+/* Parses "stick" rules */
+static int proxy_parse_stick(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
+{
+ struct sample_expr *expr = NULL;
+ struct acl_cond *cond = NULL;
+ struct sticking_rule *rule;
+ const char *name = NULL;
+ char *errmsg = NULL;
+ int myidx = 0;
+ int flags;
+
+ if (curpx->cap & PR_CAP_DEF) {
+ memprintf(err, "'%s' is not supported in 'defaults' section.", args[0]);
+ goto fail;
+ }
+
+ if (warnifnotcap(curpx, PR_CAP_BE, file, line, args[0], NULL))
+ return 0;
+
+ myidx++;
+ if ((strcmp(args[myidx], "store") == 0) ||
+ (strcmp(args[myidx], "store-request") == 0)) {
+ myidx++;
+ flags = STK_IS_STORE;
+ }
+ else if (strcmp(args[myidx], "store-response") == 0) {
+ myidx++;
+ flags = STK_IS_STORE | STK_ON_RSP;
+ }
+ else if (strcmp(args[myidx], "match") == 0) {
+ myidx++;
+ flags = STK_IS_MATCH;
+ }
+ else if (strcmp(args[myidx], "on") == 0) {
+ myidx++;
+ flags = STK_IS_MATCH | STK_IS_STORE;
+ }
+ else {
+ memprintf(err, "'%s' expects 'on', 'match', or 'store'.", args[0]);
+ goto fail;
+ }
+
+ if (*(args[myidx]) == 0) {
+ memprintf(err, "'%s' expects a fetch method.", args[0]);
+ goto fail;
+ }
+
+ curpx->conf.args.ctx = ARGC_STK;
+ expr = sample_parse_expr(args, &myidx, file, line, &errmsg, &curpx->conf.args, NULL);
+ if (!expr) {
+ memprintf(err, "'%s': %s", args[0], errmsg);
+ goto fail;
+ }
+
+ if (flags & STK_ON_RSP) {
+ if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
+ memprintf(err, "'%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.",
+ args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
+ goto fail;
+ }
+ } else {
+ if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
+ memprintf(err, "'%s': fetch method '%s' extracts information from '%s', none of which is available during request.",
+ args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
+ goto fail;
+ }
+ }
+
+ /* check if we need to allocate an http_txn struct for HTTP parsing */
+ curpx->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
+
+ if (strcmp(args[myidx], "table") == 0) {
+ myidx++;
+ name = args[myidx++];
+ }
+
+ if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
+ cond = build_acl_cond(file, line, &curpx->acl, curpx, (const char **)args + myidx, &errmsg);
+ if (!cond) {
+ memprintf(err, "'%s': error detected while parsing sticking condition : %s.",
+ args[0], errmsg);
+ goto fail;
+ }
+ }
+ else if (*(args[myidx])) {
+ memprintf(err, "'%s': unknown keyword '%s'.", args[0], args[myidx]);
+ goto fail;
+ }
+
+ if (warnif_cond_conflicts(cond, (flags & STK_ON_RSP) ? SMP_VAL_BE_STO_RUL : SMP_VAL_BE_SET_SRV, &errmsg))
+ ha_warning("parsing [%s:%d] : '%s'.\n", file, line, errmsg);
+ ha_free(&errmsg);
+
+ rule = calloc(1, sizeof(*rule));
+ if (!rule) {
+ memprintf(err, "out of memory.");
+ goto fail;
+ }
+
+ rule->cond = cond;
+ rule->expr = expr;
+ rule->flags = flags;
+ rule->table.name = name ? strdup(name) : NULL;
+ LIST_INIT(&rule->list);
+ if (flags & STK_ON_RSP)
+ LIST_APPEND(&curpx->storersp_rules, &rule->list);
+ else
+ LIST_APPEND(&curpx->sticking_rules, &rule->list);
+
+ return 0;
+ fail:
+ free(errmsg);
+ free_acl_cond(cond);
+ free(expr);
+ return -1;
+}
+
static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_LISTEN, "acl", proxy_parse_acl },
{ CFG_LISTEN, "appsession", proxy_parse_removed_kw },
{ CFG_LISTEN, "server-state-file-name", proxy_parse_be_opts },
{ CFG_LISTEN, "source", proxy_parse_source },
{ CFG_LISTEN, "srvexp", proxy_parse_removed_kw },
+ { CFG_LISTEN, "stick", proxy_parse_stick },
{ CFG_LISTEN, "stick-table", proxy_parse_stick_table },
{ CFG_LISTEN, "transparent", proxy_parse_removed_kw },
{ CFG_LISTEN, "unique-id-format", proxy_parse_logformat },