[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.
This commit is contained in:
Willy Tarreau 2010-01-28 18:10:50 +01:00
parent f1e98b8628
commit f4f04125d4
6 changed files with 64 additions and 55 deletions

View File

@ -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
*/

View File

@ -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 */

View File

@ -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]);

View File

@ -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) {

View File

@ -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__,

View File

@ -1,7 +1,7 @@
/*
* Regex and string management functions.
*
* Copyright 2000-2006 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,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;