From: Willy Tarreau Date: Sun, 3 Jan 2010 20:03:22 +0000 (+0100) Subject: [MEDIUM] config: remove the limitation of 10 reqadd/rspadd statements X-Git-Tag: v1.4-dev5~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=deb9ed8f60eccc0106988fa1cf34ab8e64145034;p=thirdparty%2Fhaproxy.git [MEDIUM] config: remove the limitation of 10 reqadd/rspadd statements Now we use a linked list, there is no limit anymore. --- diff --git a/include/common/defaults.h b/include/common/defaults.h index cada729c3d..9b8d806ecf 100644 --- a/include/common/defaults.h +++ b/include/common/defaults.h @@ -1,23 +1,23 @@ /* - include/common/defaults.h - Miscellaneous default values. - - Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation, version 2.1 - exclusively. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * include/common/defaults.h + * Miscellaneous default values. + * + * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, version 2.1 + * exclusively. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ #ifndef _COMMON_DEFAULTS_H #define _COMMON_DEFAULTS_H @@ -57,9 +57,6 @@ // max # args on a stats socket #define MAX_STATS_ARGS 16 -// max # of added headers per request -#define MAX_NEWHDR 10 - // max # of matches per regexp #define MAX_MATCH 10 diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h index 7d16b5e46b..fa0537ce89 100644 --- a/include/common/mini-clist.h +++ b/include/common/mini-clist.h @@ -1,6 +1,6 @@ /* * list.h : list manipulation macros and structures. - * Copyright 2002-2008 Willy Tarreau + * Copyright 2002-2010 Willy Tarreau * */ @@ -33,6 +33,12 @@ struct bref { 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, * in sys/queue.h, used by sys/event.h */ diff --git a/include/types/proxy.h b/include/types/proxy.h index 54190ee8e5..6130cf5416 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -2,7 +2,7 @@ * include/types/proxy.h * 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 * 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 to_log; /* things to be logged (LW_*) */ 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 *rsp_exp; /* regular expressions for response headers */ 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 */ *rsp_cap_pool; 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 */ 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 */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 75ae1884e5..10013fe46b 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -1,7 +1,7 @@ /* * Configuration parser * - * Copyright 2000-2009 Willy Tarreau + * Copyright 2000-2010 Willy Tarreau * * This program is free software; you can redistribute it and/or * 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) { - 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", file, line, arg); return 1; @@ -796,6 +796,8 @@ static void init_new_proxy(struct proxy *p) LIST_INIT(&p->mon_fail_cond); LIST_INIT(&p->switching_rules); LIST_INIT(&p->tcp_req.inspect_rules); + LIST_INIT(&p->req_add); + LIST_INIT(&p->rsp_add); /* Timeouts are defined as -1 */ 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]); } else if (!strcmp(args[0], "reqadd")) { /* add request header */ + struct wordlist *wl; + if (curproxy == &defproxy) { Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); 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)) 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) { Alert("parsing [%s:%d] : '%s' expects
as an argument.\n", file, linenum, args[0]); err_code |= ERR_ALERT | ERR_FATAL; 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]); } 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 */ + struct wordlist *wl; + if (curproxy == &defproxy) { Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); 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)) 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) { Alert("parsing [%s:%d] : '%s' expects
as an argument.\n", file, linenum, args[0]); err_code |= ERR_ALERT | ERR_FATAL; 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") || !strcmp(args[0], "errorloc302") || diff --git a/src/haproxy.c b/src/haproxy.c index 48f23d67cc..d645ee02ac 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1,6 +1,6 @@ /* * HA-Proxy : High Availability-enabled HTTP/TCP proxy - * Copyright 2000-2009 Willy Tarreau . + * Copyright 2000-2010 Willy Tarreau . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -23,15 +23,6 @@ * * 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 @@ -706,6 +697,7 @@ void deinit(void) struct acl *acl, *aclb; struct switching_rule *rule, *ruleb; struct redirect_rule *rdr, *rdrb; + struct wordlist *wl, *wlb; struct uri_auth *uap, *ua = NULL; struct user_auth *user; int i; @@ -722,11 +714,17 @@ void deinit(void) for (i = 0; i < HTTP_ERR_SIZE; i++) chunk_destroy(&p->errmsg[i]); - for (i = 0; i < p->nb_reqadd; i++) - free(p->req_add[i]); + list_for_each_entry_safe(wl, wlb, &p->req_add, list) { + LIST_DEL(&wl->list); + free(wl->s); + free(wl); + } - for (i = 0; i < p->nb_rspadd; i++) - free(p->rsp_add[i]); + list_for_each_entry_safe(wl, wlb, &p->rsp_add, list) { + LIST_DEL(&wl->list); + free(wl->s); + free(wl); + } list_for_each_entry_safe(cond, condb, &p->block_cond, list) { LIST_DEL(&cond->list); diff --git a/src/proto_http.c b/src/proto_http.c index 5d70000199..66024a7155 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -1,7 +1,7 @@ /* * HTTP protocol analyzer * - * Copyright 2000-2009 Willy Tarreau + * Copyright 2000-2010 Willy Tarreau * * This program is free software; you can redistribute it and/or * 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 acl_cond *cond; struct redirect_rule *rule; + struct wordlist *wl; int cur_idx; 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 */ /* add request headers from the rule sets in the same order */ - for (cur_idx = 0; cur_idx < px->nb_reqadd; cur_idx++) { - if (unlikely(http_header_add_tail(req, - &txn->req, - &txn->hdr_idx, - px->req_add[cur_idx]) < 0)) + list_for_each_entry(wl, &px->req_add, list) { + if (unlikely(http_header_add_tail(req, &txn->req, &txn->hdr_idx, wl->s) < 0)) 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_msg *msg = &txn->rsp; struct proxy *cur_proxy; - int cur_idx; + struct wordlist *wl; int conn_ka = 0, conn_cl = 0; int must_close = 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 */ - 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) break; - if (unlikely(http_header_add_tail(rep, &txn->rsp, &txn->hdr_idx, - rule_set->rsp_add[cur_idx]) < 0)) + if (unlikely(http_header_add_tail(rep, &txn->rsp, &txn->hdr_idx, wl->s) < 0)) goto return_bad_resp; }