Now we use a linked list, there is no limit anymore.
/*
- 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
// 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
/*
* list.h : list manipulation macros and structures.
- * Copyright 2002-2008 Willy Tarreau <w@1wt.eu>
+ * Copyright 2002-2010 Willy Tarreau <w@1wt.eu>
*
*/
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
*/
* 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
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 */
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 */
/*
* 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
*/
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;
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);
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;
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 */
}
}
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;
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") ||
/*
* 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>
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;
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);
/*
* 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
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)) {
} /* 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;
}
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;
}
/* 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;
}