diff --git a/include/haproxy/action-t.h b/include/haproxy/action-t.h index e5720428f..eee16a312 100644 --- a/include/haproxy/action-t.h +++ b/include/haproxy/action-t.h @@ -25,6 +25,7 @@ #include #include #include +#include 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; diff --git a/include/haproxy/fcgi-app-t.h b/include/haproxy/fcgi-app-t.h index fb6ab2740..6233aef6e 100644 --- a/include/haproxy/fcgi-app-t.h +++ b/include/haproxy/fcgi-app-t.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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; }; diff --git a/include/haproxy/http_htx-t.h b/include/haproxy/http_htx-t.h index 8051925e2..1dd86aa0f 100644 --- a/include/haproxy/http_htx-t.h +++ b/include/haproxy/http_htx-t.h @@ -28,6 +28,7 @@ #include #include +#include #include /* 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 */ diff --git a/include/haproxy/log-t.h b/include/haproxy/log-t.h index 91e418051..d9d41f534 100644 --- a/include/haproxy/log-t.h +++ b/include/haproxy/log-t.h @@ -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. */ diff --git a/include/haproxy/log.h b/include/haproxy/log.h index e70970f63..b0e87ccf9 100644 --- a/include/haproxy/log.h +++ b/include/haproxy/log.h @@ -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); diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index d76eed083..fb44a2cc8 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -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; diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h index 9dd77b12f..70489ff78 100644 --- a/include/haproxy/server-t.h +++ b/include/haproxy/server-t.h @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -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; }; diff --git a/include/haproxy/stream.h b/include/haproxy/stream.h index a8840072e..12c58b891 100644 --- a/include/haproxy/stream.h +++ b/include/haproxy/stream.h @@ -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); diff --git a/include/haproxy/tcpcheck-t.h b/include/haproxy/tcpcheck-t.h index 887899550..22310eee0 100644 --- a/include/haproxy/tcpcheck-t.h +++ b/include/haproxy/tcpcheck-t.h @@ -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 { diff --git a/src/cfgparse.c b/src/cfgparse.c index 8a445da38..2df386e2c 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3127,7 +3127,7 @@ int check_config_validity() * 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 @@ int check_config_validity() 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 @@ int check_config_validity() /* 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 @@ int check_config_validity() * 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 @@ int check_config_validity() 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 @@ int check_config_validity() /* 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 @@ int check_config_validity() 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; diff --git a/src/cli.c b/src/cli.c index ab67abd3c..30593f130 100644 --- a/src/cli.c +++ b/src/cli.c @@ -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); diff --git a/src/connection.c b/src/connection.c index 54fad8994..f9e05c373 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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; diff --git a/src/fcgi-app.c b/src/fcgi-app.c index dcd7fd224..e8117a332 100644 --- a/src/fcgi-app.c +++ b/src/fcgi-app.c @@ -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, diff --git a/src/frontend.c b/src/frontend.c index ad2e39ecb..e9b3bc069 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -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))) diff --git a/src/http_act.c b/src/http_act.c index ebc2bcc68..e6a4390b7 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -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; diff --git a/src/http_ana.c b/src/http_ana.c index 91aaeb451..5249b557f 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -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); diff --git a/src/http_fetch.c b/src/http_fetch.c index 6e27c6630..ad1e8c543 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -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) diff --git a/src/http_htx.c b/src/http_htx.c index 954473db3..2cd738f77 100644 --- a/src/http_htx.c +++ b/src/http_htx.c @@ -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; diff --git a/src/http_rules.c b/src/http_rules.c index 9fde30aca..b1f60c2e7 100644 --- a/src/http_rules.c +++ b/src/http_rules.c @@ -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 */ diff --git a/src/log.c b/src/log.c index 1dcdd4ba4..86a2edbd6 100644 --- a/src/log.c +++ b/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 nor 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 and add a node to upon + * Parse the sample fetch expression and add a node to upon * success. The curpx->conf.args.ctx must be set by the caller. If an end pointer * is passed in , 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 based on , 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 to + * at the end of the operation, 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 and */ + 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 based on , and stops before reaching * 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); diff --git a/src/proxy.c b/src/proxy.c index c56007acf..9002954c5 100644 --- a/src/proxy.c +++ b/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); diff --git a/src/server.c b/src/server.c index fc5a45820..e537473e9 100644 --- a/src/server.c +++ b/src/server.c @@ -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) { diff --git a/src/session.c b/src/session.c index 6591fd199..fd5d60038 100644 --- a/src/session.c +++ b/src/session.c @@ -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); } diff --git a/src/stream.c b/src/stream.c index 7052f7c30..f233d6ef4 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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; diff --git a/src/tcpcheck.c b/src/tcpcheck.c index 6efca5bf5..b4f959086 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -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; diff --git a/src/vars.c b/src/vars.c index a3433b5b4..6447818ed 100644 --- a/src/vars.c +++ b/src/vars.c @@ -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;