]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: proxy/log: leverage lf_expr API for logformat preparsing
authorAurelien DARRAGON <adarragon@haproxy.com>
Tue, 5 Mar 2024 14:44:43 +0000 (15:44 +0100)
committerAurelien DARRAGON <adarragon@haproxy.com>
Thu, 4 Apr 2024 17:10:01 +0000 (19:10 +0200)
Currently, the way proxy-oriented logformat directives are handled is way
too complicated. Indeed, "log-format", "log-format-error", "log-format-sd"
and "unique-id-format" all rely on preparsing hints stored inside
proxy->conf member struct. Those preparsing hints include the original
string that should be compiled once the proxy parameters are known plus
the config file and line number where the string was found to generate
precise error messages in case of failure during the compiling process
that happens within check_config_validity().

Now that lf_expr API permits to compile a lf_expr struct that was
previously prepared (with original string and config hints), let's
leverage lf_expr_compile() from check_config_validity() and instead
of relying on individual proxy->conf hints for each logformat expression,
store string and config hints in the lf_expr struct directly and use
lf_expr helpers funcs to handle them when relevant (ie: original
logformat string freeing is now done at a central place inside
lf_expr_deinit(), which allows for some simplifications)

Doing so allows us to greatly simplify the preparsing logic for those 4
proxy directives, and to finally save some space in the proxy struct.

Also, since httpclient proxy has its "logformat" automatically compiled
in check_config_validity(), we now use the file hint from the logformat
expression struct to set an explicit name that will be reported in case
of error ("parsing [httpclient:0] : ...") and remove the extraneous check
in httpclient_precheck() (logformat was parsed twice previously..)

include/haproxy/proxy-t.h
src/cfgparse-listen.c
src/cfgparse.c
src/http_client.c
src/log.c
src/proxy.c
src/ssl_ocsp.c

index 08ec3ec003360f6ca1876b709ea86a7ee7bde55c..3dfa4d818db0fd3b1232730690950853cfc67c6e 100644 (file)
@@ -427,18 +427,6 @@ struct proxy {
                struct arg_list args;           /* sample arg list that need to be resolved */
                unsigned int refcount;          /* refcount on this proxy (only used for default proxy for now) */
                struct ebpt_node by_name;       /* proxies are stored sorted by name here */
-               char *logformat_string;         /* log format string */
-               char *lfs_file;                 /* file name where the logformat string appears (strdup) */
-               int   lfs_line;                 /* file name where the logformat string appears */
-               int   uif_line;                 /* file name where the unique-id-format string appears */
-               char *uif_file;                 /* file name where the unique-id-format string appears (strdup) */
-               char *uniqueid_format_string;   /* unique-id format string */
-               char *logformat_sd_string;      /* log format string for the RFC5424 structured-data part */
-               char *lfsd_file;                /* file name where the structured-data logformat string for RFC5424 appears (strdup) */
-               int  lfsd_line;                 /* file name where the structured-data logformat string for RFC5424 appears */
-               char *error_logformat_string;
-               char *elfs_file;
-               int elfs_line;
                struct list lf_checks;          /* list of logformats found in the proxy section that needs to be checked during postparse */
        } conf;                                 /* config information */
        struct http_ext *http_ext;              /* http ext options */
index a97b1e55de6545ebbe5df8ebffee9d4bced08701..c4b266e3e14fc49f4460a6afab145e7131a1bf43 100644 (file)
@@ -2096,33 +2096,27 @@ stats_error_parsing:
                                if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
                                        goto out;
                        }
-                       if (curproxy->conf.logformat_string && curproxy->cap & PR_CAP_DEF) {
+                       if (curproxy->logformat.str && curproxy->cap & PR_CAP_DEF) {
                                char *oldlogformat = "log-format";
                                char *clflogformat = "";
 
-                               if (curproxy->conf.logformat_string == default_http_log_format)
+                               if (curproxy->logformat.str == default_http_log_format)
                                        oldlogformat = "option httplog";
-                               else if (curproxy->conf.logformat_string == default_tcp_log_format)
+                               else if (curproxy->logformat.str == default_tcp_log_format)
                                        oldlogformat = "option tcplog";
-                               else if (curproxy->conf.logformat_string == clf_http_log_format)
+                               else if (curproxy->logformat.str == clf_http_log_format)
                                        oldlogformat = "option httplog clf";
-                               else if (curproxy->conf.logformat_string == default_https_log_format)
+                               else if (curproxy->logformat.str == default_https_log_format)
                                        oldlogformat = "option httpslog";
                                if (logformat == clf_http_log_format)
                                        clflogformat = " clf";
                                ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
                                           file, linenum, clflogformat, oldlogformat);
                        }
-                       if (curproxy->conf.logformat_string != default_http_log_format &&
-                           curproxy->conf.logformat_string != default_tcp_log_format &&
-                           curproxy->conf.logformat_string != clf_http_log_format &&
-                           curproxy->conf.logformat_string != default_https_log_format)
-                               free(curproxy->conf.logformat_string);
-                       curproxy->conf.logformat_string = logformat;
-
-                       free(curproxy->conf.lfs_file);
-                       curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
-                       curproxy->conf.lfs_line = curproxy->conf.args.line;
+                       lf_expr_deinit(&curproxy->logformat);
+                       curproxy->logformat.str = logformat;
+                       curproxy->logformat.conf.file = strdup(curproxy->conf.args.file);
+                       curproxy->logformat.conf.line = curproxy->conf.args.line;
 
                        if (!(curproxy->cap & PR_CAP_DEF) && !(curproxy->cap & PR_CAP_FE)) {
                                ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
@@ -2131,31 +2125,25 @@ stats_error_parsing:
                        }
                }
                else if (strcmp(args[1], "tcplog") == 0) {
-                       if (curproxy->conf.logformat_string && curproxy->cap & PR_CAP_DEF) {
+                       if (curproxy->logformat.str && curproxy->cap & PR_CAP_DEF) {
                                char *oldlogformat = "log-format";
 
-                               if (curproxy->conf.logformat_string == default_http_log_format)
+                               if (curproxy->logformat.str == default_http_log_format)
                                        oldlogformat = "option httplog";
-                               else if (curproxy->conf.logformat_string == default_tcp_log_format)
+                               else if (curproxy->logformat.str == default_tcp_log_format)
                                        oldlogformat = "option tcplog";
-                               else if (curproxy->conf.logformat_string == clf_http_log_format)
+                               else if (curproxy->logformat.str == clf_http_log_format)
                                        oldlogformat = "option httplog clf";
-                               else if (curproxy->conf.logformat_string == default_https_log_format)
+                               else if (curproxy->logformat.str == default_https_log_format)
                                        oldlogformat = "option httpslog";
                                ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
                                           file, linenum, oldlogformat);
                        }
                        /* generate a detailed TCP log */
-                       if (curproxy->conf.logformat_string != default_http_log_format &&
-                           curproxy->conf.logformat_string != default_tcp_log_format &&
-                           curproxy->conf.logformat_string != clf_http_log_format &&
-                           curproxy->conf.logformat_string != default_https_log_format)
-                               free(curproxy->conf.logformat_string);
-                       curproxy->conf.logformat_string = default_tcp_log_format;
-
-                       free(curproxy->conf.lfs_file);
-                       curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
-                       curproxy->conf.lfs_line = curproxy->conf.args.line;
+                       lf_expr_deinit(&curproxy->logformat);
+                       curproxy->logformat.str = default_tcp_log_format;
+                       curproxy->logformat.conf.file = strdup(curproxy->conf.args.file);
+                       curproxy->logformat.conf.line = curproxy->conf.args.line;
 
                        if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
                                goto out;
@@ -2170,30 +2158,24 @@ stats_error_parsing:
                        char *logformat;
                        /* generate a complete HTTP log */
                        logformat = default_https_log_format;
-                       if (curproxy->conf.logformat_string && curproxy->cap & PR_CAP_DEF) {
+                       if (curproxy->logformat.str && curproxy->cap & PR_CAP_DEF) {
                                char *oldlogformat = "log-format";
 
-                               if (curproxy->conf.logformat_string == default_http_log_format)
+                               if (curproxy->logformat.str == default_http_log_format)
                                        oldlogformat = "option httplog";
-                               else if (curproxy->conf.logformat_string == default_tcp_log_format)
+                               else if (curproxy->logformat.str == default_tcp_log_format)
                                        oldlogformat = "option tcplog";
-                               else if (curproxy->conf.logformat_string == clf_http_log_format)
+                               else if (curproxy->logformat.str == clf_http_log_format)
                                        oldlogformat = "option httplog clf";
-                               else if (curproxy->conf.logformat_string == default_https_log_format)
+                               else if (curproxy->logformat.str == default_https_log_format)
                                        oldlogformat = "option httpslog";
                                ha_warning("parsing [%s:%d]: 'option httplog' overrides previous '%s' in 'defaults' section.\n",
                                           file, linenum, oldlogformat);
                        }
-                       if (curproxy->conf.logformat_string != default_http_log_format &&
-                           curproxy->conf.logformat_string != default_tcp_log_format &&
-                           curproxy->conf.logformat_string != clf_http_log_format &&
-                           curproxy->conf.logformat_string != default_https_log_format)
-                               free(curproxy->conf.logformat_string);
-                       curproxy->conf.logformat_string = logformat;
-
-                       free(curproxy->conf.lfs_file);
-                       curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
-                       curproxy->conf.lfs_line = curproxy->conf.args.line;
+                       lf_expr_deinit(&curproxy->logformat);
+                       curproxy->logformat.str = logformat;
+                       curproxy->logformat.conf.file = strdup(curproxy->conf.args.file);
+                       curproxy->logformat.conf.line = curproxy->conf.args.line;
 
                        if (!(curproxy->cap & PR_CAP_DEF) && !(curproxy->cap & PR_CAP_FE)) {
                                ha_warning("parsing [%s:%d] : backend '%s' : 'option httpslog' directive is ignored in backends.\n",
@@ -2591,14 +2573,12 @@ stats_error_parsing:
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
-               free(curproxy->conf.uniqueid_format_string);
-               curproxy->conf.uniqueid_format_string = strdup(args[1]);
-               if (!curproxy->conf.uniqueid_format_string)
+               lf_expr_deinit(&curproxy->format_unique_id);
+               curproxy->format_unique_id.str = strdup(args[1]);
+               if (!curproxy->format_unique_id.str)
                        goto alloc_error;
-
-               free(curproxy->conf.uif_file);
-               curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
-               curproxy->conf.uif_line = curproxy->conf.args.line;
+               curproxy->format_unique_id.conf.file = strdup(curproxy->conf.args.file);
+               curproxy->format_unique_id.conf.line = curproxy->conf.args.line;
        }
 
        else if (strcmp(args[0], "unique-id-header") == 0) {
@@ -2630,32 +2610,26 @@ stats_error_parsing:
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
-               if (curproxy->conf.logformat_string && curproxy->cap & PR_CAP_DEF) {
+               if (curproxy->logformat.str && curproxy->cap & PR_CAP_DEF) {
                        char *oldlogformat = "log-format";
 
-                       if (curproxy->conf.logformat_string == default_http_log_format)
+                       if (curproxy->logformat.str == default_http_log_format)
                                oldlogformat = "option httplog";
-                       else if (curproxy->conf.logformat_string == default_tcp_log_format)
+                       else if (curproxy->logformat.str == default_tcp_log_format)
                                oldlogformat = "option tcplog";
-                       else if (curproxy->conf.logformat_string == clf_http_log_format)
+                       else if (curproxy->logformat.str == clf_http_log_format)
                                oldlogformat = "option httplog clf";
-                       else if (curproxy->conf.logformat_string == default_https_log_format)
+                       else if (curproxy->logformat.str == default_https_log_format)
                                oldlogformat = "option httpslog";
                        ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
                                   file, linenum, oldlogformat);
                }
-               if (curproxy->conf.logformat_string != default_http_log_format &&
-                   curproxy->conf.logformat_string != default_tcp_log_format &&
-                   curproxy->conf.logformat_string != clf_http_log_format &&
-                   curproxy->conf.logformat_string != default_https_log_format)
-                       free(curproxy->conf.logformat_string);
-               curproxy->conf.logformat_string = strdup(args[1]);
-               if (!curproxy->conf.logformat_string)
+               lf_expr_deinit(&curproxy->logformat);
+               curproxy->logformat.str = strdup(args[1]);
+               if (!curproxy->logformat.str)
                        goto alloc_error;
-
-               free(curproxy->conf.lfs_file);
-               curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
-               curproxy->conf.lfs_line = curproxy->conf.args.line;
+               curproxy->logformat.conf.file = strdup(curproxy->conf.args.file);
+               curproxy->logformat.conf.line = curproxy->conf.args.line;
 
                /* get a chance to improve log-format error reporting by
                 * reporting the correct line-number when possible.
@@ -2678,15 +2652,12 @@ stats_error_parsing:
                        goto out;
                }
 
-               if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
-                       free(curproxy->conf.logformat_sd_string);
-               curproxy->conf.logformat_sd_string = strdup(args[1]);
-               if (!curproxy->conf.logformat_sd_string)
+               lf_expr_deinit(&curproxy->logformat_sd);
+               curproxy->logformat_sd.str = strdup(args[1]);
+               if (!curproxy->logformat_sd.str)
                        goto alloc_error;
-
-               free(curproxy->conf.lfsd_file);
-               curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
-               curproxy->conf.lfsd_line = curproxy->conf.args.line;
+               curproxy->logformat_sd.conf.file = strdup(curproxy->conf.args.file);
+               curproxy->logformat_sd.conf.line = curproxy->conf.args.line;
 
                /* get a chance to improve log-format-sd error reporting by
                 * reporting the correct line-number when possible.
@@ -2708,18 +2679,17 @@ stats_error_parsing:
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
-               if (curproxy->conf.error_logformat_string && curproxy->cap & PR_CAP_DEF) {
+               if (curproxy->logformat_error.str && curproxy->cap & PR_CAP_DEF) {
                        ha_warning("parsing [%s:%d]: 'error-log-format' overrides previous 'error-log-format' in 'defaults' section.\n",
                                   file, linenum);
                }
-               free(curproxy->conf.error_logformat_string);
-               curproxy->conf.error_logformat_string = strdup(args[1]);
-               if (!curproxy->conf.error_logformat_string)
+               lf_expr_deinit(&curproxy->logformat_error);
+               curproxy->logformat_error.str = strdup(args[1]);
+               if (!curproxy->logformat_error.str)
                        goto alloc_error;
 
-               free(curproxy->conf.elfs_file);
-               curproxy->conf.elfs_file = strdup(curproxy->conf.args.file);
-               curproxy->conf.elfs_line = curproxy->conf.args.line;
+               curproxy->logformat_error.conf.file = strdup(curproxy->conf.args.file);
+               curproxy->logformat_error.conf.line = curproxy->conf.args.line;;
 
                /* get a chance to improve log-format error reporting by
                 * reporting the correct line-number when possible.
index 2df386e2c90d07699c29177ea20c6d957e2be73e..15fca551bc33e95bd9611db7da53e8d31ecbf742 100644 (file)
@@ -3382,9 +3382,9 @@ out_uri_auth_compat:
                /* check whether we have a logger that uses RFC5424 log format */
                list_for_each_entry(tmplogger, &curproxy->loggers, list) {
                        if (tmplogger->format == LOG_FORMAT_RFC5424) {
-                               if (!curproxy->conf.logformat_sd_string) {
+                               if (!curproxy->logformat_sd.str) {
                                        /* set the default logformat_sd_string */
-                                       curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
+                                       curproxy->logformat_sd.str = default_rfc5424_sd_log_format;
                                }
                                break;
                        }
@@ -3392,31 +3392,21 @@ out_uri_auth_compat:
 
                /* compile the log format */
                if (!(curproxy->cap & PR_CAP_FE)) {
-                       if (curproxy->conf.logformat_string != default_http_log_format &&
-                           curproxy->conf.logformat_string != default_tcp_log_format &&
-                           curproxy->conf.logformat_string != clf_http_log_format)
-                               free(curproxy->conf.logformat_string);
-                       curproxy->conf.logformat_string = NULL;
-                       ha_free(&curproxy->conf.lfs_file);
-                       curproxy->conf.lfs_line = 0;
-
-                       if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
-                               free(curproxy->conf.logformat_sd_string);
-                       curproxy->conf.logformat_sd_string = NULL;
-                       ha_free(&curproxy->conf.lfsd_file);
-                       curproxy->conf.lfsd_line = 0;
-               }
-
-               if (curproxy->conf.logformat_string) {
+                       lf_expr_deinit(&curproxy->logformat);
+                       lf_expr_deinit(&curproxy->logformat_sd);
+               }
+
+               if (curproxy->logformat.str) {
                        curproxy->conf.args.ctx = ARGC_LOG;
-                       curproxy->conf.args.file = curproxy->conf.lfs_file;
-                       curproxy->conf.args.line = curproxy->conf.lfs_line;
+                       curproxy->conf.args.file = curproxy->logformat.conf.file;
+                       curproxy->conf.args.line = curproxy->logformat.conf.line;
                        err = NULL;
-                       if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat,
+                       if (!lf_expr_compile(&curproxy->logformat, &curproxy->conf.args,
                                                    LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
-                                                   SMP_VAL_FE_LOG_END, &err)) {
+                                                   SMP_VAL_FE_LOG_END, &err) ||
+                           !lf_expr_postcheck(&curproxy->logformat, curproxy, &err)) {
                                ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
-                                        curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
+                                        curproxy->logformat.conf.file, curproxy->logformat.conf.line, err);
                                free(err);
                                cfgerr++;
                        }
@@ -3424,21 +3414,18 @@ out_uri_auth_compat:
                        curproxy->conf.args.line = 0;
                }
 
-               if (curproxy->conf.logformat_sd_string) {
+               if (curproxy->logformat_sd.str) {
                        curproxy->conf.args.ctx = ARGC_LOGSD;
-                       curproxy->conf.args.file = curproxy->conf.lfsd_file;
-                       curproxy->conf.args.line = curproxy->conf.lfsd_line;
+                       curproxy->conf.args.file = curproxy->logformat_sd.conf.file;
+                       curproxy->conf.args.line = curproxy->logformat_sd.conf.line;
                        err = NULL;
-                       if (!parse_logformat_string(curproxy->conf.logformat_sd_string, curproxy, &curproxy->logformat_sd,
+                       if (!lf_expr_compile(&curproxy->logformat_sd, &curproxy->conf.args,
                                                    LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
-                                                   SMP_VAL_FE_LOG_END, &err)) {
-                               ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
-                                        curproxy->conf.lfsd_file, curproxy->conf.lfsd_line, err);
-                               free(err);
-                               cfgerr++;
-                       } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
+                                                   SMP_VAL_FE_LOG_END, &err) ||
+                           !add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err) ||
+                           !lf_expr_postcheck(&curproxy->logformat_sd, curproxy, &err)) {
                                ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
-                                        curproxy->conf.lfsd_file, curproxy->conf.lfsd_line, err);
+                                        curproxy->logformat_sd.conf.file, curproxy->logformat_sd.conf.line, err);
                                free(err);
                                cfgerr++;
                        }
@@ -3446,21 +3433,22 @@ out_uri_auth_compat:
                        curproxy->conf.args.line = 0;
                }
 
-               if (curproxy->conf.uniqueid_format_string) {
+               if (curproxy->format_unique_id.str) {
                        int where = 0;
 
                        curproxy->conf.args.ctx = ARGC_UIF;
-                       curproxy->conf.args.file = curproxy->conf.uif_file;
-                       curproxy->conf.args.line = curproxy->conf.uif_line;
+                       curproxy->conf.args.file = curproxy->format_unique_id.conf.file;
+                       curproxy->conf.args.line = curproxy->format_unique_id.conf.line;
                        err = NULL;
                        if (curproxy->cap & PR_CAP_FE)
                                where |= SMP_VAL_FE_HRQ_HDR;
                        if (curproxy->cap & PR_CAP_BE)
                                where |= SMP_VAL_BE_HRQ_HDR;
-                       if (!parse_logformat_string(curproxy->conf.uniqueid_format_string, curproxy, &curproxy->format_unique_id,
-                                                   LOG_OPT_HTTP|LOG_OPT_MERGE_SPACES, where, &err)) {
+                       if (!lf_expr_compile(&curproxy->format_unique_id, &curproxy->conf.args,
+                                                   LOG_OPT_HTTP|LOG_OPT_MERGE_SPACES, where, &err) ||
+                           !lf_expr_postcheck(&curproxy->format_unique_id, curproxy, &err)) {
                                ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
-                                        curproxy->conf.uif_file, curproxy->conf.uif_line, err);
+                                        curproxy->format_unique_id.conf.file, curproxy->format_unique_id.conf.line, err);
                                free(err);
                                cfgerr++;
                        }
@@ -3468,16 +3456,17 @@ out_uri_auth_compat:
                        curproxy->conf.args.line = 0;
                }
 
-               if (curproxy->conf.error_logformat_string) {
+               if (curproxy->logformat_error.str) {
                        curproxy->conf.args.ctx = ARGC_LOG;
-                       curproxy->conf.args.file = curproxy->conf.elfs_file;
-                       curproxy->conf.args.line = curproxy->conf.elfs_line;
+                       curproxy->conf.args.file = curproxy->logformat_error.conf.file;
+                       curproxy->conf.args.line = curproxy->logformat_error.conf.line;
                        err = NULL;
-                       if (!parse_logformat_string(curproxy->conf.error_logformat_string, curproxy, &curproxy->logformat_error,
+                       if (!lf_expr_compile(&curproxy->logformat_error, &curproxy->conf.args,
                                                    LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
-                                                   SMP_VAL_FE_LOG_END, &err)) {
+                                                   SMP_VAL_FE_LOG_END, &err) ||
+                           !lf_expr_postcheck(&curproxy->logformat_error, curproxy, &err)) {
                                ha_alert("Parsing [%s:%d]: failed to parse error-log-format : %s.\n",
-                                        curproxy->conf.elfs_file, curproxy->conf.elfs_line, err);
+                                        curproxy->logformat_error.conf.file, curproxy->logformat_error.conf.line, err);
                                free(err);
                                cfgerr++;
                        }
index d8d9654a2152d8a26a476e9819b3df0621c0579f..96ddd037832ef36992939922c82638b3257d7703 100644 (file)
@@ -1219,7 +1219,8 @@ struct proxy *httpclient_create_proxy(const char *id)
        px->timeout.connect = httpclient_timeout_connect;
        px->timeout.client = TICK_ETERNITY;
        /* The HTTP Client use the "option httplog" with the global loggers */
-       px->conf.logformat_string = httpclient_log_format;
+       px->logformat.str = httpclient_log_format;
+       px->logformat.conf.file = strdup("httpclient");
        px->http_needed = 1;
 
        /* clear HTTP server */
@@ -1335,34 +1336,13 @@ err:
  */
 static int httpclient_precheck()
 {
-       int err_code = ERR_NONE;
-       char *errmsg = NULL;
-
        /* initialize the default httpclient_proxy which is used for the CLI and the lua */
 
        httpclient_proxy = httpclient_create_proxy("<HTTPCLIENT>");
        if (!httpclient_proxy)
                return ERR_RETRYABLE;
-       if (httpclient_proxy->conf.logformat_string) {
-               httpclient_proxy->conf.args.ctx = ARGC_LOG;
-               if (!parse_logformat_string(httpclient_proxy->conf.logformat_string,
-                                           httpclient_proxy, &httpclient_proxy->logformat,
-                                           LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
-                                           SMP_VAL_FE_LOG_END, &errmsg)) {
-                       memprintf(&errmsg, "failed to parse log-format : %s.", errmsg);
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       goto err;
-               }
-               httpclient_proxy->conf.args.file = NULL;
-               httpclient_proxy->conf.args.line = 0;
-       }
 
- err:
-       if (err_code & ERR_CODE) {
-               ha_alert("httpclient: failed to initialize: %s\n", errmsg);
-               free(errmsg);
-       }
-       return err_code;
+       return ERR_NONE;
 }
 
 /* Initialize the logs for every proxy dedicated to the httpclient */
index 8b414cc58377c2a6c7399dcbb53d9cf9dc6ffa1a..13d23351b1fe8a3029e6e3328710bf98c4dd31d9 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -272,6 +272,36 @@ char *log_format = NULL;
  */
 char default_rfc5424_sd_log_format[] = "- ";
 
+/* returns true if the input logformat string is one of the default ones declared
+ * above
+ */
+static inline int logformat_str_isdefault(const char *str)
+{
+       return str == httpclient_log_format ||
+              str == default_http_log_format ||
+              str == default_https_log_format ||
+              str == clf_http_log_format ||
+              str == default_tcp_log_format ||
+              str == default_rfc5424_sd_log_format;
+}
+
+/* free logformat str if it is not a default (static) one */
+static inline void logformat_str_free(char **str)
+{
+       if (!logformat_str_isdefault(*str))
+               ha_free(str);
+}
+
+/* duplicate and return logformat str if it is not a default (static)
+ * one, else return the original one
+ */
+static inline char *logformat_str_dup(char *str)
+{
+       if (logformat_str_isdefault(str))
+               return str;
+       return strdup(str);
+}
+
 /* total number of dropped logs */
 unsigned int dropped_logs = 0;
 
@@ -549,7 +579,7 @@ static int add_sample_to_logformat_list(char *text, char *name, int name_len, in
 int lf_expr_compile(struct lf_expr *lf_expr,
                     struct arg_list *al, int options, int cap, char **err)
 {
-       char *fmt = lf_expr->str; /* will be freed */
+       char *fmt = lf_expr->str; /* will be freed unless default */
        char *sp, *str, *backfmt; /* start pointer for text parts */
        char *arg = NULL; /* start pointer for args */
        char *tag = NULL; /* start pointer for tags */
@@ -758,12 +788,12 @@ int lf_expr_compile(struct lf_expr *lf_expr,
                memprintf(err, "truncated line after '%s'", tag ? tag : arg ? arg : "%");
                goto fail;
        }
-       ha_free(&fmt);
+       logformat_str_free(&fmt);
        ha_free(&backfmt);
 
        return 1;
  fail:
-       ha_free(&fmt);
+       logformat_str_free(&fmt);
        ha_free(&backfmt);
        return 0;
 }
@@ -2768,7 +2798,7 @@ void lf_expr_deinit(struct lf_expr *expr)
        if ((expr->flags & LF_FL_COMPILED))
                free_logformat_list(&expr->nodes);
        else
-               free(expr->str);
+               logformat_str_free(&expr->str);
        free(expr->conf.file);
        /* remove from parent list (if any) */
        LIST_DEL_INIT(&expr->list);
@@ -2819,7 +2849,7 @@ int lf_expr_dup(const struct lf_expr *orig, struct lf_expr *dest)
        BUG_ON((orig->flags & LF_FL_COMPILED));
        lf_expr_deinit(dest);
        if (orig->str) {
-               dest->str = strdup(orig->str);
+               dest->str = logformat_str_dup(orig->str);
                if (!dest->str)
                        goto error;
        }
index 20fc15601b3f4ed6ac1bae47f9609636ca7ce204..2be87912f9fe517383ca1a5792b1f2c2d16302f2 100644 (file)
@@ -223,27 +223,10 @@ void free_proxy(struct proxy *p)
 #if defined(CONFIG_HAP_TRANSPARENT)
        free(p->conn_src.bind_hdr_name);
 #endif
-       if (p->conf.logformat_string != default_http_log_format &&
-           p->conf.logformat_string != default_tcp_log_format &&
-           p->conf.logformat_string != clf_http_log_format &&
-           p->conf.logformat_string != default_https_log_format &&
-           p->conf.logformat_string != httpclient_log_format)
-               free(p->conf.logformat_string);
-
-       free(p->conf.lfs_file);
-       free(p->conf.uniqueid_format_string);
        istfree(&p->header_unique_id);
-       free(p->conf.uif_file);
        if ((p->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_MAP)
                free(p->lbprm.map.srv);
 
-       if (p->conf.logformat_sd_string != default_rfc5424_sd_log_format)
-               free(p->conf.logformat_sd_string);
-       free(p->conf.lfsd_file);
-
-       free(p->conf.error_logformat_string);
-       free(p->conf.elfs_file);
-
        list_for_each_entry_safe(cond, condb, &p->mon_fail_cond, list) {
                LIST_DELETE(&cond->list);
                free_acl_cond(cond);
@@ -1279,19 +1262,19 @@ int proxy_cfg_ensure_no_http(struct proxy *curproxy)
                ha_warning("Layer 7 hash not possible for %s '%s' (needs 'mode http'). Falling back to round robin.\n",
                           proxy_type_str(curproxy), curproxy->id);
        }
-       if (curproxy->conf.logformat_string == default_http_log_format ||
-           curproxy->conf.logformat_string == clf_http_log_format) {
+       if (curproxy->logformat.str == default_http_log_format ||
+           curproxy->logformat.str == clf_http_log_format) {
                /* Note: we don't change the directive's file:line number */
-               curproxy->conf.logformat_string = default_tcp_log_format;
+               curproxy->logformat.str = default_tcp_log_format;
                ha_warning("parsing [%s:%d] : 'option httplog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n",
-                          curproxy->conf.lfs_file, curproxy->conf.lfs_line,
+                          curproxy->logformat.conf.file, curproxy->logformat.conf.line,
                           proxy_type_str(curproxy), curproxy->id);
        }
-       else if (curproxy->conf.logformat_string == default_https_log_format) {
+       else if (curproxy->logformat.str == default_https_log_format) {
                /* Note: we don't change the directive's file:line number */
-               curproxy->conf.logformat_string = default_tcp_log_format;
+               curproxy->logformat.str = default_tcp_log_format;
                ha_warning("parsing [%s:%d] : 'option httpslog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n",
-                          curproxy->conf.lfs_file, curproxy->conf.lfs_line,
+                          curproxy->logformat.conf.file, curproxy->logformat.conf.line,
                           proxy_type_str(curproxy), curproxy->id);
        }
 
@@ -1342,10 +1325,6 @@ void init_new_proxy(struct proxy *p)
        LIST_INIT(&p->tcp_req.l5_rules);
        MT_LIST_INIT(&p->listener_queue);
        LIST_INIT(&p->loggers);
-       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);
@@ -1395,6 +1374,11 @@ void proxy_preset_defaults(struct proxy *defproxy)
 
        srv_settings_init(&defproxy->defsrv);
 
+       lf_expr_init(&defproxy->logformat);
+       lf_expr_init(&defproxy->logformat_sd);
+       lf_expr_init(&defproxy->format_unique_id);
+       lf_expr_init(&defproxy->logformat_error);
+
        defproxy->email_alert.level = LOG_ALERT;
        defproxy->load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
 
@@ -1465,27 +1449,16 @@ void proxy_free_defaults(struct proxy *defproxy)
                h = h_next;
        }
 
-       if (defproxy->conf.logformat_string != default_http_log_format &&
-           defproxy->conf.logformat_string != default_tcp_log_format &&
-           defproxy->conf.logformat_string != clf_http_log_format &&
-           defproxy->conf.logformat_string != default_https_log_format) {
-               ha_free(&defproxy->conf.logformat_string);
-       }
-
-       if (defproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
-               ha_free(&defproxy->conf.logformat_sd_string);
+       lf_expr_deinit(&defproxy->logformat);
+       lf_expr_deinit(&defproxy->logformat_sd);
+       lf_expr_deinit(&defproxy->logformat_error);
+       lf_expr_deinit(&defproxy->format_unique_id);
 
        list_for_each_entry_safe(log, logb, &defproxy->loggers, list) {
                LIST_DEL_INIT(&log->list);
                free_logger(log);
        }
 
-       ha_free(&defproxy->conf.uniqueid_format_string);
-       ha_free(&defproxy->conf.error_logformat_string);
-       ha_free(&defproxy->conf.lfs_file);
-       ha_free(&defproxy->conf.lfsd_file);
-       ha_free(&defproxy->conf.uif_file);
-       ha_free(&defproxy->conf.elfs_file);
        chunk_destroy(&defproxy->log_tag);
 
        free_email_alert(defproxy);
@@ -1726,39 +1699,9 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
                if (defproxy->defbe.name)
                        curproxy->defbe.name = strdup(defproxy->defbe.name);
 
-               /* get either a pointer to the logformat string or a copy of it */
-               curproxy->conf.logformat_string = defproxy->conf.logformat_string;
-               if (curproxy->conf.logformat_string &&
-                   curproxy->conf.logformat_string != default_http_log_format &&
-                   curproxy->conf.logformat_string != default_tcp_log_format &&
-                   curproxy->conf.logformat_string != clf_http_log_format &&
-                   curproxy->conf.logformat_string != default_https_log_format)
-                       curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
-
-               if (defproxy->conf.lfs_file) {
-                       curproxy->conf.lfs_file = strdup(defproxy->conf.lfs_file);
-                       curproxy->conf.lfs_line = defproxy->conf.lfs_line;
-               }
-
-               /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
-               curproxy->conf.logformat_sd_string = defproxy->conf.logformat_sd_string;
-               if (curproxy->conf.logformat_sd_string &&
-                   curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
-                       curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
-
-               if (defproxy->conf.lfsd_file) {
-                       curproxy->conf.lfsd_file = strdup(defproxy->conf.lfsd_file);
-                       curproxy->conf.lfsd_line = defproxy->conf.lfsd_line;
-               }
-
-               curproxy->conf.error_logformat_string = defproxy->conf.error_logformat_string;
-               if (curproxy->conf.error_logformat_string)
-                       curproxy->conf.error_logformat_string = strdup(curproxy->conf.error_logformat_string);
-
-               if (defproxy->conf.elfs_file) {
-                       curproxy->conf.elfs_file = strdup(defproxy->conf.elfs_file);
-                       curproxy->conf.elfs_line = defproxy->conf.elfs_line;
-               }
+               lf_expr_dup(&defproxy->logformat, &curproxy->logformat);
+               lf_expr_dup(&defproxy->logformat_sd, &curproxy->logformat_sd);
+               lf_expr_dup(&defproxy->logformat_error, &curproxy->logformat_error);
        }
 
        if (curproxy->cap & PR_CAP_BE) {
@@ -1788,17 +1731,10 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
                LIST_APPEND(&curproxy->loggers, &node->list);
        }
 
-       curproxy->conf.uniqueid_format_string = defproxy->conf.uniqueid_format_string;
-       if (curproxy->conf.uniqueid_format_string)
-               curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
+       lf_expr_dup(&defproxy->format_unique_id, &curproxy->format_unique_id);
 
        chunk_dup(&curproxy->log_tag, &defproxy->log_tag);
 
-       if (defproxy->conf.uif_file) {
-               curproxy->conf.uif_file = strdup(defproxy->conf.uif_file);
-               curproxy->conf.uif_line = defproxy->conf.uif_line;
-       }
-
        /* copy default header unique id */
        if (isttest(defproxy->header_unique_id)) {
                const struct ist copy = istdup(defproxy->header_unique_id);
index 1add6bd009155e93d194993e69d784eaecc33a32..1b96200cae758a5aedab4df9165f8d6a6f34c5fc 100644 (file)
@@ -1405,7 +1405,7 @@ static int ssl_ocsp_update_precheck()
        httpclient_ocsp_update_px = httpclient_create_proxy("<OCSP-UPDATE>");
        if (!httpclient_ocsp_update_px)
                return ERR_RETRYABLE;
-       httpclient_ocsp_update_px->conf.logformat_string = httpclient_log_format;
+       httpclient_ocsp_update_px->logformat.str = httpclient_log_format;
        httpclient_ocsp_update_px->options2 |= PR_O2_NOLOGNORM;
 
        return ERR_NONE;