]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: fix option httplog validation with TCP frontends
authorWilly Tarreau <w@1wt.eu>
Thu, 31 May 2012 17:30:26 +0000 (19:30 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 31 May 2012 17:30:26 +0000 (19:30 +0200)
Option httplog needs to be checked only once the proxy has been validated,
so that its final mode (tcp/http) can be used. Also we need to check for
httplog before checking the log format, so that we can report a warning
about this specific option and not about the format it implies.

include/types/proxy.h
src/cfgparse.c
src/haproxy.c
src/proxy.c

index 622e1686c0d221248d58cc5da1c9637de50fcf41..15ed23af1ab18f392ce286e0c5bb07935a69db2e 100644 (file)
@@ -344,6 +344,8 @@ struct proxy {
        int no_options;                         /* PR_O_REDISP, PR_O_TRANSP, ... */
        int no_options2;                        /* PR_O2_* */
 
+       char *logformat_string;                 /* log format string */
+       char *uniqueid_format_string;           /* unique-id format string */
        struct {
                const char *file;               /* file where the section appears */
                int line;                       /* line where the section appears */
index 5bd2cfc37178f9cde23f98d2d0a117baddefca8b..a45acb15d13d96c3dcb5b8014712c325238d6345 100644 (file)
@@ -1345,7 +1345,6 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
        int err_code = 0;
        struct acl_cond *cond = NULL;
        struct logsrv *tmplogsrv;
-       struct logformat_node *tmplf;
        char *errmsg = NULL;
 
        if (!strcmp(args[0], "listen"))
@@ -1564,21 +1563,17 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        LIST_ADDQ(&curproxy->logsrvs, &node->list);
                }
 
-               /* copy default log_format to curproxy */
-               list_for_each_entry(tmplf, &defproxy.logformat, list) {
-                       struct logformat_node *node = malloc(sizeof(struct logformat_node));
-                       memcpy(node, tmplf, sizeof(struct logformat_node));
-                       LIST_INIT(&node->list);
-                       LIST_ADDQ(&curproxy->logformat, &node->list);
-               }
+               /* get either a pointer to the logformat string or a copy of it */
+               curproxy->logformat_string = defproxy.logformat_string;
+               if (curproxy->logformat_string &&
+                   curproxy->logformat_string != default_http_log_format &&
+                   curproxy->logformat_string != default_tcp_log_format &&
+                   curproxy->logformat_string != clf_http_log_format)
+                       curproxy->logformat_string = strdup(curproxy->logformat_string);
 
-               /* copy default unique_id to curproxy */
-               list_for_each_entry(tmplf, &defproxy.format_unique_id, list) {
-                       struct logformat_node *node = malloc(sizeof(struct logformat_node));
-                       memcpy(node, tmplf, sizeof(struct logformat_node));
-                       LIST_INIT(&node->list);
-                       LIST_ADDQ(&curproxy->format_unique_id, &node->list);
-               }
+               curproxy->uniqueid_format_string = defproxy.uniqueid_format_string;
+               if (curproxy->uniqueid_format_string)
+                       curproxy->uniqueid_format_string = strdup(curproxy->uniqueid_format_string);
 
                /* copy default header unique id */
                if (defproxy.header_unique_id)
@@ -1614,6 +1609,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                free(defproxy.expect_str);
                if (defproxy.expect_regex) regfree(defproxy.expect_regex);
 
+               if (defproxy.logformat_string == default_http_log_format ||
+                   defproxy.logformat_string == default_tcp_log_format ||
+                   defproxy.logformat_string == clf_http_log_format)
+                       free(defproxy.logformat_string);
+
+               free(defproxy.uniqueid_format_string);
+
                for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
                        chunk_destroy(&defproxy.errmsg[rc]);
 
@@ -3384,13 +3386,19 @@ stats_error_parsing:
                                        goto out;
                                }
                        }
-                       parse_logformat_string(logformat, curproxy, &curproxy->logformat, curproxy->mode);
+                       if (curproxy->logformat_string != default_http_log_format &&
+                           curproxy->logformat_string != default_tcp_log_format &&
+                           curproxy->logformat_string != clf_http_log_format)
+                               free(curproxy->logformat_string);
+                       curproxy->logformat_string = logformat;
                }
                else if (!strcmp(args[1], "tcplog")) {
-                       char *logformat;
                        /* generate a detailed TCP log */
-                       logformat = default_tcp_log_format;
-                       parse_logformat_string(logformat, curproxy, &curproxy->logformat, curproxy->mode);
+                       if (curproxy->logformat_string != default_http_log_format &&
+                           curproxy->logformat_string != default_tcp_log_format &&
+                           curproxy->logformat_string != clf_http_log_format)
+                               free(curproxy->logformat_string);
+                       curproxy->logformat_string = default_tcp_log_format;
                }
                else if (!strcmp(args[1], "tcpka")) {
                        /* enable TCP keep-alives on client and server sessions */
@@ -4639,7 +4647,8 @@ stats_error_parsing:
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
-               parse_logformat_string(args[1], curproxy, &curproxy->format_unique_id, PR_MODE_HTTP);
+               free(curproxy->uniqueid_format_string);
+               curproxy->uniqueid_format_string = strdup(args[1]);
        }
 
        else if (strcmp(args[0], "unique-id-header") == 0) {
@@ -4658,7 +4667,12 @@ stats_error_parsing:
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
-               parse_logformat_string(args[1], curproxy, &curproxy->logformat, curproxy->mode);
+
+               if (curproxy->logformat_string != default_http_log_format &&
+                   curproxy->logformat_string != default_tcp_log_format &&
+                   curproxy->logformat_string != clf_http_log_format)
+                       free(curproxy->logformat_string);
+               curproxy->logformat_string = strdup(args[1]);
        }
 
        else if (!strcmp(args[0], "log") && kwm == KWM_NO) {
@@ -6208,6 +6222,13 @@ out_uri_auth_compat:
                        }
                }
 
+               /* compile the log format */
+               if (curproxy->logformat_string)
+                       parse_logformat_string(curproxy->logformat_string, curproxy, &curproxy->logformat, curproxy->mode);
+
+               if (curproxy->uniqueid_format_string)
+                       parse_logformat_string(curproxy->uniqueid_format_string, curproxy, &curproxy->format_unique_id, PR_MODE_HTTP);
+
                /* first, we will invert the servers list order */
                newsrv = NULL;
                while (curproxy->srv) {
index 8d3e6e3764650521fd7c5b5d8af17a48ac56b56a..ff962c2748f88ef3614343ea48a22fd699c053a5 100644 (file)
@@ -831,6 +831,12 @@ void deinit(void)
                free(p->capture_name);
                free(p->monitor_uri);
                free(p->rdp_cookie_name);
+               if (p->logformat_string == default_http_log_format ||
+                   p->logformat_string == default_tcp_log_format ||
+                   p->logformat_string == clf_http_log_format)
+                       free(p->logformat_string);
+
+               free(p->uniqueid_format_string);
 
                for (i = 0; i < HTTP_ERR_SIZE; i++)
                        chunk_destroy(&p->errmsg[i]);
index bc5779ff3f759f4bcbbcede9ae6f732b9c16446d..3568251df7b81d25645651b7313d35766eb6cae1 100644 (file)
@@ -406,6 +406,13 @@ int proxy_cfg_ensure_no_http(struct proxy *curproxy)
                Warning("config : 'option httplog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n",
                        proxy_type_str(curproxy), curproxy->id);
        }
+       if (curproxy->logformat_string == default_http_log_format ||
+           curproxy->logformat_string == clf_http_log_format) {
+               curproxy->logformat_string = default_tcp_log_format;
+               Warning("config : 'option httplog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n",
+                       proxy_type_str(curproxy), curproxy->id);
+       }
+
        return 0;
 }