From: Willy Tarreau Date: Thu, 28 Jan 2010 17:10:50 +0000 (+0100) Subject: [MINOR] prepare req_*/rsp_* to receive a condition X-Git-Tag: v1.4-rc1~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f4f04125d4db81026895258dfde3747d1fbfb8b7;p=thirdparty%2Fhaproxy.git [MINOR] prepare req_*/rsp_* to receive a condition It will be very handy to be able to pass conditions to req_* and rsp_*. For now, we just add the pointer to the condition in the affected structs. --- diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h index fa0537ce89..e89ffe0aec 100644 --- a/include/common/mini-clist.h +++ b/include/common/mini-clist.h @@ -39,6 +39,13 @@ struct wordlist { char *s; }; +/* this is the same as above with an additional pointer to a condition. */ +struct cond_wordlist { + struct list list; + void *cond; + 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/common/regex.h b/include/common/regex.h index bc86bbdf31..60c7f422db 100644 --- a/include/common/regex.h +++ b/include/common/regex.h @@ -1,23 +1,23 @@ /* - include/common/regex.h - This file defines everything related to regular expressions. - - Copyright (C) 2000-2006 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/regex.h + * This file defines everything related to regular expressions. + * + * 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_REGEX_H #define _COMMON_REGEX_H @@ -45,6 +45,7 @@ struct hdr_exp { const regex_t *preg; /* expression to look for */ int action; /* ACT_ALLOW, ACT_REPLACE, ACT_REMOVE, ACT_DENY */ const char *replace; /* expression to set instead */ + void *cond; /* a possible condition or NULL */ }; extern regmatch_t pmatch[MAX_MATCH]; @@ -52,7 +53,7 @@ extern regmatch_t pmatch[MAX_MATCH]; int exp_replace(char *dst, char *src, const char *str, const regmatch_t *matches); const char *check_replace_string(const char *str); const char *chain_regex(struct hdr_exp **head, const regex_t *preg, - int action, const char *replace); + int action, const char *replace, void *cond); #endif /* _COMMON_REGEX_H */ diff --git a/src/cfgparse.c b/src/cfgparse.c index ab82871283..bf2ad2ab4f 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3564,7 +3564,7 @@ stats_error_parsing: goto out; } - err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2])); + err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2]), NULL); if (err) { Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n", file, linenum, *err); @@ -3595,7 +3595,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_REMOVE, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_REMOVE, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */ @@ -3621,7 +3621,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_DENY, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_DENY, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */ @@ -3647,7 +3647,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_PASS, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_PASS, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */ @@ -3673,7 +3673,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_ALLOW, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_ALLOW, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */ @@ -3699,7 +3699,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_TARPIT, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_TARPIT, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqsetbe")) { /* switch the backend from a regex, respecting case */ @@ -3726,7 +3726,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_SETBE, strdup(args[2])); + chain_regex(&curproxy->req_exp, preg, ACT_SETBE, strdup(args[2]), NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqisetbe")) { /* switch the backend from a regex, ignoring case */ @@ -3753,7 +3753,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_SETBE, strdup(args[2])); + chain_regex(&curproxy->req_exp, preg, ACT_SETBE, strdup(args[2]), NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */ @@ -3780,7 +3780,7 @@ stats_error_parsing: goto out; } - err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2])); + err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2]), NULL); if (err) { Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n", file, linenum, *err); @@ -3812,7 +3812,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_REMOVE, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_REMOVE, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */ @@ -3838,7 +3838,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_DENY, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_DENY, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */ @@ -3864,7 +3864,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_PASS, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_PASS, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */ @@ -3890,7 +3890,7 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_ALLOW, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_ALLOW, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */ @@ -3916,11 +3916,11 @@ stats_error_parsing: goto out; } - chain_regex(&curproxy->req_exp, preg, ACT_TARPIT, NULL); + chain_regex(&curproxy->req_exp, preg, ACT_TARPIT, NULL, NULL); warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]); } else if (!strcmp(args[0], "reqadd")) { /* add request header */ - struct wordlist *wl; + struct cond_wordlist *wl; if (curproxy == &defproxy) { Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); @@ -3965,7 +3965,7 @@ stats_error_parsing: goto out; } - err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2])); + err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2]), NULL); if (err) { Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n", file, linenum, *err); @@ -3997,7 +3997,7 @@ stats_error_parsing: goto out; } - err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2])); + err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2]), NULL); if (err) { Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n", file, linenum, *err); @@ -4028,7 +4028,7 @@ stats_error_parsing: goto out; } - err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2])); + err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2]), NULL); if (err) { Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n", file, linenum, *err); @@ -4060,7 +4060,7 @@ stats_error_parsing: goto out; } - err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2])); + err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2]), NULL); if (err) { Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n", file, linenum, *err); @@ -4091,7 +4091,7 @@ stats_error_parsing: goto out; } - err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2])); + err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2]), NULL); if (err) { Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n", file, linenum, *err); @@ -4122,7 +4122,7 @@ stats_error_parsing: goto out; } - err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2])); + err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2]), NULL); if (err) { Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n", file, linenum, *err); @@ -4131,7 +4131,7 @@ stats_error_parsing: } } else if (!strcmp(args[0], "rspadd")) { /* add response header */ - struct wordlist *wl; + struct cond_wordlist *wl; if (curproxy == &defproxy) { Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); diff --git a/src/haproxy.c b/src/haproxy.c index d26b0a72a4..2fdde61414 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -700,6 +700,7 @@ void deinit(void) struct switching_rule *rule, *ruleb; struct redirect_rule *rdr, *rdrb; struct wordlist *wl, *wlb; + struct cond_wordlist *cwl, *cwlb; struct uri_auth *uap, *ua = NULL; struct user_auth *user; int i; @@ -716,16 +717,16 @@ void deinit(void) for (i = 0; i < HTTP_ERR_SIZE; i++) chunk_destroy(&p->errmsg[i]); - list_for_each_entry_safe(wl, wlb, &p->req_add, list) { - LIST_DEL(&wl->list); - free(wl->s); - free(wl); + list_for_each_entry_safe(cwl, cwlb, &p->req_add, list) { + LIST_DEL(&cwl->list); + free(cwl->s); + free(cwl); } - 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(cwl, cwlb, &p->rsp_add, list) { + LIST_DEL(&cwl->list); + free(cwl->s); + free(cwl); } list_for_each_entry_safe(cond, condb, &p->block_cond, list) { diff --git a/src/proto_http.c b/src/proto_http.c index d3c2b52f86..94022c8766 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -2724,7 +2724,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; + struct cond_wordlist *wl; int del_ka, del_cl; if (unlikely(msg->msg_state < HTTP_MSG_BODY)) { @@ -4485,7 +4485,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; - struct wordlist *wl; + struct cond_wordlist *wl; DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n", now_ms, __FUNCTION__, diff --git a/src/regex.c b/src/regex.c index 70093667fa..1455fb4529 100644 --- a/src/regex.c +++ b/src/regex.c @@ -1,7 +1,7 @@ /* * Regex and string management functions. * - * Copyright 2000-2006 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,7 +23,6 @@ regmatch_t pmatch[MAX_MATCH]; /* rm_so, rm_eo for regular expressions */ - int exp_replace(char *dst, char *src, const char *str, const regmatch_t *matches) { char *old_dst = dst; @@ -98,7 +97,7 @@ const char *check_replace_string(const char *str) /* returns the pointer to an error in the replacement string, or NULL if OK */ const char *chain_regex(struct hdr_exp **head, const regex_t *preg, - int action, const char *replace) + int action, const char *replace, void *cond) { struct hdr_exp *exp; @@ -117,6 +116,7 @@ const char *chain_regex(struct hdr_exp **head, const regex_t *preg, exp->preg = preg; exp->replace = replace; exp->action = action; + exp->cond = cond; *head = exp; return NULL;