mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-02 10:12:03 +00:00
MEDIUM: tree-wide: add logformat expressions wrapper
log format expressions are broadly used within the code: once they are parsed from input string, they are converted to a linked list of logformat nodes. We're starting to face some limitations because we're simply storing the converted expression as a generic logformat_node list. The first issue we're facing is that storing logformat expressions that way doesn't allow us to add metadata alongside the list, which is part of the prerequites for implementing log-profiles. Another issue with storing logformat expressions as generic lists of logformat_node elements is that it's starting to become really hard to tell when we rely on logformat expressions or not in the code given that there isn't always a comment near the list declaration or manipulation to indicate that it's relying on logformat expressions under the hood, so this adds some complexity for code maintenance. This patch looks quite impressive due to changes in a lot of header and source files (since logformat expressions are broadly used), but it does a simple thing: it defines the lf_expr structure which itself holds a generic list of logformat nodes, and then declares some helpers to manipulate lf_expr elements and fixes the code so that we now exclusively manipulate logformat_node lists as lf_expr elements outside of log.c. For now, lf_expr struct only contains the list of logformat nodes (no additional metadata), but now that we have dedicated type and helpers, doing so in the future won't be problematic at all and won't require extensive code changes.
This commit is contained in:
parent
7d8f45b647
commit
6810c41f8e
@ -25,6 +25,7 @@
|
||||
#include <haproxy/applet-t.h>
|
||||
#include <haproxy/stick_table-t.h>
|
||||
#include <haproxy/vars-t.h>
|
||||
#include <haproxy/log-t.h>
|
||||
|
||||
struct session;
|
||||
struct stream;
|
||||
@ -141,15 +142,15 @@ struct act_rule {
|
||||
struct {
|
||||
int i; /* integer param (status, nice, loglevel, ..) */
|
||||
struct ist str; /* string param (reason, header name, ...) */
|
||||
struct list fmt; /* log-format compatible expression */
|
||||
struct lf_expr fmt; /* log-format compatible expression */
|
||||
struct my_regex *re; /* used by replace-header/value/uri/path */
|
||||
} http; /* args used by some HTTP rules */
|
||||
struct http_reply *http_reply; /* HTTP response to be used by return/deny/tarpit rules */
|
||||
struct redirect_rule *redir; /* redirect rule or "http-request redirect" */
|
||||
struct {
|
||||
char *ref; /* MAP or ACL file name to update */
|
||||
struct list key; /* pattern to retrieve MAP or ACL key */
|
||||
struct list value; /* pattern to retrieve MAP value */
|
||||
struct lf_expr key; /* pattern to retrieve MAP or ACL key */
|
||||
struct lf_expr value; /* pattern to retrieve MAP value */
|
||||
} map;
|
||||
struct sample_expr *expr;
|
||||
struct {
|
||||
@ -167,7 +168,7 @@ struct act_rule {
|
||||
} timeout;
|
||||
struct hlua_rule *hlua_rule;
|
||||
struct {
|
||||
struct list fmt; /* log-format compatible expression */
|
||||
struct lf_expr fmt; /* log-format compatible expression */
|
||||
struct sample_expr *expr;
|
||||
uint64_t name_hash;
|
||||
enum vars_scope scope;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <haproxy/acl-t.h>
|
||||
#include <haproxy/api-t.h>
|
||||
#include <haproxy/arg-t.h>
|
||||
#include <haproxy/log-t.h>
|
||||
#include <haproxy/fcgi.h>
|
||||
#include <haproxy/filters-t.h>
|
||||
#include <haproxy/regex-t.h>
|
||||
@ -59,7 +60,7 @@ struct fcgi_rule_conf {
|
||||
struct fcgi_rule {
|
||||
enum fcgi_rule_type type;
|
||||
struct ist name; /* name of the parameter/header */
|
||||
struct list value; /* log-format compatible expression, may be empty */
|
||||
struct lf_expr value; /* log-format compatible expression, may be empty */
|
||||
struct acl_cond *cond; /* acl condition to set the param */
|
||||
struct list list;
|
||||
};
|
||||
@ -67,7 +68,7 @@ struct fcgi_rule {
|
||||
/* parameter rule to set/unset a param at the end of the analyzis */
|
||||
struct fcgi_param_rule {
|
||||
struct ist name;
|
||||
struct list *value; /* if empty , unset the parameter */
|
||||
struct lf_expr *value; /* if empty , unset the parameter */
|
||||
struct ebpt_node node;
|
||||
};
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <haproxy/buf-t.h>
|
||||
#include <haproxy/http-t.h>
|
||||
#include <haproxy/log-t.h>
|
||||
#include <haproxy/htx-t.h>
|
||||
|
||||
/* Context used to find/remove an HTTP header. */
|
||||
@ -41,9 +42,9 @@ struct http_hdr_ctx {
|
||||
|
||||
/* Structure used to build the header list of an HTTP reply */
|
||||
struct http_reply_hdr {
|
||||
struct ist name; /* the header name */
|
||||
struct list value; /* the log-format string value */
|
||||
struct list list; /* header chained list */
|
||||
struct ist name; /* the header name */
|
||||
struct lf_expr value; /* the log-format string value */
|
||||
struct list list; /* header linked list */
|
||||
};
|
||||
|
||||
#define HTTP_REPLY_EMPTY 0x00 /* the reply has no payload */
|
||||
@ -60,7 +61,7 @@ struct http_reply {
|
||||
char *ctype; /* The response content-type, may be NULL */
|
||||
struct list hdrs; /* A list of http_reply_hdr */
|
||||
union {
|
||||
struct list fmt; /* A log-format string (type = HTTP_REPLY_LOGFMT) */
|
||||
struct lf_expr fmt; /* A log-format string (type = HTTP_REPLY_LOGFMT) */
|
||||
struct buffer obj; /* A raw string (type = HTTP_REPLY_RAW) */
|
||||
struct buffer *errmsg; /* The error message to use as response (type = HTTP_REPLY_ERRMSG).
|
||||
* may be NULL, if so rely on the proxy error messages */
|
||||
|
@ -168,6 +168,11 @@ struct logformat_node {
|
||||
const struct logformat_tag *tag; // set if ->type == LOG_FMT_TAG
|
||||
};
|
||||
|
||||
/* a full logformat expr made of one or multiple logformat nodes */
|
||||
struct lf_expr {
|
||||
struct list nodes; /* logformat_node list */
|
||||
};
|
||||
|
||||
/* Range of indexes for log sampling. */
|
||||
struct smp_log_range {
|
||||
unsigned int low; /* Low limit of the indexes of this range. */
|
||||
|
@ -64,12 +64,20 @@ void syslog_fd_handler(int fd);
|
||||
int init_log_buffers(void);
|
||||
void deinit_log_buffers(void);
|
||||
|
||||
void lf_expr_init(struct lf_expr *expr);
|
||||
void lf_expr_xfer(struct lf_expr *src, struct lf_expr *dst);
|
||||
void lf_expr_deinit(struct lf_expr *expr);
|
||||
static inline int lf_expr_isempty(const struct lf_expr *expr)
|
||||
{
|
||||
return LIST_ISEMPTY(&expr->nodes);
|
||||
}
|
||||
|
||||
/* Deinitialize log buffers used for syslog messages */
|
||||
void free_logformat_list(struct list *fmt);
|
||||
void free_logformat_node(struct logformat_node *node);
|
||||
|
||||
/* build a log line for the session and an optional stream */
|
||||
int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize, struct list *list_format);
|
||||
int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize, struct lf_expr *lf_expr);
|
||||
|
||||
/*
|
||||
* send a log for the stream when we have enough info about it.
|
||||
@ -85,7 +93,7 @@ void app_log(struct list *loggers, struct buffer *tag, int level, const char *fo
|
||||
/*
|
||||
* add to the logformat linked list
|
||||
*/
|
||||
int add_to_logformat_list(char *start, char *end, int type, struct list *list_format, char **err);
|
||||
int add_to_logformat_list(char *start, char *end, int type, struct lf_expr *lf_expr, char **err);
|
||||
|
||||
ssize_t syslog_applet_append_event(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len);
|
||||
|
||||
@ -94,7 +102,7 @@ ssize_t syslog_applet_append_event(void *ctx, struct ist v1, struct ist v2, size
|
||||
* Tag name are preceded by % and composed by characters [a-zA-Z0-9]* : %tagname
|
||||
* You can set arguments using { } : %{many arguments}tagname
|
||||
*/
|
||||
int parse_logformat_string(const char *str, struct proxy *curproxy, struct list *list_format, int options, int cap, char **err);
|
||||
int parse_logformat_string(const char *str, struct proxy *curproxy, struct lf_expr *lf_expr, int options, int cap, char **err);
|
||||
|
||||
int postresolve_logger_list(struct list *loggers, const char *section, const char *section_name);
|
||||
|
||||
@ -168,9 +176,9 @@ char * get_format_pid_sep2(int format, size_t *len);
|
||||
/*
|
||||
* Builds a log line for the stream (must be valid).
|
||||
*/
|
||||
static inline int build_logline(struct stream *s, char *dst, size_t maxsize, struct list *list_format)
|
||||
static inline int build_logline(struct stream *s, char *dst, size_t maxsize, struct lf_expr *lf_expr)
|
||||
{
|
||||
return sess_build_logline(strm_sess(s), s, dst, maxsize, list_format);
|
||||
return sess_build_logline(strm_sess(s), s, dst, maxsize, lf_expr);
|
||||
}
|
||||
|
||||
struct ist *build_log_header(struct log_header hdr, size_t *nbelem);
|
||||
|
@ -373,12 +373,12 @@ struct proxy {
|
||||
struct proxy *next_stkt_ref; /* Link to the list of proxies which refer to the same stick-table. */
|
||||
|
||||
struct list loggers; /* one per 'log' directive */
|
||||
struct list logformat; /* log_format linked list */
|
||||
struct list logformat_sd; /* log_format linked list for the RFC5424 structured-data part */
|
||||
struct list logformat_error; /* log_format linked list used in case of connection error on the frontend */
|
||||
struct lf_expr logformat; /* log_format linked list */
|
||||
struct lf_expr logformat_sd; /* log_format linked list for the RFC5424 structured-data part */
|
||||
struct lf_expr logformat_error; /* log_format linked list used in case of connection error on the frontend */
|
||||
struct buffer log_tag; /* override default syslog tag */
|
||||
struct ist header_unique_id; /* unique-id header */
|
||||
struct list format_unique_id; /* unique-id format */
|
||||
struct lf_expr format_unique_id; /* unique-id format */
|
||||
int to_log; /* things to be logged (LW_*) */
|
||||
int nb_req_cap, nb_rsp_cap; /* # of headers to be captured */
|
||||
struct cap_hdr *req_cap; /* chained list of request headers to be captured */
|
||||
@ -478,7 +478,7 @@ struct switching_rule {
|
||||
union {
|
||||
struct proxy *backend; /* target backend */
|
||||
char *name; /* target backend name during config parsing */
|
||||
struct list expr; /* logformat expression to use for dynamic rules */
|
||||
struct lf_expr expr; /* logformat expression to use for dynamic rules */
|
||||
} be;
|
||||
char *file;
|
||||
int line;
|
||||
@ -492,7 +492,7 @@ struct server_rule {
|
||||
struct server *ptr; /* target server */
|
||||
char *name; /* target server name during config parsing */
|
||||
} srv;
|
||||
struct list expr; /* logformat expression to use for dynamic rules */
|
||||
struct lf_expr expr; /* logformat expression to use for dynamic rules */
|
||||
char *file;
|
||||
int line;
|
||||
};
|
||||
@ -521,7 +521,7 @@ struct redirect_rule {
|
||||
int type;
|
||||
int rdr_len;
|
||||
char *rdr_str;
|
||||
struct list rdr_fmt;
|
||||
struct lf_expr rdr_fmt;
|
||||
int code;
|
||||
unsigned int flags;
|
||||
int cookie_len;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <haproxy/task-t.h>
|
||||
#include <haproxy/thread-t.h>
|
||||
#include <haproxy/event_hdl-t.h>
|
||||
#include <haproxy/log-t.h>
|
||||
#include <haproxy/tools-t.h>
|
||||
|
||||
|
||||
@ -269,7 +270,7 @@ enum __attribute__((__packed__)) srv_ws_mode {
|
||||
*/
|
||||
struct srv_pp_tlv_list {
|
||||
struct list list;
|
||||
struct list fmt;
|
||||
struct lf_expr fmt;
|
||||
char *fmt_string;
|
||||
unsigned char type;
|
||||
};
|
||||
|
@ -69,7 +69,7 @@ void stream_shutdown(struct stream *stream, int why);
|
||||
void stream_dump_and_crash(enum obj_type *obj, int rate);
|
||||
void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const char *pfx, uint32_t anon_key);
|
||||
|
||||
struct ist stream_generate_unique_id(struct stream *strm, struct list *format);
|
||||
struct ist stream_generate_unique_id(struct stream *strm, struct lf_expr *format);
|
||||
|
||||
void stream_process_counters(struct stream *s);
|
||||
void sess_change_server(struct stream *strm, struct server *newsrv);
|
||||
|
@ -134,9 +134,9 @@ struct tcpcheck_connect {
|
||||
};
|
||||
|
||||
struct tcpcheck_http_hdr {
|
||||
struct ist name; /* the header name */
|
||||
struct list value; /* the log-format string value */
|
||||
struct list list; /* header chained list */
|
||||
struct ist name; /* the header name */
|
||||
struct lf_expr value; /* the log-format string value */
|
||||
struct list list; /* header linked list */
|
||||
};
|
||||
|
||||
struct tcpcheck_codes {
|
||||
@ -147,20 +147,20 @@ struct tcpcheck_codes {
|
||||
struct tcpcheck_send {
|
||||
enum tcpcheck_send_type type;
|
||||
union {
|
||||
struct ist data; /* an ASCII string or a binary sequence */
|
||||
struct list fmt; /* an ASCII or hexa log-format string */
|
||||
struct ist data; /* an ASCII string or a binary sequence */
|
||||
struct lf_expr fmt; /* an ASCII or hexa log-format string */
|
||||
struct {
|
||||
unsigned int flags; /* TCPCHK_SND_HTTP_FL_* */
|
||||
struct http_meth meth; /* the HTTP request method */
|
||||
union {
|
||||
struct ist uri; /* the HTTP request uri is a string */
|
||||
struct list uri_fmt; /* or a log-format string */
|
||||
struct lf_expr uri_fmt; /* or a log-format string */
|
||||
};
|
||||
struct ist vsn; /* the HTTP request version string */
|
||||
struct list hdrs; /* the HTTP request header list */
|
||||
union {
|
||||
struct ist body; /* the HTTP request payload is a string */
|
||||
struct list body_fmt; /* or a log-format string */
|
||||
struct lf_expr body_fmt;/* or a log-format string */
|
||||
};
|
||||
} http; /* Info about the HTTP request to send */
|
||||
};
|
||||
@ -173,16 +173,16 @@ struct tcpcheck_expect {
|
||||
struct ist data; /* Matching a literal string / binary anywhere in the response. */
|
||||
struct my_regex *regex; /* Matching a regex pattern. */
|
||||
struct tcpcheck_codes codes; /* Matching a list of codes */
|
||||
struct list fmt; /* Matching a log-format string / binary */
|
||||
struct lf_expr fmt; /* Matching a log-format string / binary */
|
||||
struct {
|
||||
union {
|
||||
struct ist name;
|
||||
struct list name_fmt;
|
||||
struct lf_expr name_fmt;
|
||||
struct my_regex *name_re;
|
||||
};
|
||||
union {
|
||||
struct ist value;
|
||||
struct list value_fmt;
|
||||
struct lf_expr value_fmt;
|
||||
struct my_regex *value_re;
|
||||
};
|
||||
} hdr; /* Matching a header pattern */
|
||||
@ -196,9 +196,9 @@ struct tcpcheck_expect {
|
||||
enum healthcheck_status ok_status; /* The healthcheck status to use on success (default: L7OKD) */
|
||||
enum healthcheck_status err_status; /* The healthcheck status to use on error (default: L7RSP) */
|
||||
enum healthcheck_status tout_status; /* The healthcheck status to use on timeout (default: L7TOUT) */
|
||||
struct list onerror_fmt; /* log-format string to use as comment on error */
|
||||
struct list onsuccess_fmt; /* log-format string to use as comment on success (if last rule) */
|
||||
struct sample_expr *status_expr; /* sample expr to determine the check status code */
|
||||
struct lf_expr onerror_fmt; /* log-format string to use as comment on error */
|
||||
struct lf_expr onsuccess_fmt; /* log-format string to use as comment on success (if last rule) */
|
||||
struct sample_expr *status_expr; /* sample expr to determine the check status code */
|
||||
};
|
||||
|
||||
struct tcpcheck_action_kw {
|
||||
|
@ -3127,7 +3127,7 @@ init_proxies_list_stage1:
|
||||
* parsing is cancelled and be.name is restored to be resolved.
|
||||
*/
|
||||
pxname = rule->be.name;
|
||||
LIST_INIT(&rule->be.expr);
|
||||
lf_expr_init(&rule->be.expr);
|
||||
curproxy->conf.args.ctx = ARGC_UBK;
|
||||
curproxy->conf.args.file = rule->file;
|
||||
curproxy->conf.args.line = rule->line;
|
||||
@ -3139,10 +3139,10 @@ init_proxies_list_stage1:
|
||||
cfgerr++;
|
||||
continue;
|
||||
}
|
||||
node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
|
||||
node = LIST_NEXT(&rule->be.expr.nodes, struct logformat_node *, list);
|
||||
|
||||
if (!LIST_ISEMPTY(&rule->be.expr)) {
|
||||
if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
|
||||
if (!lf_expr_isempty(&rule->be.expr)) {
|
||||
if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr.nodes) {
|
||||
rule->dynamic = 1;
|
||||
free(pxname);
|
||||
/* backend is not yet known so we cannot assume its type,
|
||||
@ -3155,8 +3155,7 @@ init_proxies_list_stage1:
|
||||
/* Only one element in the list, a simple string: free the expression and
|
||||
* fall back to static rule
|
||||
*/
|
||||
LIST_DELETE(&node->list);
|
||||
free_logformat_node(node);
|
||||
lf_expr_deinit(&rule->be.expr);
|
||||
}
|
||||
|
||||
rule->dynamic = 0;
|
||||
@ -3204,7 +3203,7 @@ init_proxies_list_stage1:
|
||||
* to a static rule, thus the parsing is cancelled and we fall back to setting srv.ptr.
|
||||
*/
|
||||
server_name = srule->srv.name;
|
||||
LIST_INIT(&srule->expr);
|
||||
lf_expr_init(&srule->expr);
|
||||
curproxy->conf.args.ctx = ARGC_USRV;
|
||||
err = NULL;
|
||||
if (!parse_logformat_string(server_name, curproxy, &srule->expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
|
||||
@ -3214,10 +3213,10 @@ init_proxies_list_stage1:
|
||||
cfgerr++;
|
||||
continue;
|
||||
}
|
||||
node = LIST_NEXT(&srule->expr, struct logformat_node *, list);
|
||||
node = LIST_NEXT(&srule->expr.nodes, struct logformat_node *, list);
|
||||
|
||||
if (!LIST_ISEMPTY(&srule->expr)) {
|
||||
if (node->type != LOG_FMT_TEXT || node->list.n != &srule->expr) {
|
||||
if (!lf_expr_isempty(&srule->expr)) {
|
||||
if (node->type != LOG_FMT_TEXT || node->list.n != &srule->expr.nodes) {
|
||||
srule->dynamic = 1;
|
||||
free(server_name);
|
||||
continue;
|
||||
@ -3225,8 +3224,7 @@ init_proxies_list_stage1:
|
||||
/* Only one element in the list, a simple string: free the expression and
|
||||
* fall back to static rule
|
||||
*/
|
||||
LIST_DELETE(&node->list);
|
||||
free_logformat_node(node);
|
||||
lf_expr_deinit(&srule->expr);
|
||||
}
|
||||
|
||||
srule->dynamic = 0;
|
||||
@ -3774,7 +3772,7 @@ out_uri_auth_compat:
|
||||
|
||||
if (!(curproxy->cap & PR_CAP_INT) && (curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
|
||||
(curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->loggers) &&
|
||||
(!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
|
||||
(!lf_expr_isempty(&curproxy->logformat) || !lf_expr_isempty(&curproxy->logformat_sd))) {
|
||||
ha_warning("log format ignored for %s '%s' since it has no log address.\n",
|
||||
proxy_type_str(curproxy), curproxy->id);
|
||||
err_code |= ERR_WARN;
|
||||
|
@ -3137,7 +3137,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
pendconn_free(s);
|
||||
|
||||
/* let's do a final log if we need it */
|
||||
if (!LIST_ISEMPTY(&fe->logformat) && s->logs.logwait &&
|
||||
if (!lf_expr_isempty(&fe->logformat) && s->logs.logwait &&
|
||||
!(s->flags & SF_MONITOR) &&
|
||||
(!(fe->options & PR_O_NULLNOLOG) || s->req.total)) {
|
||||
s->do_log(s);
|
||||
|
@ -2030,7 +2030,7 @@ static int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct
|
||||
/* Users will always need to provide a value, in case of forwarding, they should use fc_pp_tlv.
|
||||
* for generic types. Otherwise, we will send an empty TLV.
|
||||
*/
|
||||
if (!LIST_ISEMPTY(&srv_tlv->fmt)) {
|
||||
if (!lf_expr_isempty(&srv_tlv->fmt)) {
|
||||
replace = alloc_trash_chunk();
|
||||
if (unlikely(!replace))
|
||||
return 0;
|
||||
|
@ -134,7 +134,7 @@ static void fcgi_release_rule(struct fcgi_rule *rule)
|
||||
if (!rule)
|
||||
return;
|
||||
|
||||
free_logformat_list(&rule->value);
|
||||
lf_expr_deinit(&rule->value);
|
||||
/* ->cond and ->name are not owned by the rule */
|
||||
free(rule);
|
||||
}
|
||||
@ -247,7 +247,7 @@ static int fcgi_flt_check(struct proxy *px, struct flt_conf *fconf)
|
||||
rule->type = crule->type;
|
||||
rule->name = ist(crule->name);
|
||||
rule->cond = crule->cond;
|
||||
LIST_INIT(&rule->value);
|
||||
lf_expr_init(&rule->value);
|
||||
|
||||
if (crule->value) {
|
||||
if (!parse_logformat_string(crule->value, px, &rule->value, LOG_OPT_HTTP,
|
||||
|
@ -55,7 +55,7 @@ int frontend_accept(struct stream *s)
|
||||
|
||||
if ((fe->mode == PR_MODE_TCP || fe->mode == PR_MODE_HTTP)
|
||||
&& (!LIST_ISEMPTY(&fe->loggers))) {
|
||||
if (likely(!LIST_ISEMPTY(&fe->logformat))) {
|
||||
if (likely(!lf_expr_isempty(&fe->logformat))) {
|
||||
/* we have the client ip */
|
||||
if (s->logs.logwait & LW_CLIP)
|
||||
if (!(s->logs.logwait &= ~(LW_CLIP|LW_INIT)))
|
||||
|
@ -49,7 +49,7 @@ static void release_http_action(struct act_rule *rule)
|
||||
istfree(&rule->arg.http.str);
|
||||
if (rule->arg.http.re)
|
||||
regex_free(rule->arg.http.re);
|
||||
free_logformat_list(&rule->arg.http.fmt);
|
||||
lf_expr_deinit(&rule->arg.http.fmt);
|
||||
}
|
||||
|
||||
/* Release memory allocated by HTTP actions relying on an http reply. Concretly,
|
||||
@ -172,7 +172,7 @@ static enum act_parse_ret parse_set_req_line(const char **args, int *orig_arg, s
|
||||
}
|
||||
rule->action_ptr = http_action_set_req_line;
|
||||
rule->release_ptr = release_http_action;
|
||||
LIST_INIT(&rule->arg.http.fmt);
|
||||
lf_expr_init(&rule->arg.http.fmt);
|
||||
|
||||
if (!*args[cur_arg] ||
|
||||
(*args[cur_arg + 1] && strcmp(args[cur_arg + 1], "if") != 0 && strcmp(args[cur_arg + 1], "unless") != 0)) {
|
||||
@ -609,7 +609,7 @@ static enum act_parse_ret parse_replace_uri(const char **args, int *orig_arg, st
|
||||
|
||||
rule->action_ptr = http_action_replace_uri;
|
||||
rule->release_ptr = release_http_action;
|
||||
LIST_INIT(&rule->arg.http.fmt);
|
||||
lf_expr_init(&rule->arg.http.fmt);
|
||||
|
||||
if (!*args[cur_arg] || !*args[cur_arg+1] ||
|
||||
(*args[cur_arg+2] && strcmp(args[cur_arg+2], "if") != 0 && strcmp(args[cur_arg+2], "unless") != 0)) {
|
||||
@ -673,7 +673,7 @@ static enum act_parse_ret parse_http_set_status(const char **args, int *orig_arg
|
||||
rule->action = ACT_CUSTOM;
|
||||
rule->action_ptr = action_http_set_status;
|
||||
rule->release_ptr = release_http_action;
|
||||
LIST_INIT(&rule->arg.http.fmt);
|
||||
lf_expr_init(&rule->arg.http.fmt);
|
||||
|
||||
/* Check if an argument is available */
|
||||
if (!*args[*orig_arg]) {
|
||||
@ -1310,7 +1310,7 @@ static enum act_parse_ret parse_http_auth(const char **args, int *orig_arg, stru
|
||||
rule->flags |= ACT_FLAG_FINAL;
|
||||
rule->action_ptr = http_action_auth;
|
||||
rule->release_ptr = release_http_action;
|
||||
LIST_INIT(&rule->arg.http.fmt);
|
||||
lf_expr_init(&rule->arg.http.fmt);
|
||||
|
||||
cur_arg = *orig_arg;
|
||||
if (strcmp(args[cur_arg], "realm") == 0) {
|
||||
@ -1490,7 +1490,7 @@ static enum act_parse_ret parse_http_set_header(const char **args, int *orig_arg
|
||||
rule->action_ptr = http_action_set_header;
|
||||
}
|
||||
rule->release_ptr = release_http_action;
|
||||
LIST_INIT(&rule->arg.http.fmt);
|
||||
lf_expr_init(&rule->arg.http.fmt);
|
||||
|
||||
cur_arg = *orig_arg;
|
||||
if (!*args[cur_arg] || !*args[cur_arg+1]) {
|
||||
@ -1616,7 +1616,7 @@ static enum act_parse_ret parse_http_replace_header(const char **args, int *orig
|
||||
rule->action = 1; // replace-value
|
||||
rule->action_ptr = http_action_replace_header;
|
||||
rule->release_ptr = release_http_action;
|
||||
LIST_INIT(&rule->arg.http.fmt);
|
||||
lf_expr_init(&rule->arg.http.fmt);
|
||||
|
||||
cur_arg = *orig_arg;
|
||||
if (!*args[cur_arg] || !*args[cur_arg+1] || !*args[cur_arg+2]) {
|
||||
@ -1719,7 +1719,7 @@ static enum act_parse_ret parse_http_del_header(const char **args, int *orig_arg
|
||||
rule->action = PAT_MATCH_STR;
|
||||
rule->action_ptr = http_action_del_header;
|
||||
rule->release_ptr = release_http_action;
|
||||
LIST_INIT(&rule->arg.http.fmt);
|
||||
lf_expr_init(&rule->arg.http.fmt);
|
||||
|
||||
cur_arg = *orig_arg;
|
||||
if (!*args[cur_arg]) {
|
||||
@ -1895,9 +1895,9 @@ static enum act_return http_action_set_map(struct act_rule *rule, struct proxy *
|
||||
static void release_http_map(struct act_rule *rule)
|
||||
{
|
||||
free(rule->arg.map.ref);
|
||||
free_logformat_list(&rule->arg.map.key);
|
||||
lf_expr_deinit(&rule->arg.map.key);
|
||||
if (rule->action == 1)
|
||||
free_logformat_list(&rule->arg.map.value);
|
||||
lf_expr_deinit(&rule->arg.map.value);
|
||||
}
|
||||
|
||||
/* Parse a "add-acl", "del-acl", "set-map" or "del-map" actions. It takes one or
|
||||
@ -1959,7 +1959,7 @@ static enum act_parse_ret parse_http_set_map(const char **args, int *orig_arg, s
|
||||
}
|
||||
|
||||
/* key pattern */
|
||||
LIST_INIT(&rule->arg.map.key);
|
||||
lf_expr_init(&rule->arg.map.key);
|
||||
if (!parse_logformat_string(args[cur_arg], px, &rule->arg.map.key, LOG_OPT_HTTP, cap, err)) {
|
||||
free(rule->arg.map.ref);
|
||||
return ACT_RET_PRS_ERR;
|
||||
@ -1968,7 +1968,7 @@ static enum act_parse_ret parse_http_set_map(const char **args, int *orig_arg, s
|
||||
if (rule->action == 1) {
|
||||
/* value pattern for set-map only */
|
||||
cur_arg++;
|
||||
LIST_INIT(&rule->arg.map.value);
|
||||
lf_expr_init(&rule->arg.map.value);
|
||||
if (!parse_logformat_string(args[cur_arg], px, &rule->arg.map.value, LOG_OPT_HTTP, cap, err)) {
|
||||
free(rule->arg.map.ref);
|
||||
return ACT_RET_PRS_ERR;
|
||||
|
@ -657,7 +657,7 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit)
|
||||
* A unique ID is generated even when it is not sent to ensure that the ID can make use of
|
||||
* fetches only available in the HTTP request processing stage.
|
||||
*/
|
||||
if (!LIST_ISEMPTY(&sess->fe->format_unique_id)) {
|
||||
if (!lf_expr_isempty(&sess->fe->format_unique_id)) {
|
||||
struct ist unique_id = stream_generate_unique_id(s, &sess->fe->format_unique_id);
|
||||
|
||||
if (!isttest(unique_id)) {
|
||||
@ -1900,7 +1900,7 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s
|
||||
* bytes from the server, then this is the right moment. We have
|
||||
* to temporarily assign bytes_out to log what we currently have.
|
||||
*/
|
||||
if (!LIST_ISEMPTY(&sess->fe->logformat) && !(s->logs.logwait & LW_BYTES)) {
|
||||
if (!lf_expr_isempty(&sess->fe->logformat) && !(s->logs.logwait & LW_BYTES)) {
|
||||
s->logs.t_close = s->logs.t_data; /* to get a valid end date */
|
||||
s->logs.bytes_out = htx->data;
|
||||
s->do_log(s);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <haproxy/sample.h>
|
||||
#include <haproxy/sc_strm.h>
|
||||
#include <haproxy/stream.h>
|
||||
#include <haproxy/log.h>
|
||||
#include <haproxy/tools.h>
|
||||
#include <haproxy/version.h>
|
||||
|
||||
@ -477,7 +478,7 @@ static int smp_fetch_uniqueid(const struct arg *args, struct sample *smp, const
|
||||
{
|
||||
struct ist unique_id;
|
||||
|
||||
if (LIST_ISEMPTY(&smp->sess->fe->format_unique_id))
|
||||
if (lf_expr_isempty(&smp->sess->fe->format_unique_id))
|
||||
return 0;
|
||||
|
||||
if (!smp->strm)
|
||||
|
@ -1125,7 +1125,7 @@ void release_http_reply(struct http_reply *http_reply)
|
||||
ha_free(&http_reply->ctype);
|
||||
list_for_each_entry_safe(hdr, hdrb, &http_reply->hdrs, list) {
|
||||
LIST_DELETE(&hdr->list);
|
||||
free_logformat_list(&hdr->value);
|
||||
lf_expr_deinit(&hdr->value);
|
||||
istfree(&hdr->name);
|
||||
free(hdr);
|
||||
}
|
||||
@ -1136,7 +1136,7 @@ void release_http_reply(struct http_reply *http_reply)
|
||||
else if (http_reply->type == HTTP_REPLY_RAW)
|
||||
chunk_destroy(&http_reply->body.obj);
|
||||
else if (http_reply->type == HTTP_REPLY_LOGFMT)
|
||||
free_logformat_list(&http_reply->body.fmt);
|
||||
lf_expr_deinit(&http_reply->body.fmt);
|
||||
free(http_reply);
|
||||
}
|
||||
|
||||
@ -1669,7 +1669,7 @@ struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struc
|
||||
fd = -1;
|
||||
obj[objlen] = '\0';
|
||||
reply->type = HTTP_REPLY_LOGFMT;
|
||||
LIST_INIT(&reply->body.fmt);
|
||||
lf_expr_init(&reply->body.fmt);
|
||||
cur_arg++;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "lf-string") == 0) {
|
||||
@ -1686,7 +1686,7 @@ struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struc
|
||||
obj = strdup(args[cur_arg]);
|
||||
objlen = strlen(args[cur_arg]);
|
||||
reply->type = HTTP_REPLY_LOGFMT;
|
||||
LIST_INIT(&reply->body.fmt);
|
||||
lf_expr_init(&reply->body.fmt);
|
||||
cur_arg++;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "hdr") == 0) {
|
||||
@ -1709,7 +1709,7 @@ struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struc
|
||||
goto error;
|
||||
}
|
||||
LIST_APPEND(&reply->hdrs, &hdr->list);
|
||||
LIST_INIT(&hdr->value);
|
||||
lf_expr_init(&hdr->value);
|
||||
hdr->name = ist(strdup(args[cur_arg]));
|
||||
if (!isttest(hdr->name)) {
|
||||
memprintf(errmsg, "out of memory");
|
||||
@ -1765,7 +1765,7 @@ struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struc
|
||||
px->conf.args.file, px->conf.args.line);
|
||||
list_for_each_entry_safe(hdr, hdrb, &reply->hdrs, list) {
|
||||
LIST_DELETE(&hdr->list);
|
||||
free_logformat_list(&hdr->value);
|
||||
lf_expr_deinit(&hdr->value);
|
||||
istfree(&hdr->name);
|
||||
free(hdr);
|
||||
}
|
||||
@ -1793,7 +1793,7 @@ struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struc
|
||||
}
|
||||
}
|
||||
else if (reply->type == HTTP_REPLY_LOGFMT) { /* log-format payload using 'lf-file' of 'lf-string' parameter */
|
||||
LIST_INIT(&reply->body.fmt);
|
||||
lf_expr_init(&reply->body.fmt);
|
||||
if ((reply->status == 204 || reply->status == 304)) {
|
||||
memprintf(errmsg, "No body expected for %d responses", reply->status);
|
||||
goto error;
|
||||
|
@ -323,7 +323,7 @@ void http_free_redirect_rule(struct redirect_rule *rdr)
|
||||
free_acl_cond(rdr->cond);
|
||||
free(rdr->rdr_str);
|
||||
free(rdr->cookie_str);
|
||||
free_logformat_list(&rdr->rdr_fmt);
|
||||
lf_expr_deinit(&rdr->rdr_fmt);
|
||||
free(rdr);
|
||||
}
|
||||
|
||||
@ -440,7 +440,7 @@ struct redirect_rule *http_parse_redirect_rule(const char *file, int linenum, st
|
||||
if (!rule)
|
||||
goto out_of_memory;
|
||||
rule->cond = cond;
|
||||
LIST_INIT(&rule->rdr_fmt);
|
||||
lf_expr_init(&rule->rdr_fmt);
|
||||
|
||||
if (!use_fmt) {
|
||||
/* old-style static redirect rule */
|
||||
|
75
src/log.c
75
src/log.c
@ -370,9 +370,10 @@ int parse_logformat_tag_args(char *args, struct logformat_node *node, char **err
|
||||
* ignored when arg_len is 0. Neither <tag> nor <tag_len> may be null.
|
||||
* Returns false in error case and err is filled, otherwise returns true.
|
||||
*/
|
||||
int parse_logformat_tag(char *arg, int arg_len, char *name, int name_len, int typecast, char *tag, int tag_len, struct proxy *curproxy, struct list *list_format, int *defoptions, char **err)
|
||||
int parse_logformat_tag(char *arg, int arg_len, char *name, int name_len, int typecast, char *tag, int tag_len, struct proxy *curproxy, struct lf_expr *lf_expr, int *defoptions, char **err)
|
||||
{
|
||||
int j;
|
||||
struct list *list_format= &lf_expr->nodes;
|
||||
struct logformat_node *node = NULL;
|
||||
|
||||
for (j = 0; logformat_tags[j].name; j++) { // search a log type
|
||||
@ -431,13 +432,14 @@ int parse_logformat_tag(char *arg, int arg_len, char *name, int name_len, int ty
|
||||
* start: start pointer
|
||||
* end: end text pointer
|
||||
* type: string type
|
||||
* list_format: destination list
|
||||
* lf_expr: destination logformat expr (list of fmt nodes)
|
||||
*
|
||||
* LOG_TEXT: copy chars from start to end excluding end.
|
||||
*
|
||||
*/
|
||||
int add_to_logformat_list(char *start, char *end, int type, struct list *list_format, char **err)
|
||||
int add_to_logformat_list(char *start, char *end, int type, struct lf_expr *lf_expr, char **err)
|
||||
{
|
||||
struct list *list_format = &lf_expr->nodes;
|
||||
char *str;
|
||||
|
||||
if (type == LF_TEXT) { /* type text */
|
||||
@ -465,16 +467,17 @@ int add_to_logformat_list(char *start, char *end, int type, struct list *list_fo
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the sample fetch expression <text> and add a node to <list_format> upon
|
||||
* Parse the sample fetch expression <text> and add a node to <lf_expr> upon
|
||||
* success. The curpx->conf.args.ctx must be set by the caller. If an end pointer
|
||||
* is passed in <endptr>, it will be updated with the pointer to the first character
|
||||
* not part of the sample expression.
|
||||
*
|
||||
* In error case, the function returns 0, otherwise it returns 1.
|
||||
*/
|
||||
int add_sample_to_logformat_list(char *text, char *name, int name_len, int typecast, char *arg, int arg_len, struct proxy *curpx, struct list *list_format, int options, int cap, char **err, char **endptr)
|
||||
int add_sample_to_logformat_list(char *text, char *name, int name_len, int typecast, char *arg, int arg_len, struct proxy *curpx, struct lf_expr *lf_expr, int options, int cap, char **err, char **endptr)
|
||||
{
|
||||
char *cmd[2];
|
||||
struct list *list_format = &lf_expr->nodes;
|
||||
struct sample_expr *expr = NULL;
|
||||
struct logformat_node *node = NULL;
|
||||
int cmd_arg;
|
||||
@ -551,13 +554,13 @@ int add_sample_to_logformat_list(char *text, char *name, int name_len, int typec
|
||||
*
|
||||
* fmt: the string to parse
|
||||
* curproxy: the proxy affected
|
||||
* list_format: the destination list
|
||||
* lf_expr: the destination logformat expression (logformat_node list)
|
||||
* options: LOG_OPT_* to force on every node
|
||||
* cap: all SMP_VAL_* flags supported by the consumer
|
||||
*
|
||||
* The function returns 1 in success case, otherwise, it returns 0 and err is filled.
|
||||
*/
|
||||
int parse_logformat_string(const char *fmt, struct proxy *curproxy, struct list *list_format, int options, int cap, char **err)
|
||||
int parse_logformat_string(const char *fmt, struct proxy *curproxy, struct lf_expr *lf_expr, int options, int cap, char **err)
|
||||
{
|
||||
char *sp, *str, *backfmt; /* start pointer for text parts */
|
||||
char *arg = NULL; /* start pointer for args */
|
||||
@ -578,8 +581,8 @@ int parse_logformat_string(const char *fmt, struct proxy *curproxy, struct list
|
||||
}
|
||||
curproxy->to_log |= LW_INIT;
|
||||
|
||||
/* flush the list first. */
|
||||
free_logformat_list(list_format);
|
||||
/* reset the old expr first (if previously defined) */
|
||||
lf_expr_deinit(lf_expr);
|
||||
|
||||
for (cformat = LF_INIT; cformat != LF_END; str++) {
|
||||
pformat = cformat;
|
||||
@ -694,7 +697,7 @@ int parse_logformat_string(const char *fmt, struct proxy *curproxy, struct list
|
||||
* part of the expression, which MUST be the trailing
|
||||
* angle bracket.
|
||||
*/
|
||||
if (!add_sample_to_logformat_list(tag, name, name_len, typecast, arg, arg_len, curproxy, list_format, options, cap, err, &str))
|
||||
if (!add_sample_to_logformat_list(tag, name, name_len, typecast, arg, arg_len, curproxy, lf_expr, options, cap, err, &str))
|
||||
goto fail;
|
||||
|
||||
if (*str == ']') {
|
||||
@ -740,12 +743,12 @@ int parse_logformat_string(const char *fmt, struct proxy *curproxy, struct list
|
||||
if (cformat != pformat || pformat == LF_SEPARATOR) {
|
||||
switch (pformat) {
|
||||
case LF_TAG:
|
||||
if (!parse_logformat_tag(arg, arg_len, name, name_len, typecast, tag, tag_len, curproxy, list_format, &options, err))
|
||||
if (!parse_logformat_tag(arg, arg_len, name, name_len, typecast, tag, tag_len, curproxy, lf_expr, &options, err))
|
||||
goto fail;
|
||||
break;
|
||||
case LF_TEXT:
|
||||
case LF_SEPARATOR:
|
||||
if (!add_to_logformat_list(sp, str, pformat, list_format, err))
|
||||
if (!add_to_logformat_list(sp, str, pformat, lf_expr, err))
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
@ -2592,19 +2595,53 @@ void free_logformat_list(struct list *fmt)
|
||||
}
|
||||
}
|
||||
|
||||
/* Builds a log line in <dst> based on <list_format>, and stops before reaching
|
||||
/* Prepares log-format expression struct */
|
||||
void lf_expr_init(struct lf_expr *expr)
|
||||
{
|
||||
LIST_INIT(&expr->nodes);
|
||||
}
|
||||
|
||||
/* Releases and resets a log-format expression */
|
||||
void lf_expr_deinit(struct lf_expr *expr)
|
||||
{
|
||||
free_logformat_list(&expr->nodes);
|
||||
lf_expr_init(expr);
|
||||
}
|
||||
|
||||
/* Transfer log-format expression from <src> to <dst>
|
||||
* at the end of the operation, <src> is reset
|
||||
*/
|
||||
void lf_expr_xfer(struct lf_expr *src, struct lf_expr *dst)
|
||||
{
|
||||
struct logformat_node *lf, *lfb;
|
||||
|
||||
/* first, reset any existing expr */
|
||||
lf_expr_deinit(dst);
|
||||
|
||||
/* then proceed with transfer between <src> and <dst> */
|
||||
list_for_each_entry_safe(lf, lfb, &src->nodes, list) {
|
||||
LIST_DELETE(&lf->list);
|
||||
LIST_APPEND(&dst->nodes, &lf->list);
|
||||
}
|
||||
|
||||
/* src is now empty, perform an explicit reset */
|
||||
lf_expr_init(src);
|
||||
}
|
||||
|
||||
/* Builds a log line in <dst> based on <lf_expr>, and stops before reaching
|
||||
* <maxsize> characters. Returns the size of the output string in characters,
|
||||
* not counting the trailing zero which is always added if the resulting size
|
||||
* is not zero. It requires a valid session and optionally a stream. If the
|
||||
* stream is NULL, default values will be assumed for the stream part.
|
||||
*/
|
||||
int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize, struct list *list_format)
|
||||
int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize, struct lf_expr *lf_expr)
|
||||
{
|
||||
struct proxy *fe = sess->fe;
|
||||
struct proxy *be;
|
||||
struct http_txn *txn;
|
||||
const struct strm_logs *logs;
|
||||
struct connection *fe_conn, *be_conn;
|
||||
struct list *list_format = &lf_expr->nodes;
|
||||
unsigned int s_flags;
|
||||
unsigned int uniq_id;
|
||||
struct buffer chunk;
|
||||
@ -2708,7 +2745,7 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
|
||||
tmplog = dst;
|
||||
|
||||
/* fill logbuffer */
|
||||
if (LIST_ISEMPTY(list_format))
|
||||
if (lf_expr_isempty(lf_expr))
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(tmp, list_format, list) {
|
||||
@ -3668,11 +3705,11 @@ void strm_log(struct stream *s)
|
||||
}
|
||||
|
||||
/* if unique-id was not generated */
|
||||
if (!isttest(s->unique_id) && !LIST_ISEMPTY(&sess->fe->format_unique_id)) {
|
||||
if (!isttest(s->unique_id) && !lf_expr_isempty(&sess->fe->format_unique_id)) {
|
||||
stream_generate_unique_id(s, &sess->fe->format_unique_id);
|
||||
}
|
||||
|
||||
if (!LIST_ISEMPTY(&sess->fe->logformat_sd)) {
|
||||
if (!lf_expr_isempty(&sess->fe->logformat_sd)) {
|
||||
sd_size = build_logline(s, logline_rfc5424, global.max_syslog_len,
|
||||
&sess->fe->logformat_sd);
|
||||
}
|
||||
@ -3710,13 +3747,13 @@ void sess_log(struct session *sess)
|
||||
if (sess->fe->options2 & PR_O2_LOGERRORS)
|
||||
level = LOG_ERR;
|
||||
|
||||
if (!LIST_ISEMPTY(&sess->fe->logformat_sd)) {
|
||||
if (!lf_expr_isempty(&sess->fe->logformat_sd)) {
|
||||
sd_size = sess_build_logline(sess, NULL,
|
||||
logline_rfc5424, global.max_syslog_len,
|
||||
&sess->fe->logformat_sd);
|
||||
}
|
||||
|
||||
if (!LIST_ISEMPTY(&sess->fe->logformat_error))
|
||||
if (!lf_expr_isempty(&sess->fe->logformat_error))
|
||||
size = sess_build_logline(sess, NULL, logline, global.max_syslog_len, &sess->fe->logformat_error);
|
||||
else
|
||||
size = sess_build_logline(sess, NULL, logline, global.max_syslog_len, &sess->fe->logformat);
|
||||
|
20
src/proxy.c
20
src/proxy.c
@ -184,7 +184,7 @@ void free_server_rules(struct list *srules)
|
||||
list_for_each_entry_safe(srule, sruleb, srules, list) {
|
||||
LIST_DELETE(&srule->list);
|
||||
free_acl_cond(srule->cond);
|
||||
free_logformat_list(&srule->expr);
|
||||
lf_expr_deinit(&srule->expr);
|
||||
free(srule->file);
|
||||
free(srule);
|
||||
}
|
||||
@ -264,7 +264,7 @@ void free_proxy(struct proxy *p)
|
||||
LIST_DELETE(&rule->list);
|
||||
free_acl_cond(rule->cond);
|
||||
if (rule->dynamic)
|
||||
free_logformat_list(&rule->be.expr);
|
||||
lf_expr_deinit(&rule->be.expr);
|
||||
free(rule->file);
|
||||
free(rule);
|
||||
}
|
||||
@ -279,10 +279,10 @@ void free_proxy(struct proxy *p)
|
||||
free_logger(log);
|
||||
}
|
||||
|
||||
free_logformat_list(&p->logformat);
|
||||
free_logformat_list(&p->logformat_sd);
|
||||
free_logformat_list(&p->format_unique_id);
|
||||
free_logformat_list(&p->logformat_error);
|
||||
lf_expr_deinit(&p->logformat);
|
||||
lf_expr_deinit(&p->logformat_sd);
|
||||
lf_expr_deinit(&p->format_unique_id);
|
||||
lf_expr_deinit(&p->logformat_error);
|
||||
|
||||
free_act_rules(&p->tcp_req.inspect_rules);
|
||||
free_act_rules(&p->tcp_rep.inspect_rules);
|
||||
@ -1348,10 +1348,10 @@ void init_new_proxy(struct proxy *p)
|
||||
LIST_INIT(&p->tcp_req.l5_rules);
|
||||
MT_LIST_INIT(&p->listener_queue);
|
||||
LIST_INIT(&p->loggers);
|
||||
LIST_INIT(&p->logformat);
|
||||
LIST_INIT(&p->logformat_sd);
|
||||
LIST_INIT(&p->format_unique_id);
|
||||
LIST_INIT(&p->logformat_error);
|
||||
lf_expr_init(&p->logformat);
|
||||
lf_expr_init(&p->logformat_sd);
|
||||
lf_expr_init(&p->format_unique_id);
|
||||
lf_expr_init(&p->logformat_error);
|
||||
LIST_INIT(&p->conf.bind);
|
||||
LIST_INIT(&p->conf.listeners);
|
||||
LIST_INIT(&p->conf.errors);
|
||||
|
@ -3525,7 +3525,7 @@ static int _srv_parse_finalize(char **args, int cur_arg,
|
||||
}
|
||||
|
||||
list_for_each_entry(srv_tlv, &srv->pp_tlvs, list) {
|
||||
LIST_INIT(&srv_tlv->fmt);
|
||||
lf_expr_init(&srv_tlv->fmt);
|
||||
if (srv_tlv->fmt_string && unlikely(!parse_logformat_string(srv_tlv->fmt_string,
|
||||
srv->proxy, &srv_tlv->fmt, 0, SMP_VAL_BE_SRV_CON, &errmsg))) {
|
||||
if (errmsg) {
|
||||
|
@ -428,7 +428,7 @@ static void session_kill_embryonic(struct session *sess, unsigned int state)
|
||||
conn->err_code = CO_ER_SSL_TIMEOUT;
|
||||
}
|
||||
|
||||
if(!LIST_ISEMPTY(&sess->fe->logformat_error)) {
|
||||
if(!lf_expr_isempty(&sess->fe->logformat_error)) {
|
||||
/* Display a log line following the configured error-log-format. */
|
||||
sess_log(sess);
|
||||
}
|
||||
|
@ -920,7 +920,7 @@ void back_establish(struct stream *s)
|
||||
if (!IS_HTX_STRM(s)) { /* let's allow immediate data connection in this case */
|
||||
/* if the user wants to log as soon as possible, without counting
|
||||
* bytes from the server, then this is the right moment. */
|
||||
if (!LIST_ISEMPTY(&strm_fe(s)->logformat) && !(s->logs.logwait & LW_BYTES)) {
|
||||
if (!lf_expr_isempty(&strm_fe(s)->logformat) && !(s->logs.logwait & LW_BYTES)) {
|
||||
/* note: no pend_pos here, session is established */
|
||||
s->logs.t_close = s->logs.t_connect; /* to get a valid end date */
|
||||
s->do_log(s);
|
||||
@ -2597,7 +2597,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
}
|
||||
|
||||
/* let's do a final log if we need it */
|
||||
if (!LIST_ISEMPTY(&sess->fe->logformat) && s->logs.logwait &&
|
||||
if (!lf_expr_isempty(&sess->fe->logformat) && s->logs.logwait &&
|
||||
!(s->flags & SF_MONITOR) &&
|
||||
(!(sess->fe->options & PR_O_NULLNOLOG) || req->total)) {
|
||||
/* we may need to know the position in the queue */
|
||||
@ -2847,7 +2847,7 @@ INITCALL0(STG_INIT, init_stream);
|
||||
* If an ID is already stored within the stream nothing happens existing unique ID is
|
||||
* returned.
|
||||
*/
|
||||
struct ist stream_generate_unique_id(struct stream *strm, struct list *format)
|
||||
struct ist stream_generate_unique_id(struct stream *strm, struct lf_expr *format)
|
||||
{
|
||||
if (isttest(strm->unique_id)) {
|
||||
return strm->unique_id;
|
||||
|
@ -81,7 +81,7 @@ void free_tcpcheck_http_hdr(struct tcpcheck_http_hdr *hdr)
|
||||
if (!hdr)
|
||||
return;
|
||||
|
||||
free_logformat_list(&hdr->value);
|
||||
lf_expr_deinit(&hdr->value);
|
||||
istfree(&hdr->name);
|
||||
free(hdr);
|
||||
}
|
||||
@ -118,28 +118,28 @@ void free_tcpcheck(struct tcpcheck_rule *rule, int in_pool)
|
||||
break;
|
||||
case TCPCHK_SEND_STRING_LF:
|
||||
case TCPCHK_SEND_BINARY_LF:
|
||||
free_logformat_list(&rule->send.fmt);
|
||||
lf_expr_deinit(&rule->send.fmt);
|
||||
break;
|
||||
case TCPCHK_SEND_HTTP:
|
||||
free(rule->send.http.meth.str.area);
|
||||
if (!(rule->send.http.flags & TCPCHK_SND_HTTP_FL_URI_FMT))
|
||||
istfree(&rule->send.http.uri);
|
||||
else
|
||||
free_logformat_list(&rule->send.http.uri_fmt);
|
||||
lf_expr_deinit(&rule->send.http.uri_fmt);
|
||||
istfree(&rule->send.http.vsn);
|
||||
free_tcpcheck_http_hdrs(&rule->send.http.hdrs);
|
||||
if (!(rule->send.http.flags & TCPCHK_SND_HTTP_FL_BODY_FMT))
|
||||
istfree(&rule->send.http.body);
|
||||
else
|
||||
free_logformat_list(&rule->send.http.body_fmt);
|
||||
lf_expr_deinit(&rule->send.http.body_fmt);
|
||||
break;
|
||||
case TCPCHK_SEND_UNDEF:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TCPCHK_ACT_EXPECT:
|
||||
free_logformat_list(&rule->expect.onerror_fmt);
|
||||
free_logformat_list(&rule->expect.onsuccess_fmt);
|
||||
lf_expr_deinit(&rule->expect.onerror_fmt);
|
||||
lf_expr_deinit(&rule->expect.onsuccess_fmt);
|
||||
release_sample_expr(rule->expect.status_expr);
|
||||
switch (rule->expect.type) {
|
||||
case TCPCHK_EXPECT_HTTP_STATUS:
|
||||
@ -159,20 +159,20 @@ void free_tcpcheck(struct tcpcheck_rule *rule, int in_pool)
|
||||
case TCPCHK_EXPECT_STRING_LF:
|
||||
case TCPCHK_EXPECT_BINARY_LF:
|
||||
case TCPCHK_EXPECT_HTTP_BODY_LF:
|
||||
free_logformat_list(&rule->expect.fmt);
|
||||
lf_expr_deinit(&rule->expect.fmt);
|
||||
break;
|
||||
case TCPCHK_EXPECT_HTTP_HEADER:
|
||||
if (rule->expect.flags & TCPCHK_EXPT_FL_HTTP_HNAME_REG)
|
||||
regex_free(rule->expect.hdr.name_re);
|
||||
else if (rule->expect.flags & TCPCHK_EXPT_FL_HTTP_HNAME_FMT)
|
||||
free_logformat_list(&rule->expect.hdr.name_fmt);
|
||||
lf_expr_deinit(&rule->expect.hdr.name_fmt);
|
||||
else
|
||||
istfree(&rule->expect.hdr.name);
|
||||
|
||||
if (rule->expect.flags & TCPCHK_EXPT_FL_HTTP_HVAL_REG)
|
||||
regex_free(rule->expect.hdr.value_re);
|
||||
else if (rule->expect.flags & TCPCHK_EXPT_FL_HTTP_HVAL_FMT)
|
||||
free_logformat_list(&rule->expect.hdr.value_fmt);
|
||||
lf_expr_deinit(&rule->expect.hdr.value_fmt);
|
||||
else if (!(rule->expect.flags & TCPCHK_EXPT_FL_HTTP_HVAL_NONE))
|
||||
istfree(&rule->expect.hdr.value);
|
||||
break;
|
||||
@ -421,7 +421,7 @@ static void tcpcheck_expect_onerror_message(struct buffer *msg, struct check *ch
|
||||
chunk_istcat(msg, info);
|
||||
goto comment;
|
||||
}
|
||||
else if (!LIST_ISEMPTY(&rule->expect.onerror_fmt)) {
|
||||
else if (!lf_expr_isempty(&rule->expect.onerror_fmt)) {
|
||||
msg->data += sess_build_logline(check->sess, NULL, b_tail(msg), b_room(msg), &rule->expect.onerror_fmt);
|
||||
goto comment;
|
||||
}
|
||||
@ -516,7 +516,7 @@ static void tcpcheck_expect_onsuccess_message(struct buffer *msg, struct check *
|
||||
*/
|
||||
if (istlen(info))
|
||||
chunk_istcat(msg, info);
|
||||
if (!LIST_ISEMPTY(&rule->expect.onsuccess_fmt))
|
||||
if (!lf_expr_isempty(&rule->expect.onsuccess_fmt))
|
||||
msg->data += sess_build_logline(check->sess, NULL, b_tail(msg), b_room(msg),
|
||||
&rule->expect.onsuccess_fmt);
|
||||
else if (check->type == PR_O2_TCPCHK_CHK &&
|
||||
@ -1684,7 +1684,7 @@ enum tcpcheck_eval_ret tcpcheck_eval_expect_http(struct check *check, struct tcp
|
||||
|
||||
/* Set status and description in case of error */
|
||||
status = ((status != HCHK_STATUS_UNKNOWN) ? status : HCHK_STATUS_L7STS);
|
||||
if (LIST_ISEMPTY(&expect->onerror_fmt))
|
||||
if (lf_expr_isempty(&expect->onerror_fmt))
|
||||
desc = htx_sl_res_reason(sl);
|
||||
break;
|
||||
case TCPCHK_EXPECT_HTTP_STATUS_REGEX:
|
||||
@ -1692,7 +1692,7 @@ enum tcpcheck_eval_ret tcpcheck_eval_expect_http(struct check *check, struct tcp
|
||||
|
||||
/* Set status and description in case of error */
|
||||
status = ((status != HCHK_STATUS_UNKNOWN) ? status : HCHK_STATUS_L7STS);
|
||||
if (LIST_ISEMPTY(&expect->onerror_fmt))
|
||||
if (lf_expr_isempty(&expect->onerror_fmt))
|
||||
desc = htx_sl_res_reason(sl);
|
||||
break;
|
||||
|
||||
@ -1823,7 +1823,7 @@ enum tcpcheck_eval_ret tcpcheck_eval_expect_http(struct check *check, struct tcp
|
||||
|
||||
end_of_match:
|
||||
status = ((status != HCHK_STATUS_UNKNOWN) ? status : HCHK_STATUS_L7STS);
|
||||
if (LIST_ISEMPTY(&expect->onerror_fmt))
|
||||
if (lf_expr_isempty(&expect->onerror_fmt))
|
||||
desc = htx_sl_res_reason(sl);
|
||||
break;
|
||||
}
|
||||
@ -1850,7 +1850,7 @@ enum tcpcheck_eval_ret tcpcheck_eval_expect_http(struct check *check, struct tcp
|
||||
goto wait_more_data;
|
||||
}
|
||||
status = ((status != HCHK_STATUS_UNKNOWN) ? status : HCHK_STATUS_L7RSP);
|
||||
if (LIST_ISEMPTY(&expect->onerror_fmt))
|
||||
if (lf_expr_isempty(&expect->onerror_fmt))
|
||||
desc = ist("HTTP content check could not find a response body");
|
||||
TRACE_ERROR("no response boduy found while expected", CHK_EV_TCPCHK_EXP|CHK_EV_TCPCHK_ERR, check);
|
||||
goto error;
|
||||
@ -1899,7 +1899,7 @@ enum tcpcheck_eval_ret tcpcheck_eval_expect_http(struct check *check, struct tcp
|
||||
|
||||
/* Set status and description in case of error */
|
||||
status = ((status != HCHK_STATUS_UNKNOWN) ? status : HCHK_STATUS_L7RSP);
|
||||
if (LIST_ISEMPTY(&expect->onerror_fmt))
|
||||
if (lf_expr_isempty(&expect->onerror_fmt))
|
||||
desc = (inverse
|
||||
? ist("HTTP check matched unwanted content")
|
||||
: ist("HTTP content check did not match"));
|
||||
@ -2636,7 +2636,7 @@ struct tcpcheck_rule *parse_tcpcheck_send(char **args, int cur_arg, struct proxy
|
||||
}
|
||||
case TCPCHK_SEND_STRING_LF:
|
||||
case TCPCHK_SEND_BINARY_LF:
|
||||
LIST_INIT(&chk->send.fmt);
|
||||
lf_expr_init(&chk->send.fmt);
|
||||
px->conf.args.ctx = ARGC_SRV;
|
||||
if (!parse_logformat_string(data, px, &chk->send.fmt, 0, SMP_VAL_BE_CHK_RUL, errmsg)) {
|
||||
memprintf(errmsg, "'%s' invalid log-format string (%s).\n", data, *errmsg);
|
||||
@ -2777,7 +2777,7 @@ struct tcpcheck_rule *parse_tcpcheck_send_http(char **args, int cur_arg, struct
|
||||
}
|
||||
if (uri) {
|
||||
if (chk->send.http.flags & TCPCHK_SND_HTTP_FL_URI_FMT) {
|
||||
LIST_INIT(&chk->send.http.uri_fmt);
|
||||
lf_expr_init(&chk->send.http.uri_fmt);
|
||||
px->conf.args.ctx = ARGC_SRV;
|
||||
if (!parse_logformat_string(uri, px, &chk->send.http.uri_fmt, 0, SMP_VAL_BE_CHK_RUL, errmsg)) {
|
||||
memprintf(errmsg, "'%s' invalid log-format string (%s).\n", uri, *errmsg);
|
||||
@ -2805,7 +2805,7 @@ struct tcpcheck_rule *parse_tcpcheck_send_http(char **args, int cur_arg, struct
|
||||
memprintf(errmsg, "out of memory");
|
||||
goto error;
|
||||
}
|
||||
LIST_INIT(&hdr->value);
|
||||
lf_expr_init(&hdr->value);
|
||||
hdr->name = istdup(hdrs[i].n);
|
||||
if (!isttest(hdr->name)) {
|
||||
memprintf(errmsg, "out of memory");
|
||||
@ -2821,7 +2821,7 @@ struct tcpcheck_rule *parse_tcpcheck_send_http(char **args, int cur_arg, struct
|
||||
|
||||
if (body) {
|
||||
if (chk->send.http.flags & TCPCHK_SND_HTTP_FL_BODY_FMT) {
|
||||
LIST_INIT(&chk->send.http.body_fmt);
|
||||
lf_expr_init(&chk->send.http.body_fmt);
|
||||
px->conf.args.ctx = ARGC_SRV;
|
||||
if (!parse_logformat_string(body, px, &chk->send.http.body_fmt, 0, SMP_VAL_BE_CHK_RUL, errmsg)) {
|
||||
memprintf(errmsg, "'%s' invalid log-format string (%s).\n", body, *errmsg);
|
||||
@ -3288,8 +3288,8 @@ struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, struct pro
|
||||
goto error;
|
||||
}
|
||||
chk->action = TCPCHK_ACT_EXPECT;
|
||||
LIST_INIT(&chk->expect.onerror_fmt);
|
||||
LIST_INIT(&chk->expect.onsuccess_fmt);
|
||||
lf_expr_init(&chk->expect.onerror_fmt);
|
||||
lf_expr_init(&chk->expect.onsuccess_fmt);
|
||||
chk->comment = comment; comment = NULL;
|
||||
chk->expect.type = type;
|
||||
chk->expect.min_recv = min_recv;
|
||||
@ -3382,7 +3382,7 @@ struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, struct pro
|
||||
case TCPCHK_EXPECT_STRING_LF:
|
||||
case TCPCHK_EXPECT_BINARY_LF:
|
||||
case TCPCHK_EXPECT_HTTP_BODY_LF:
|
||||
LIST_INIT(&chk->expect.fmt);
|
||||
lf_expr_init(&chk->expect.fmt);
|
||||
px->conf.args.ctx = ARGC_SRV;
|
||||
if (!parse_logformat_string(pattern, px, &chk->expect.fmt, 0, SMP_VAL_BE_CHK_RUL, errmsg)) {
|
||||
memprintf(errmsg, "'%s' invalid log-format string (%s).\n", pattern, *errmsg);
|
||||
@ -3402,7 +3402,7 @@ struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, struct pro
|
||||
}
|
||||
else if (chk->expect.flags & TCPCHK_EXPT_FL_HTTP_HNAME_FMT) {
|
||||
px->conf.args.ctx = ARGC_SRV;
|
||||
LIST_INIT(&chk->expect.hdr.name_fmt);
|
||||
lf_expr_init(&chk->expect.hdr.name_fmt);
|
||||
if (!parse_logformat_string(npat, px, &chk->expect.hdr.name_fmt, 0, SMP_VAL_BE_CHK_RUL, errmsg)) {
|
||||
memprintf(errmsg, "'%s' invalid log-format string (%s).\n", npat, *errmsg);
|
||||
goto error;
|
||||
@ -3432,7 +3432,7 @@ struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, struct pro
|
||||
}
|
||||
else if (chk->expect.flags & TCPCHK_EXPT_FL_HTTP_HVAL_FMT) {
|
||||
px->conf.args.ctx = ARGC_SRV;
|
||||
LIST_INIT(&chk->expect.hdr.value_fmt);
|
||||
lf_expr_init(&chk->expect.hdr.value_fmt);
|
||||
if (!parse_logformat_string(vpat, px, &chk->expect.hdr.value_fmt, 0, SMP_VAL_BE_CHK_RUL, errmsg)) {
|
||||
memprintf(errmsg, "'%s' invalid log-format string (%s).\n", npat, *errmsg);
|
||||
goto error;
|
||||
@ -3484,7 +3484,6 @@ struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, struct pro
|
||||
*/
|
||||
void tcpcheck_overwrite_send_http_rule(struct tcpcheck_rule *old, struct tcpcheck_rule *new)
|
||||
{
|
||||
struct logformat_node *lf, *lfb;
|
||||
struct tcpcheck_http_hdr *hdr, *bhdr;
|
||||
|
||||
|
||||
@ -3500,22 +3499,19 @@ void tcpcheck_overwrite_send_http_rule(struct tcpcheck_rule *old, struct tcpchec
|
||||
if (!(old->send.http.flags & TCPCHK_SND_HTTP_FL_URI_FMT))
|
||||
istfree(&old->send.http.uri);
|
||||
else
|
||||
free_logformat_list(&old->send.http.uri_fmt);
|
||||
lf_expr_deinit(&old->send.http.uri_fmt);
|
||||
old->send.http.flags &= ~TCPCHK_SND_HTTP_FL_URI_FMT;
|
||||
old->send.http.uri = new->send.http.uri;
|
||||
new->send.http.uri = IST_NULL;
|
||||
}
|
||||
else if ((new->send.http.flags & TCPCHK_SND_HTTP_FL_URI_FMT) && !LIST_ISEMPTY(&new->send.http.uri_fmt)) {
|
||||
else if ((new->send.http.flags & TCPCHK_SND_HTTP_FL_URI_FMT) && !lf_expr_isempty(&new->send.http.uri_fmt)) {
|
||||
if (!(old->send.http.flags & TCPCHK_SND_HTTP_FL_URI_FMT))
|
||||
istfree(&old->send.http.uri);
|
||||
else
|
||||
free_logformat_list(&old->send.http.uri_fmt);
|
||||
lf_expr_deinit(&old->send.http.uri_fmt);
|
||||
old->send.http.flags |= TCPCHK_SND_HTTP_FL_URI_FMT;
|
||||
LIST_INIT(&old->send.http.uri_fmt);
|
||||
list_for_each_entry_safe(lf, lfb, &new->send.http.uri_fmt, list) {
|
||||
LIST_DELETE(&lf->list);
|
||||
LIST_APPEND(&old->send.http.uri_fmt, &lf->list);
|
||||
}
|
||||
lf_expr_init(&old->send.http.uri_fmt);
|
||||
lf_expr_xfer(&new->send.http.uri_fmt, &old->send.http.uri_fmt);
|
||||
}
|
||||
|
||||
if (isttest(new->send.http.vsn)) {
|
||||
@ -3536,22 +3532,19 @@ void tcpcheck_overwrite_send_http_rule(struct tcpcheck_rule *old, struct tcpchec
|
||||
if (!(old->send.http.flags & TCPCHK_SND_HTTP_FL_BODY_FMT))
|
||||
istfree(&old->send.http.body);
|
||||
else
|
||||
free_logformat_list(&old->send.http.body_fmt);
|
||||
lf_expr_deinit(&old->send.http.body_fmt);
|
||||
old->send.http.flags &= ~TCPCHK_SND_HTTP_FL_BODY_FMT;
|
||||
old->send.http.body = new->send.http.body;
|
||||
new->send.http.body = IST_NULL;
|
||||
}
|
||||
else if ((new->send.http.flags & TCPCHK_SND_HTTP_FL_BODY_FMT) && !LIST_ISEMPTY(&new->send.http.body_fmt)) {
|
||||
else if ((new->send.http.flags & TCPCHK_SND_HTTP_FL_BODY_FMT) && !lf_expr_isempty(&new->send.http.body_fmt)) {
|
||||
if (!(old->send.http.flags & TCPCHK_SND_HTTP_FL_BODY_FMT))
|
||||
istfree(&old->send.http.body);
|
||||
else
|
||||
free_logformat_list(&old->send.http.body_fmt);
|
||||
lf_expr_deinit(&old->send.http.body_fmt);
|
||||
old->send.http.flags |= TCPCHK_SND_HTTP_FL_BODY_FMT;
|
||||
LIST_INIT(&old->send.http.body_fmt);
|
||||
list_for_each_entry_safe(lf, lfb, &new->send.http.body_fmt, list) {
|
||||
LIST_DELETE(&lf->list);
|
||||
LIST_APPEND(&old->send.http.body_fmt, &lf->list);
|
||||
}
|
||||
lf_expr_init(&old->send.http.body_fmt);
|
||||
lf_expr_xfer(&new->send.http.body_fmt, &old->send.http.body_fmt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3802,8 +3795,8 @@ int add_tcpcheck_expect_str(struct tcpcheck_rules *rules, const char *str)
|
||||
|
||||
expect = &tcpcheck->expect;
|
||||
expect->type = TCPCHK_EXPECT_STRING;
|
||||
LIST_INIT(&expect->onerror_fmt);
|
||||
LIST_INIT(&expect->onsuccess_fmt);
|
||||
lf_expr_init(&expect->onerror_fmt);
|
||||
lf_expr_init(&expect->onsuccess_fmt);
|
||||
expect->ok_status = HCHK_STATUS_L7OKD;
|
||||
expect->err_status = HCHK_STATUS_L7RSP;
|
||||
expect->tout_status = HCHK_STATUS_L7TOUT;
|
||||
|
@ -787,7 +787,7 @@ static enum act_return action_store(struct act_rule *rule, struct proxy *px,
|
||||
/* Process the expression. */
|
||||
memset(&smp, 0, sizeof(smp));
|
||||
|
||||
if (!LIST_ISEMPTY(&rule->arg.vars.fmt)) {
|
||||
if (!lf_expr_isempty(&rule->arg.vars.fmt)) {
|
||||
/* a format-string is used */
|
||||
|
||||
fmtstr = alloc_trash_chunk();
|
||||
@ -838,7 +838,7 @@ static enum act_return action_clear(struct act_rule *rule, struct proxy *px,
|
||||
|
||||
static void release_store_rule(struct act_rule *rule)
|
||||
{
|
||||
free_logformat_list(&rule->arg.vars.fmt);
|
||||
lf_expr_deinit(&rule->arg.vars.fmt);
|
||||
|
||||
release_sample_expr(rule->arg.vars.expr);
|
||||
}
|
||||
@ -942,7 +942,7 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
|
||||
condition = istsplit(&var, ',');
|
||||
}
|
||||
|
||||
LIST_INIT(&rule->arg.vars.fmt);
|
||||
lf_expr_init(&rule->arg.vars.fmt);
|
||||
if (!vars_hash_name(var_name, var_len, &rule->arg.vars.scope, &rule->arg.vars.name_hash, err))
|
||||
return ACT_RET_PRS_ERR;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user