151
151
{ "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
152
152
{ "http-use-proxy-header", PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
153
153
{ "http-pretend-keepalive", PR_O2_FAKE_KA, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
154
{ "http-no-delay", PR_O2_NODELAY, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
154
155
{ NULL, 0, 0, 0 }
905
908
if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
906
909
/* prepare error message just in case */
907
snprintf(trash, sizeof(trash),
910
snprintf(trash, trashlen,
908
911
"error near '%s' in '%s' section", args[0], "global");
909
rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, trash, sizeof(trash));
912
rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, trash, trashlen);
911
914
Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
912
915
err_code |= ERR_ALERT | ERR_FATAL;
1204
1212
curproxy->check_len = defproxy.check_len;
1214
if (defproxy.expect_str) {
1215
curproxy->expect_str = strdup(defproxy.expect_str);
1216
if (defproxy.expect_regex) {
1217
/* note: this regex is known to be valid */
1218
curproxy->expect_regex = calloc(1, sizeof(regex_t));
1219
regcomp(curproxy->expect_regex, defproxy.expect_str, REG_EXTENDED);
1223
curproxy->ck_opts = defproxy.ck_opts;
1206
1224
if (defproxy.cookie_name)
1207
1225
curproxy->cookie_name = strdup(defproxy.cookie_name);
1208
1226
curproxy->cookie_len = defproxy.cookie_len;
1300
1318
defproxy.fwdfor_hdr_len = 0;
1301
1319
free(defproxy.orgto_hdr_name);
1302
1320
defproxy.orgto_hdr_len = 0;
1321
free(defproxy.server_id_hdr_name);
1322
defproxy.server_id_hdr_len = 0;
1323
free(defproxy.expect_str);
1324
if (defproxy.expect_regex) regfree(defproxy.expect_regex);
1304
1326
for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
1305
1327
chunk_destroy(&defproxy.errmsg[rc]);
1700
1721
while (*(args[cur_arg])) {
1701
1722
if (!strcmp(args[cur_arg], "rewrite")) {
1702
curproxy->options |= PR_O_COOK_RW;
1723
curproxy->ck_opts |= PR_CK_RW;
1704
1725
else if (!strcmp(args[cur_arg], "indirect")) {
1705
curproxy->options |= PR_O_COOK_IND;
1726
curproxy->ck_opts |= PR_CK_IND;
1707
1728
else if (!strcmp(args[cur_arg], "insert")) {
1708
curproxy->options |= PR_O_COOK_INS;
1729
curproxy->ck_opts |= PR_CK_INS;
1710
1731
else if (!strcmp(args[cur_arg], "nocache")) {
1711
curproxy->options |= PR_O_COOK_NOC;
1732
curproxy->ck_opts |= PR_CK_NOC;
1713
1734
else if (!strcmp(args[cur_arg], "postonly")) {
1714
curproxy->options |= PR_O_COOK_POST;
1735
curproxy->ck_opts |= PR_CK_POST;
1716
1737
else if (!strcmp(args[cur_arg], "preserve")) {
1717
curproxy->options2 |= PR_O2_COOK_PSV;
1738
curproxy->ck_opts |= PR_CK_PSV;
1719
1740
else if (!strcmp(args[cur_arg], "prefix")) {
1720
curproxy->options |= PR_O_COOK_PFX;
1741
curproxy->ck_opts |= PR_CK_PFX;
1743
else if (!strcmp(args[cur_arg], "httponly")) {
1744
curproxy->ck_opts |= PR_CK_HTTPONLY;
1746
else if (!strcmp(args[cur_arg], "secure")) {
1747
curproxy->ck_opts |= PR_CK_SECURE;
1722
1749
else if (!strcmp(args[cur_arg], "domain")) {
1723
1750
if (!*args[cur_arg + 1]) {
1814
if (!POWEROF2(curproxy->options & (PR_O_COOK_RW|PR_O_COOK_IND))) {
1841
if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
1815
1842
Alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
1816
1843
file, linenum);
1817
1844
err_code |= ERR_ALERT | ERR_FATAL;
1820
if (!POWEROF2(curproxy->options & (PR_O_COOK_RW|PR_O_COOK_INS|PR_O_COOK_PFX))) {
1847
if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
1821
1848
Alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
1822
1849
file, linenum);
1823
1850
err_code |= ERR_ALERT | ERR_FATAL;
1826
if ((curproxy->options2 & PR_O2_COOK_PSV) && !(curproxy->options & (PR_O_COOK_INS|PR_O_COOK_IND))) {
1853
if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
1827
1854
Alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
1828
1855
file, linenum);
1829
1856
err_code |= ERR_ALERT | ERR_FATAL;
2072
2099
err_code |= warnif_cond_requires_resp(req_acl->cond, file, linenum);
2073
2100
LIST_ADDQ(&curproxy->req_acl, &req_acl->list);
2102
else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
2103
/* set the header name and length into the proxy structure */
2104
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2105
err_code |= ERR_WARN;
2108
Alert("parsing [%s:%d] : '%s' requires a header string.\n",
2109
file, linenum, args[0]);
2110
err_code |= ERR_ALERT | ERR_FATAL;
2114
/* set the desired header name */
2115
free(curproxy->server_id_hdr_name);
2116
curproxy->server_id_hdr_name = strdup(args[1]);
2117
curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
2075
2119
else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
2076
2120
if (curproxy == &defproxy) {
2077
2121
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2173
2217
code = atol(args[cur_arg]);
2174
if (code < 301 || code > 303) {
2175
Alert("parsing [%s:%d] : '%s': unsupported HTTP code '%d'.\n",
2176
file, linenum, args[0], code);
2218
if (code < 301 || code > 308 || (code > 303 && code < 307)) {
2219
Alert("parsing [%s:%d] : '%s': unsupported HTTP code '%s' (must be one of 301, 302, 303, 307 or 308).\n",
2220
file, linenum, args[0], args[cur_arg]);
2177
2221
err_code |= ERR_ALERT | ERR_FATAL;
3000
3046
curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
3001
3047
curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
3049
} else if (!strcmp(args[cur_arg], "if-none")) {
3050
curproxy->options2 &= ~PR_O2_FF_ALWAYS;
3004
3053
/* unknown suboption - catchall */
3005
Alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
3054
Alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
3006
3055
file, linenum, args[0], args[1]);
3007
3056
err_code |= ERR_ALERT | ERR_FATAL;
3022
3071
curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
3023
3072
curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
3025
/* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
3074
/* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
3027
3076
while (*(args[cur_arg])) {
3028
3077
if (!strcmp(args[cur_arg], "except")) {
3152
3203
curproxy->options2 |= PR_O2_EXP_RSTS;
3204
free(curproxy->expect_str);
3205
if (curproxy->expect_regex) regfree(curproxy->expect_regex);
3206
curproxy->expect_str = strdup(args[cur_arg + 1]);
3153
3207
curproxy->expect_regex = calloc(1, sizeof(regex_t));
3154
3208
if (regcomp(curproxy->expect_regex, args[cur_arg + 1], REG_EXTENDED) != 0) {
3155
3209
Alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s'.\n",
3168
3222
curproxy->options2 |= PR_O2_EXP_RSTR;
3223
free(curproxy->expect_str);
3224
if (curproxy->expect_regex) regfree(curproxy->expect_regex);
3225
curproxy->expect_str = strdup(args[cur_arg + 1]);
3169
3226
curproxy->expect_regex = calloc(1, sizeof(regex_t));
3170
3227
if (regcomp(curproxy->expect_regex, args[cur_arg + 1], REG_EXTENDED) != 0) {
3171
3228
Alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s'.\n",
3302
3359
err_code |= ERR_WARN;
3304
3361
memcpy(trash, "error near 'balance'", 21);
3305
if (backend_parse_balance((const char **)args + 1, trash, sizeof(trash), curproxy) < 0) {
3362
if (backend_parse_balance((const char **)args + 1, trash, trashlen, curproxy) < 0) {
3306
3363
Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
3307
3364
err_code |= ERR_ALERT | ERR_FATAL;
4530
4581
if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
4531
4582
/* prepare error message just in case */
4532
snprintf(trash, sizeof(trash),
4583
snprintf(trash, trashlen,
4533
4584
"error near '%s' in %s section", args[0], cursection);
4534
rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, trash, sizeof(trash));
4585
rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, trash, trashlen);
4536
4587
Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
4537
4588
err_code |= ERR_ALERT | ERR_FATAL;
5312
5358
/* The small pools required for the capture lists */
5313
if (curproxy->nb_req_cap)
5314
curproxy->req_cap_pool = create_pool("ptrcap",
5315
curproxy->nb_req_cap * sizeof(char *),
5317
if (curproxy->nb_rsp_cap)
5318
curproxy->rsp_cap_pool = create_pool("ptrcap",
5319
curproxy->nb_rsp_cap * sizeof(char *),
5359
if (curproxy->nb_req_cap) {
5360
if (curproxy->mode == PR_MODE_HTTP) {
5361
curproxy->req_cap_pool = create_pool("ptrcap",
5362
curproxy->nb_req_cap * sizeof(char *),
5365
Warning("config : 'capture request header' ignored for %s '%s' as it requires HTTP mode.\n",
5366
proxy_type_str(curproxy), curproxy->id);
5367
err_code |= ERR_WARN;
5368
curproxy->to_log &= ~LW_REQHDR;
5369
curproxy->nb_req_cap = 0;
5373
if (curproxy->nb_rsp_cap) {
5374
if (curproxy->mode == PR_MODE_HTTP) {
5375
curproxy->rsp_cap_pool = create_pool("ptrcap",
5376
curproxy->nb_rsp_cap * sizeof(char *),
5379
Warning("config : 'capture response header' ignored for %s '%s' as it requires HTTP mode.\n",
5380
proxy_type_str(curproxy), curproxy->id);
5381
err_code |= ERR_WARN;
5382
curproxy->to_log &= ~LW_REQHDR;
5383
curproxy->nb_rsp_cap = 0;
5322
5387
curproxy->hdr_idx_pool = create_pool("hdr_idx",
5323
5388
MAX_HTTP_HDR * sizeof(struct hdr_idx_elem),
5362
5427
curproxy->lbprm.wmult = 1; /* default weight multiplier */
5363
5428
curproxy->lbprm.wdiv = 1; /* default weight divider */
5431
* If this server supports a maxconn parameter, it needs a dedicated
5432
* tasks to fill the emptied slots when a connection leaves.
5433
* Also, resolve deferred tracking dependency if needed.
5435
newsrv = curproxy->srv;
5436
while (newsrv != NULL) {
5437
if (newsrv->minconn > newsrv->maxconn) {
5438
/* Only 'minconn' was specified, or it was higher than or equal
5439
* to 'maxconn'. Let's turn this into maxconn and clean it, as
5440
* this will avoid further useless expensive computations.
5442
newsrv->maxconn = newsrv->minconn;
5443
} else if (newsrv->maxconn && !newsrv->minconn) {
5444
/* minconn was not specified, so we set it to maxconn */
5445
newsrv->minconn = newsrv->maxconn;
5446
} else if (newsrv->minconn != newsrv->maxconn && !curproxy->fullconn) {
5447
Alert("config : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
5448
proxy_type_str(curproxy), curproxy->id);
5452
if (newsrv->trackit) {
5455
char *pname, *sname;
5457
pname = newsrv->trackit;
5458
sname = strrchr(pname, '/');
5468
px = findproxy(pname, PR_CAP_BE);
5470
Alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
5471
proxy_type_str(curproxy), curproxy->id,
5479
srv = findserver(px, sname);
5481
Alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
5482
proxy_type_str(curproxy), curproxy->id,
5488
if (!(srv->state & SRV_CHECKED)) {
5489
Alert("config : %s '%s', server '%s': unable to use %s/%s for "
5490
"tracking as it does not have checks enabled.\n",
5491
proxy_type_str(curproxy), curproxy->id,
5492
newsrv->id, px->id, srv->id);
5497
if (curproxy != px &&
5498
(curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
5499
Alert("config : %s '%s', server '%s': unable to use %s/%s for"
5500
"tracking: disable-on-404 option inconsistency.\n",
5501
proxy_type_str(curproxy), curproxy->id,
5502
newsrv->id, px->id, srv->id);
5507
/* if the other server is forced disabled, we have to do the same here */
5508
if (srv->state & SRV_MAINTAIN) {
5509
newsrv->state |= SRV_MAINTAIN;
5510
newsrv->state &= ~SRV_RUNNING;
5514
newsrv->tracked = srv;
5515
newsrv->tracknext = srv->tracknext;
5516
srv->tracknext = newsrv;
5518
free(newsrv->trackit);
5519
newsrv->trackit = NULL;
5522
newsrv = newsrv->next;
5365
5525
/* We have to initialize the server lookup mechanism depending
5366
5526
* on what LB algorithm was choosen.
5407
5567
if (curproxy->mode != PR_MODE_HTTP) {
5410
if (curproxy->options & PR_O_COOK_ANY) {
5411
Warning("config : 'cookie' statement ignored for %s '%s' as it requires HTTP mode.\n",
5412
proxy_type_str(curproxy), curproxy->id);
5413
err_code |= ERR_WARN;
5416
5570
if (curproxy->uri_auth) {
5417
5571
Warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
5418
5572
proxy_type_str(curproxy), curproxy->id);
5472
5627
newsrv = curproxy->srv;
5473
5628
while (newsrv != NULL) {
5474
if ((curproxy->mode != PR_MODE_HTTP) && (newsrv->rdr_len || newsrv->cklen)) {
5629
if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
5475
5630
Alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
5476
5631
proxy_type_str(curproxy), curproxy->id);
5635
if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
5636
Warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
5637
proxy_type_str(curproxy), curproxy->id, newsrv->id);
5638
err_code |= ERR_WARN;
5480
5641
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
5481
5642
if (curproxy->mode != PR_MODE_HTTP && newsrv->bind_hdr_occ) {
5482
5643
newsrv->bind_hdr_occ = 0;
5488
5649
newsrv = newsrv->next;
5492
* If this server supports a maxconn parameter, it needs a dedicated
5493
* tasks to fill the emptied slots when a connection leaves.
5494
* Also, resolve deferred tracking dependency if needed.
5496
newsrv = curproxy->srv;
5497
while (newsrv != NULL) {
5498
if (newsrv->minconn > newsrv->maxconn) {
5499
/* Only 'minconn' was specified, or it was higher than or equal
5500
* to 'maxconn'. Let's turn this into maxconn and clean it, as
5501
* this will avoid further useless expensive computations.
5503
newsrv->maxconn = newsrv->minconn;
5504
} else if (newsrv->maxconn && !newsrv->minconn) {
5505
/* minconn was not specified, so we set it to maxconn */
5506
newsrv->minconn = newsrv->maxconn;
5507
} else if (newsrv->minconn != newsrv->maxconn && !curproxy->fullconn) {
5508
Alert("config : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
5509
proxy_type_str(curproxy), curproxy->id);
5513
if (newsrv->trackit) {
5516
char *pname, *sname;
5518
pname = newsrv->trackit;
5519
sname = strrchr(pname, '/');
5529
px = findproxy(pname, PR_CAP_BE);
5531
Alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
5532
proxy_type_str(curproxy), curproxy->id,
5540
srv = findserver(px, sname);
5542
Alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
5543
proxy_type_str(curproxy), curproxy->id,
5549
if (!(srv->state & SRV_CHECKED)) {
5550
Alert("config : %s '%s', server '%s': unable to use %s/%s for "
5551
"tracking as it does not have checks enabled.\n",
5552
proxy_type_str(curproxy), curproxy->id,
5553
newsrv->id, px->id, srv->id);
5558
if (curproxy != px &&
5559
(curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
5560
Alert("config : %s '%s', server '%s': unable to use %s/%s for"
5561
"tracking: disable-on-404 option inconsistency.\n",
5562
proxy_type_str(curproxy), curproxy->id,
5563
newsrv->id, px->id, srv->id);
5568
newsrv->tracked = srv;
5569
newsrv->tracknext = srv->tracknext;
5570
srv->tracknext = newsrv;
5572
free(newsrv->trackit);
5575
newsrv = newsrv->next;
5578
5652
if (curproxy->cap & PR_CAP_FE) {
5579
5653
if (curproxy->tcp_req.inspect_delay ||
5580
5654
!LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))