[MEDIUM]: Inversion for options
This patch adds a possibility to invert most of available options by introducing the "no" keyword, available as an additional prefix. If it is found arguments are shifted left and an additional flag (inv) is set. It allows to use all options from a current defaults section, except the selected ones, for example: -- cut here -- defaults contimeout 4200 clitimeout 50000 srvtimeout 40000 option contstats listen stats 1.2.3.4:80 no option contstats -- cut here -- Currenly inversion works only with the "option" keyword. The patch also moves last_checks calculation at the end of the readcfgfile() function and changes "PR_O_FORCE_CLO | PR_O_HTTP_CLOSE" into "PR_O_FORCE_CLO" in cfg_opts so it is possible to invert forceclose without breaking httpclose (and vice versa) and to invert tcpsplice in one proxy but to keep a proper last_checks value when tcpsplice is used in another proxy. Now, the code checks for PR_O_FORCE_CLO everywhere it checks for PR_O_HTTP_CLOSE. I also decided to depreciate "redisp" and "redispatch" keywords as it is IMHO better to use "option redispatch" which can be inverted. Some useful documentation were added and at the same time I sorted (alfabetically) all valid options both in the code and the documentation.
This commit is contained in:
parent
0ba2750591
commit
336d475d13
|
@ -490,7 +490,10 @@ details.
|
|||
The following list of keywords is supported. Most of them may only be used in a
|
||||
limited set of section types. Some of them are marked as "deprecated" because
|
||||
they are inherited from an old syntax which may be confusing or functionnally
|
||||
limited, and there are new recommended keywords to replace them.
|
||||
limited, and there are new recommended keywords to replace them. Keywords
|
||||
listed with [no] can be optionally inverted using the "no" prefix, ex. "no
|
||||
option contstats". This makes sense when the option has been enabled by default
|
||||
and must be disabled for a specific instance.
|
||||
|
||||
|
||||
keyword defaults frontend listen backend
|
||||
|
@ -523,31 +526,31 @@ mode X X X X
|
|||
monitor fail - X X -
|
||||
monitor-net X X X -
|
||||
monitor-uri X X X -
|
||||
option abortonclose X - X X
|
||||
option allbackups X - X X
|
||||
option checkcache X - X X
|
||||
option clitcpka X X X -
|
||||
option contstats X X X -
|
||||
option dontlognull X X X -
|
||||
option forceclose X - X X
|
||||
[no] option abortonclose X - X X
|
||||
[no] option allbackups X - X X
|
||||
[no] option checkcache X - X X
|
||||
[no] option clitcpka X X X -
|
||||
[no] option contstats X X X -
|
||||
[no] option dontlognull X X X -
|
||||
[no] option forceclose X - X X
|
||||
option forwardfor X X X X
|
||||
[no] option http_proxy X X X X
|
||||
option httpchk X - X X
|
||||
option httpclose X X X X
|
||||
[no] option httpclose X X X X
|
||||
option httplog X X X X
|
||||
option logasap X X X -
|
||||
option nolinger X X X X
|
||||
option http_proxy X X X X
|
||||
option persist X - X X
|
||||
option redispatch X - X X
|
||||
[no] option logasap X X X -
|
||||
[no] option nolinger X X X X
|
||||
[no] option persist X - X X
|
||||
[no] option redispatch X - X X
|
||||
option smtpchk X - X X
|
||||
option srvtcpka X - X X
|
||||
[no] option srvtcpka X - X X
|
||||
option ssl-hello-chk X - X X
|
||||
option tcpka X X X X
|
||||
option tcplog X X X X
|
||||
option tcpsplice X X X X
|
||||
option transparent X X X -
|
||||
redisp X - X X
|
||||
redispatch X - X X
|
||||
[no] option tcpsplice X X X X
|
||||
[no] option transparent X X X -
|
||||
redisp X - X X (deprecated)
|
||||
redispatch X - X X (deprecated)
|
||||
reqadd - X X X
|
||||
reqallow - X X X
|
||||
reqdel - X X X
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
extern int cfg_maxpconn;
|
||||
extern int cfg_maxconn;
|
||||
|
||||
int cfg_parse_global(const char *file, int linenum, char **args);
|
||||
int cfg_parse_listen(const char *file, int linenum, char **args);
|
||||
int cfg_parse_global(const char *file, int linenum, char **args, int inv);
|
||||
int cfg_parse_listen(const char *file, int linenum, char **args, int inv);
|
||||
int readcfgfile(const char *file);
|
||||
|
||||
|
||||
|
|
|
@ -90,29 +90,29 @@ static const struct {
|
|||
unsigned int checks;
|
||||
} cfg_opts[] =
|
||||
{
|
||||
#ifdef TPROXY
|
||||
{ "transparent", PR_O_TRANSP, PR_CAP_FE },
|
||||
#endif
|
||||
{ "redispatch", PR_O_REDISP, PR_CAP_BE, 0 },
|
||||
{ "keepalive", PR_O_KEEPALIVE, PR_CAP_NONE, 0 },
|
||||
{ "httpclose", PR_O_HTTP_CLOSE, PR_CAP_FE | PR_CAP_BE, 0 },
|
||||
{ "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0 },
|
||||
{ "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0 },
|
||||
{ "logasap", PR_O_LOGASAP, PR_CAP_FE, 0 },
|
||||
{ "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0 },
|
||||
{ "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0 },
|
||||
{ "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0 },
|
||||
{ "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0 },
|
||||
{ "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0 },
|
||||
{ "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0 },
|
||||
{ "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0 },
|
||||
{ "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0 },
|
||||
{ "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0 },
|
||||
{ "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0 },
|
||||
{ "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0 },
|
||||
{ "forceclose", PR_O_FORCE_CLO, PR_CAP_BE, 0 },
|
||||
{ "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0 },
|
||||
{ "httpclose", PR_O_HTTP_CLOSE, PR_CAP_FE | PR_CAP_BE, 0 },
|
||||
{ "keepalive", PR_O_KEEPALIVE, PR_CAP_NONE, 0 },
|
||||
{ "logasap", PR_O_LOGASAP, PR_CAP_FE, 0 },
|
||||
{ "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0 },
|
||||
{ "persist", PR_O_PERSIST, PR_CAP_BE, 0 },
|
||||
{ "forceclose", PR_O_FORCE_CLO | PR_O_HTTP_CLOSE, PR_CAP_BE, 0 },
|
||||
{ "redispatch", PR_O_REDISP, PR_CAP_BE, 0 },
|
||||
{ "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0 },
|
||||
#ifdef CONFIG_HAP_TCPSPLICE
|
||||
{ "tcpsplice", PR_O_TCPSPLICE , PR_CAP_BE|PR_CAP_FE, LSTCHK_TCPSPLICE|LSTCHK_NETADM },
|
||||
{ "tcpsplice", PR_O_TCPSPLICE, PR_CAP_BE|PR_CAP_FE, LSTCHK_TCPSPLICE|LSTCHK_NETADM },
|
||||
#endif
|
||||
#ifdef TPROXY
|
||||
{ "transparent", PR_O_TRANSP, PR_CAP_FE, 0 },
|
||||
#endif
|
||||
|
||||
{ NULL, 0, 0 }
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
|
@ -261,7 +261,7 @@ int warnifnotcap(struct proxy *proxy, int cap, const char *file, int line, char
|
|||
/*
|
||||
* parse a line in a <global> section. Returns 0 if OK, -1 if error.
|
||||
*/
|
||||
int cfg_parse_global(const char *file, int linenum, char **args)
|
||||
int cfg_parse_global(const char *file, int linenum, char **args, int inv)
|
||||
{
|
||||
|
||||
if (!strcmp(args[0], "global")) { /* new section */
|
||||
|
@ -516,7 +516,7 @@ static void init_default_instance()
|
|||
* Parse a line in a <listen>, <frontend>, <backend> or <ruleset> section.
|
||||
* Returns 0 if OK, -1 if error.
|
||||
*/
|
||||
int cfg_parse_listen(const char *file, int linenum, char **args)
|
||||
int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
||||
{
|
||||
static struct proxy *curproxy = NULL;
|
||||
struct server *newsrv = NULL;
|
||||
|
@ -1145,8 +1145,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
|
|||
else if (!strcmp(args[0], "option")) {
|
||||
int optnum;
|
||||
|
||||
if (*(args[1]) == 0) {
|
||||
Alert("parsing [%s:%d] : '%s' expects an option name.\n", file, linenum, args[0]);
|
||||
if (*(args[1]) == '\0') {
|
||||
Alert("parsing [%s:%d]: '%s' expects an option name.\n",
|
||||
file, linenum, args[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1154,12 +1155,22 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
|
|||
if (!strcmp(args[1], cfg_opts[optnum].name)) {
|
||||
if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL))
|
||||
return 0;
|
||||
curproxy->options |= cfg_opts[optnum].val;
|
||||
global.last_checks |= cfg_opts[optnum].checks;
|
||||
|
||||
if (!inv)
|
||||
curproxy->options |= cfg_opts[optnum].val;
|
||||
else
|
||||
curproxy->options &= ~cfg_opts[optnum].val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (inv) {
|
||||
Alert("parsing [%s:%d]: negation is not supported for option '%s'.\n",
|
||||
file, linenum, args[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcmp(args[1], "httplog"))
|
||||
/* generate a complete HTTP log */
|
||||
curproxy->to_log |= LW_DATE | LW_CLIP | LW_SVID | LW_REQ | LW_PXID | LW_RESP | LW_BYTES;
|
||||
|
@ -1287,6 +1298,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
|
|||
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
|
||||
return 0;
|
||||
|
||||
Warning("parsing [%s:%d]: keyword '%s' is deprecated, please use 'option redispatch' instead.\n",
|
||||
file, linenum, args[0]);
|
||||
|
||||
/* enable reconnections to dispatch */
|
||||
curproxy->options |= PR_O_REDISP;
|
||||
}
|
||||
|
@ -2406,7 +2420,7 @@ int readcfgfile(const char *file)
|
|||
init_default_instance();
|
||||
|
||||
while (fgets(thisline, sizeof(thisline), f) != NULL) {
|
||||
int arg;
|
||||
int arg, inv = 0 ;
|
||||
char *end;
|
||||
char *args[MAX_LINE_ARGS + 1];
|
||||
char *line = thisline;
|
||||
|
@ -2502,6 +2516,17 @@ int readcfgfile(const char *file)
|
|||
args[arg] = line;
|
||||
}
|
||||
|
||||
if (!strcmp(args[0], "no")) {
|
||||
inv = 1;
|
||||
for (arg=0; *args[arg+1]; arg++)
|
||||
args[arg] = args[arg+1]; // shift args after inversion
|
||||
}
|
||||
|
||||
if (inv && strcmp(args[0], "option")) {
|
||||
Alert("parsing [%s:%d]: negation currently supported only for options.\n", file, linenum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcmp(args[0], "listen") ||
|
||||
!strcmp(args[0], "frontend") ||
|
||||
!strcmp(args[0], "backend") ||
|
||||
|
@ -2514,11 +2539,11 @@ int readcfgfile(const char *file)
|
|||
|
||||
switch (confsect) {
|
||||
case CFG_LISTEN:
|
||||
if (cfg_parse_listen(file, linenum, args) < 0)
|
||||
if (cfg_parse_listen(file, linenum, args, inv) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case CFG_GLOBAL:
|
||||
if (cfg_parse_global(file, linenum, args) < 0)
|
||||
if (cfg_parse_global(file, linenum, args, inv) < 0)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
|
@ -2849,12 +2874,28 @@ int readcfgfile(const char *file)
|
|||
|
||||
curproxy = curproxy->next;
|
||||
}
|
||||
|
||||
if (cfgerr > 0) {
|
||||
Alert("Errors found in configuration file, aborting.\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Recount currently required checks.
|
||||
*/
|
||||
|
||||
for (curproxy=proxy; curproxy; curproxy=curproxy->next) {
|
||||
int optnum;
|
||||
|
||||
for (optnum = 0; cfg_opts[optnum].name; optnum++) {
|
||||
if (!(curproxy->options & cfg_opts[optnum].val))
|
||||
continue;
|
||||
|
||||
global.last_checks |= cfg_opts[optnum].checks;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1795,7 +1795,7 @@ int process_cli(struct session *t)
|
|||
}
|
||||
|
||||
/* We might have to check for "Connection:" */
|
||||
if (((t->fe->options | t->be->options) & PR_O_HTTP_CLOSE) &&
|
||||
if (((t->fe->options | t->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO)) &&
|
||||
!(t->flags & SN_CONN_CLOSED)) {
|
||||
char *cur_ptr, *cur_end, *cur_next;
|
||||
int cur_idx, old_idx, delta, val;
|
||||
|
@ -2005,7 +2005,7 @@ int process_cli(struct session *t)
|
|||
* Note that we do not need to add it in case of HTTP/1.0.
|
||||
*/
|
||||
if (!(t->flags & SN_CONN_CLOSED) &&
|
||||
((t->fe->options | t->be->options) & PR_O_HTTP_CLOSE)) {
|
||||
((t->fe->options | t->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO))) {
|
||||
if ((unlikely(msg->sl.rq.v_l != 8) ||
|
||||
unlikely(req->data[msg->som + msg->sl.rq.v + 7] != '0')) &&
|
||||
unlikely(http_header_add_tail2(req, &txn->req, &txn->hdr_idx,
|
||||
|
@ -2914,7 +2914,7 @@ int process_srv(struct session *t)
|
|||
}
|
||||
|
||||
/* We might have to check for "Connection:" */
|
||||
if (((t->fe->options | t->be->options) & PR_O_HTTP_CLOSE) &&
|
||||
if (((t->fe->options | t->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO)) &&
|
||||
!(t->flags & SN_CONN_CLOSED)) {
|
||||
char *cur_ptr, *cur_end, *cur_next;
|
||||
int cur_idx, old_idx, delta, val;
|
||||
|
@ -3059,7 +3059,7 @@ int process_srv(struct session *t)
|
|||
* Note that we do not need to add it in case of HTTP/1.0.
|
||||
*/
|
||||
if (!(t->flags & SN_CONN_CLOSED) &&
|
||||
((t->fe->options | t->be->options) & PR_O_HTTP_CLOSE)) {
|
||||
((t->fe->options | t->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO))) {
|
||||
if ((unlikely(msg->sl.st.v_l != 8) ||
|
||||
unlikely(req->data[msg->som + 7] != '0')) &&
|
||||
unlikely(http_header_add_tail2(rep, &txn->rsp, &txn->hdr_idx,
|
||||
|
|
Loading…
Reference in New Issue