]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] config: remove the limitation of 10 reqadd/rspadd statements
authorWilly Tarreau <w@1wt.eu>
Sun, 3 Jan 2010 20:03:22 +0000 (21:03 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 3 Jan 2010 20:22:14 +0000 (21:22 +0100)
Now we use a linked list, there is no limit anymore.

include/common/defaults.h
include/common/mini-clist.h
include/types/proxy.h
src/cfgparse.c
src/haproxy.c
src/proto_http.c

index cada729c3dfad68e96ee02abcfd0a449de6b2f28..9b8d806ecfc7e822dfa1df19a337766830d106a6 100644 (file)
@@ -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
 
index 7d16b5e46bc226e3fa3407f4dec7c8099af59cb1..fa0537ce896f3a4f1b9de05b593fc730f3fc07c2 100644 (file)
@@ -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 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
  */
index 54190ee8e532bc8d7a6de41a95523743071cd1bc..6130cf5416009eb0a2f1c40db17f58dc08c50040 100644 (file)
@@ -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 */
index 75ae1884e5df311411533a7361c0bfcba287f334..10013fe46bb36e02af0c3b8a9f9656e01b6a7d3a 100644 (file)
@@ -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_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 <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 @@ 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 <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") ||
index 48f23d67cc9af3ef43988e439cb8cd982ac8ac11..d645ee02ac8194b8fa39d76c6d722825c0327e96 100644 (file)
@@ -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
  *
  * 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 @@ 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);
index 5d700001996c331c1b1fda7739395a2ca0291c8a..66024a71552f14a0ef7d96887a39952723c659c3 100644 (file)
@@ -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 @@ 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;
                        }