[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 cada729..9b8d806 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 7d16b5e..fa0537c 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 <w@1wt.eu>
+ * Copyright 2002-2010 Willy Tarreau <w@1wt.eu>
*
*/
@@ -33,6 +33,12 @@
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 54190ee..6130cf5 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 @@
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 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 75ae188..10013fe 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1,7 +1,7 @@
/*
* 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
* modify it under the terms of the GNU General Public License
@@ -327,7 +327,7 @@
*/
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 @@
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 @@
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 @@
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 <header> 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 @@
}
}
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 @@
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 <header> 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 48f23d6..d645ee0 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 <w@1wt.eu>.
+ * Copyright 2000-2010 Willy Tarreau <w@1wt.eu>.
*
* 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 <stdio.h>
@@ -706,6 +697,7 @@
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 @@
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 5d70000..66024a7 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1,7 +1,7 @@
/*
* 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
* modify it under the terms of the GNU General Public License
@@ -2515,6 +2515,7 @@
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 @@
} /* 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 @@
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 @@
}
/* 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;
}