mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-29 14:50:59 +01:00
[MEDIUM] config: remove the limitation of 10 reqadd/rspadd statements
Now we use a linked list, there is no limit anymore.
This commit is contained in:
parent
97cb780e81
commit
deb9ed8f60
@ -1,23 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
include/common/defaults.h
|
* include/common/defaults.h
|
||||||
Miscellaneous default values.
|
* Miscellaneous default values.
|
||||||
|
*
|
||||||
Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
|
* Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
|
||||||
|
*
|
||||||
This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
License as published by the Free Software Foundation, version 2.1
|
* License as published by the Free Software Foundation, version 2.1
|
||||||
exclusively.
|
* exclusively.
|
||||||
|
*
|
||||||
This library is distributed in the hope that it will be useful,
|
* This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _COMMON_DEFAULTS_H
|
#ifndef _COMMON_DEFAULTS_H
|
||||||
#define _COMMON_DEFAULTS_H
|
#define _COMMON_DEFAULTS_H
|
||||||
@ -57,9 +57,6 @@
|
|||||||
// max # args on a stats socket
|
// max # args on a stats socket
|
||||||
#define MAX_STATS_ARGS 16
|
#define MAX_STATS_ARGS 16
|
||||||
|
|
||||||
// max # of added headers per request
|
|
||||||
#define MAX_NEWHDR 10
|
|
||||||
|
|
||||||
// max # of matches per regexp
|
// max # of matches per regexp
|
||||||
#define MAX_MATCH 10
|
#define MAX_MATCH 10
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* list.h : list manipulation macros and structures.
|
* list.h : list manipulation macros and structures.
|
||||||
* Copyright 2002-2008 Willy Tarreau <w@1wt.eu>
|
* Copyright 2002-2010 Willy Tarreau <w@1wt.eu>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -33,6 +33,12 @@ struct bref {
|
|||||||
struct list *ref; /* pointer to the target's list entry */
|
struct list *ref; /* pointer to the target's list entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* a word list is a generic list with a pointer to a string in each element. */
|
||||||
|
struct wordlist {
|
||||||
|
struct list list;
|
||||||
|
char *s;
|
||||||
|
};
|
||||||
|
|
||||||
/* First undefine some macros which happen to also be defined on OpenBSD,
|
/* First undefine some macros which happen to also be defined on OpenBSD,
|
||||||
* in sys/queue.h, used by sys/event.h
|
* in sys/queue.h, used by sys/event.h
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
* include/types/proxy.h
|
* include/types/proxy.h
|
||||||
* This file defines everything related to proxies.
|
* This file defines everything related to proxies.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
|
* Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -240,7 +240,6 @@ struct proxy {
|
|||||||
int minlvl1, minlvl2; /* minimum log level for each server, 0 by default */
|
int minlvl1, minlvl2; /* minimum log level for each server, 0 by default */
|
||||||
int to_log; /* things to be logged (LW_*) */
|
int to_log; /* things to be logged (LW_*) */
|
||||||
int stop_time; /* date to stop listening, when stopping != 0 (int ticks) */
|
int stop_time; /* date to stop listening, when stopping != 0 (int ticks) */
|
||||||
int nb_reqadd, nb_rspadd;
|
|
||||||
struct hdr_exp *req_exp; /* regular expressions for request headers */
|
struct hdr_exp *req_exp; /* regular expressions for request headers */
|
||||||
struct hdr_exp *rsp_exp; /* regular expressions for response headers */
|
struct hdr_exp *rsp_exp; /* regular expressions for response headers */
|
||||||
int nb_req_cap, nb_rsp_cap; /* # of headers to be captured */
|
int nb_req_cap, nb_rsp_cap; /* # of headers to be captured */
|
||||||
@ -249,7 +248,7 @@ struct proxy {
|
|||||||
struct pool_head *req_cap_pool, /* pools of pre-allocated char ** used to build the sessions */
|
struct pool_head *req_cap_pool, /* pools of pre-allocated char ** used to build the sessions */
|
||||||
*rsp_cap_pool;
|
*rsp_cap_pool;
|
||||||
struct pool_head *hdr_idx_pool; /* pools of pre-allocated int* used for headers indexing */
|
struct pool_head *hdr_idx_pool; /* pools of pre-allocated int* used for headers indexing */
|
||||||
char *req_add[MAX_NEWHDR], *rsp_add[MAX_NEWHDR]; /* headers to be added */
|
struct list req_add, rsp_add; /* headers to be added */
|
||||||
struct pxcounters counters; /* statistics counters */
|
struct pxcounters counters; /* statistics counters */
|
||||||
int grace; /* grace time after stop request */
|
int grace; /* grace time after stop request */
|
||||||
char *check_req; /* HTTP or SSL request to use for PR_O_HTTP_CHK|PR_O_SSL3_CHK */
|
char *check_req; /* HTTP or SSL request to use for PR_O_HTTP_CHK|PR_O_SSL3_CHK */
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Configuration parser
|
* Configuration parser
|
||||||
*
|
*
|
||||||
* Copyright 2000-2009 Willy Tarreau <w@1wt.eu>
|
* Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -327,7 +327,7 @@ int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, ch
|
|||||||
*/
|
*/
|
||||||
int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, char *arg)
|
int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, char *arg)
|
||||||
{
|
{
|
||||||
if (proxy->nb_reqadd) {
|
if (!LIST_ISEMPTY(&proxy->req_add)) {
|
||||||
Warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
|
Warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
|
||||||
file, line, arg);
|
file, line, arg);
|
||||||
return 1;
|
return 1;
|
||||||
@ -796,6 +796,8 @@ static void init_new_proxy(struct proxy *p)
|
|||||||
LIST_INIT(&p->mon_fail_cond);
|
LIST_INIT(&p->mon_fail_cond);
|
||||||
LIST_INIT(&p->switching_rules);
|
LIST_INIT(&p->switching_rules);
|
||||||
LIST_INIT(&p->tcp_req.inspect_rules);
|
LIST_INIT(&p->tcp_req.inspect_rules);
|
||||||
|
LIST_INIT(&p->req_add);
|
||||||
|
LIST_INIT(&p->rsp_add);
|
||||||
|
|
||||||
/* Timeouts are defined as -1 */
|
/* Timeouts are defined as -1 */
|
||||||
proxy_reset_timeouts(p);
|
proxy_reset_timeouts(p);
|
||||||
@ -3592,6 +3594,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
|
warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "reqadd")) { /* add request header */
|
else if (!strcmp(args[0], "reqadd")) { /* add request header */
|
||||||
|
struct wordlist *wl;
|
||||||
|
|
||||||
if (curproxy == &defproxy) {
|
if (curproxy == &defproxy) {
|
||||||
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
@ -3600,19 +3604,15 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
|
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
|
||||||
err_code |= ERR_WARN;
|
err_code |= ERR_WARN;
|
||||||
|
|
||||||
if (curproxy->nb_reqadd >= MAX_NEWHDR) {
|
|
||||||
Alert("parsing [%s:%d] : too many '%s'. Continuing.\n", file, linenum, args[0]);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(args[1]) == 0) {
|
if (*(args[1]) == 0) {
|
||||||
Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
|
Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
curproxy->req_add[curproxy->nb_reqadd++] = strdup(args[1]);
|
wl = calloc(1, sizeof(*wl));
|
||||||
|
wl->s = strdup(args[1]);
|
||||||
|
LIST_ADDQ(&curproxy->req_add, &wl->list);
|
||||||
warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
|
warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
|
else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
|
||||||
@ -3800,6 +3800,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "rspadd")) { /* add response header */
|
else if (!strcmp(args[0], "rspadd")) { /* add response header */
|
||||||
|
struct wordlist *wl;
|
||||||
|
|
||||||
if (curproxy == &defproxy) {
|
if (curproxy == &defproxy) {
|
||||||
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
@ -3808,19 +3810,15 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
|
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
|
||||||
err_code |= ERR_WARN;
|
err_code |= ERR_WARN;
|
||||||
|
|
||||||
if (curproxy->nb_rspadd >= MAX_NEWHDR) {
|
|
||||||
Alert("parsing [%s:%d] : too many '%s'. Continuing.\n", file, linenum, args[0]);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(args[1]) == 0) {
|
if (*(args[1]) == 0) {
|
||||||
Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
|
Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
curproxy->rsp_add[curproxy->nb_rspadd++] = strdup(args[1]);
|
wl = calloc(1, sizeof(*wl));
|
||||||
|
wl->s = strdup(args[1]);
|
||||||
|
LIST_ADDQ(&curproxy->rsp_add, &wl->list);
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "errorloc") ||
|
else if (!strcmp(args[0], "errorloc") ||
|
||||||
!strcmp(args[0], "errorloc302") ||
|
!strcmp(args[0], "errorloc302") ||
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* HA-Proxy : High Availability-enabled HTTP/TCP proxy
|
* HA-Proxy : High Availability-enabled HTTP/TCP proxy
|
||||||
* Copyright 2000-2009 Willy Tarreau <w@1wt.eu>.
|
* Copyright 2000-2010 Willy Tarreau <w@1wt.eu>.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -23,15 +23,6 @@
|
|||||||
*
|
*
|
||||||
* ChangeLog has moved to the CHANGELOG file.
|
* ChangeLog has moved to the CHANGELOG file.
|
||||||
*
|
*
|
||||||
* TODO:
|
|
||||||
* - handle properly intermediate incomplete server headers. Done ?
|
|
||||||
* - handle hot-reconfiguration
|
|
||||||
* - fix client/server state transition when server is in connect or headers state
|
|
||||||
* and client suddenly disconnects. The server *should* switch to SHUT_WR, but
|
|
||||||
* still handle HTTP headers.
|
|
||||||
* - remove MAX_NEWHDR
|
|
||||||
* - cut this huge file into several ones
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -706,6 +697,7 @@ void deinit(void)
|
|||||||
struct acl *acl, *aclb;
|
struct acl *acl, *aclb;
|
||||||
struct switching_rule *rule, *ruleb;
|
struct switching_rule *rule, *ruleb;
|
||||||
struct redirect_rule *rdr, *rdrb;
|
struct redirect_rule *rdr, *rdrb;
|
||||||
|
struct wordlist *wl, *wlb;
|
||||||
struct uri_auth *uap, *ua = NULL;
|
struct uri_auth *uap, *ua = NULL;
|
||||||
struct user_auth *user;
|
struct user_auth *user;
|
||||||
int i;
|
int i;
|
||||||
@ -722,11 +714,17 @@ void deinit(void)
|
|||||||
for (i = 0; i < HTTP_ERR_SIZE; i++)
|
for (i = 0; i < HTTP_ERR_SIZE; i++)
|
||||||
chunk_destroy(&p->errmsg[i]);
|
chunk_destroy(&p->errmsg[i]);
|
||||||
|
|
||||||
for (i = 0; i < p->nb_reqadd; i++)
|
list_for_each_entry_safe(wl, wlb, &p->req_add, list) {
|
||||||
free(p->req_add[i]);
|
LIST_DEL(&wl->list);
|
||||||
|
free(wl->s);
|
||||||
|
free(wl);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < p->nb_rspadd; i++)
|
list_for_each_entry_safe(wl, wlb, &p->rsp_add, list) {
|
||||||
free(p->rsp_add[i]);
|
LIST_DEL(&wl->list);
|
||||||
|
free(wl->s);
|
||||||
|
free(wl);
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(cond, condb, &p->block_cond, list) {
|
list_for_each_entry_safe(cond, condb, &p->block_cond, list) {
|
||||||
LIST_DEL(&cond->list);
|
LIST_DEL(&cond->list);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* HTTP protocol analyzer
|
* HTTP protocol analyzer
|
||||||
*
|
*
|
||||||
* Copyright 2000-2009 Willy Tarreau <w@1wt.eu>
|
* Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -2515,6 +2515,7 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
|
|||||||
struct http_msg *msg = &txn->req;
|
struct http_msg *msg = &txn->req;
|
||||||
struct acl_cond *cond;
|
struct acl_cond *cond;
|
||||||
struct redirect_rule *rule;
|
struct redirect_rule *rule;
|
||||||
|
struct wordlist *wl;
|
||||||
int cur_idx;
|
int cur_idx;
|
||||||
|
|
||||||
if (unlikely(msg->msg_state < HTTP_MSG_BODY)) {
|
if (unlikely(msg->msg_state < HTTP_MSG_BODY)) {
|
||||||
@ -2674,11 +2675,8 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
|
|||||||
} /* if must close keep-alive */
|
} /* if must close keep-alive */
|
||||||
|
|
||||||
/* add request headers from the rule sets in the same order */
|
/* add request headers from the rule sets in the same order */
|
||||||
for (cur_idx = 0; cur_idx < px->nb_reqadd; cur_idx++) {
|
list_for_each_entry(wl, &px->req_add, list) {
|
||||||
if (unlikely(http_header_add_tail(req,
|
if (unlikely(http_header_add_tail(req, &txn->req, &txn->hdr_idx, wl->s) < 0))
|
||||||
&txn->req,
|
|
||||||
&txn->hdr_idx,
|
|
||||||
px->req_add[cur_idx]) < 0))
|
|
||||||
goto return_bad_req;
|
goto return_bad_req;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4015,7 +4013,7 @@ int http_process_res_common(struct session *t, struct buffer *rep, int an_bit, s
|
|||||||
struct http_txn *txn = &t->txn;
|
struct http_txn *txn = &t->txn;
|
||||||
struct http_msg *msg = &txn->rsp;
|
struct http_msg *msg = &txn->rsp;
|
||||||
struct proxy *cur_proxy;
|
struct proxy *cur_proxy;
|
||||||
int cur_idx;
|
struct wordlist *wl;
|
||||||
int conn_ka = 0, conn_cl = 0;
|
int conn_ka = 0, conn_cl = 0;
|
||||||
int must_close = 0;
|
int must_close = 0;
|
||||||
int must_del_close = 0, must_keep = 0;
|
int must_del_close = 0, must_keep = 0;
|
||||||
@ -4228,11 +4226,10 @@ int http_process_res_common(struct session *t, struct buffer *rep, int an_bit, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* add response headers from the rule sets in the same order */
|
/* add response headers from the rule sets in the same order */
|
||||||
for (cur_idx = 0; cur_idx < rule_set->nb_rspadd; cur_idx++) {
|
list_for_each_entry(wl, &rule_set->rsp_add, list) {
|
||||||
if (txn->status < 200)
|
if (txn->status < 200)
|
||||||
break;
|
break;
|
||||||
if (unlikely(http_header_add_tail(rep, &txn->rsp, &txn->hdr_idx,
|
if (unlikely(http_header_add_tail(rep, &txn->rsp, &txn->hdr_idx, wl->s) < 0))
|
||||||
rule_set->rsp_add[cur_idx]) < 0))
|
|
||||||
goto return_bad_resp;
|
goto return_bad_resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user