]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http-htx: Store errorloc/errorfile messages in http replies
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 14 May 2020 15:31:52 +0000 (17:31 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 20 May 2020 16:27:13 +0000 (18:27 +0200)
During configuration parsing, error messages resulting of parsing of errorloc
and errorfile directives are now also stored as an http reply. So, for now,
these messages are stored as a buffer and as an http reply. To be able to
release all these http replies when haproxy is stopped, a global list is
used. We must do that because the same http reply may be referenced several
times by different proxies if it is defined in a default section.

include/types/http_htx.h
src/http_htx.c

index e6752c16b8d19562f41e0758d078100b0122b149..f1f468542941724e90e8a9289b576f5d03b73ca4 100644 (file)
@@ -66,6 +66,8 @@ struct http_reply {
                char          *http_errors;   /* The http-errors section to use (type = HTTP_REPLY_ERRFILES).
                                               * Should be resolved during post-check */
        } body;
+       struct list list;  /* next http_reply in the global list.
+                           * Only used for replies defined in a proxy section */
 };
 
 /* A custom HTTP error message load from a row file and converted in HTX. The
index 7c90a96081bf53718de01b9d549befa42d1bc4ea..b830c736e61bc6d7ed7b99a5b2fc1ff1b328173b 100644 (file)
@@ -33,6 +33,7 @@ struct http_reply http_err_replies[HTTP_ERR_SIZE];
 
 struct eb_root http_error_messages = EB_ROOT;
 struct list http_errors_list = LIST_HEAD_INIT(http_errors_list);
+struct list http_replies_list = LIST_HEAD_INIT(http_replies_list);
 
 /* The declaration of an errorfiles/errorfile directives. Used during config
  * parsing only. */
@@ -42,6 +43,7 @@ struct conf_errors {
                struct {
                        int status;                 /* the status code associated to this error */
                        struct buffer *msg;         /* the HTX error message */
+                       struct http_reply *reply;   /* the http reply for the errorfile */
                } errorfile;                        /* describe an "errorfile" directive */
                struct {
                        char *name;                 /* the http-errors section name */
@@ -1028,6 +1030,7 @@ end:
 static void http_htx_deinit(void)
 {
        struct http_errors *http_errs, *http_errsb;
+       struct http_reply *http_rep, *http_repb;
        struct ebpt_node *node, *next;
        struct http_error_msg *http_errmsg;
        int rc;
@@ -1051,6 +1054,11 @@ static void http_htx_deinit(void)
                LIST_DEL(&http_errs->list);
                free(http_errs);
        }
+
+       list_for_each_entry_safe(http_rep, http_repb, &http_replies_list, list) {
+               LIST_DEL(&http_rep->list);
+               release_http_reply(http_rep);
+       }
 }
 
 REGISTER_CONFIG_POSTPARSER("http_htx", http_htx_init);
@@ -1647,6 +1655,7 @@ static int proxy_parse_errorloc(char **args, int section, struct proxy *curpx,
                                  char **errmsg)
 {
        struct conf_errors *conf_err;
+       struct http_reply *reply;
        struct buffer *msg;
        int errloc, status;
        int ret = 0;
@@ -1671,15 +1680,31 @@ static int proxy_parse_errorloc(char **args, int section, struct proxy *curpx,
                goto out;
        }
 
+       reply = calloc(1, sizeof(*reply));
+       if (!reply) {
+               memprintf(errmsg, "%s : out of memory.", args[0]);
+               ret = -1;
+               goto out;
+       }
+       reply->type = HTTP_REPLY_ERRMSG;
+       reply->status = status;
+       reply->ctype = NULL;
+       LIST_INIT(&reply->hdrs);
+       reply->body.errmsg = msg;
+       LIST_ADDQ(&http_replies_list, &reply->list);
+
        conf_err = calloc(1, sizeof(*conf_err));
        if (!conf_err) {
                memprintf(errmsg, "%s : out of memory.", args[0]);
+               free(reply);
                ret = -1;
                goto out;
        }
        conf_err->type = 1;
        conf_err->info.errorfile.status = status;
        conf_err->info.errorfile.msg = msg;
+       conf_err->info.errorfile.reply = reply;
+
        conf_err->file = strdup(file);
        conf_err->line = line;
        LIST_ADDQ(&curpx->conf.errors, &conf_err->list);
@@ -1695,6 +1720,7 @@ static int proxy_parse_errorfile(char **args, int section, struct proxy *curpx,
                                 char **errmsg)
 {
        struct conf_errors *conf_err;
+       struct http_reply *reply;
        struct buffer *msg;
        int status;
        int ret = 0;
@@ -1718,15 +1744,30 @@ static int proxy_parse_errorfile(char **args, int section, struct proxy *curpx,
                goto out;
        }
 
+       reply = calloc(1, sizeof(*reply));
+       if (!reply) {
+               memprintf(errmsg, "%s : out of memory.", args[0]);
+               ret = -1;
+               goto out;
+       }
+       reply->type = HTTP_REPLY_ERRMSG;
+       reply->status = status;
+       reply->ctype = NULL;
+       LIST_INIT(&reply->hdrs);
+       reply->body.errmsg = msg;
+       LIST_ADDQ(&http_replies_list, &reply->list);
+
        conf_err = calloc(1, sizeof(*conf_err));
        if (!conf_err) {
                memprintf(errmsg, "%s : out of memory.", args[0]);
+               free(reply);
                ret = -1;
                goto out;
        }
        conf_err->type = 1;
        conf_err->info.errorfile.status = status;
        conf_err->info.errorfile.msg = msg;
+       conf_err->info.errorfile.reply = reply;
        conf_err->file = strdup(file);
        conf_err->line = line;
        LIST_ADDQ(&curpx->conf.errors, &conf_err->list);