MEDIUM: http-htx/proxy: Use a global and centralized storage for HTTP error messages
All custom HTTP errors are now stored in a global tree. Proxies use a references
on these messages. The key used for errorfile directives is the file name as
specified in the configuration. For errorloc directives, a key is created using
the redirect code and the url. This means that the same custom error message is
now stored only once. It may be used in several proxies or for several status
code, it is only parsed and stored once.
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index b42fe53..9177181 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -262,8 +262,7 @@
}
/* initialize error relocations */
- for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
- chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
+ memcpy(&curproxy->errmsg, &defproxy.errmsg, sizeof(defproxy.errmsg));
if (curproxy->cap & PR_CAP_FE) {
curproxy->maxconn = defproxy.maxconn;
@@ -503,8 +502,7 @@
free(defproxy.conf.logformat_sd_string);
free(defproxy.conf.lfsd_file);
- for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
- chunk_destroy(&defproxy.errmsg[rc]);
+ memset(&defproxy.errmsg, 0, sizeof(defproxy.errmsg));
/* we cannot free uri_auth because it might already be used */
init_default_instance();
@@ -3810,8 +3808,8 @@
else if (!strcmp(args[0], "errorloc") ||
!strcmp(args[0], "errorloc302") ||
!strcmp(args[0], "errorloc303")) { /* error location */
- struct buffer chk;
- int errloc, status, rc;
+ struct buffer *msg;
+ int errloc, status;
if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
err_code |= ERR_WARN;
@@ -3824,39 +3822,38 @@
status = atol(args[1]);
errloc = (!strcmp(args[0], "errorloc303") ? 303 : 302);
- rc = http_parse_errorloc(errloc, status, args[2], &chk, &errmsg);
- if (rc == -1) {
+ msg = http_parse_errorloc(errloc, status, args[2], &errmsg);
+ if (!msg) {
ha_alert("parsing [%s:%d] : %s: %s\n", file, linenum, args[0], errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
-
- chunk_destroy(&curproxy->errmsg[rc]);
- curproxy->errmsg[rc] = chk;
+ rc = http_get_status_idx(status);
+ curproxy->errmsg[rc] = msg;
}
else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
- struct buffer chk;
- int status, rc;
+ struct buffer *msg;
+ int status;
if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
err_code |= ERR_WARN;
if (*(args[1]) == 0 || *(args[2]) == 0) {
- ha_alert("parsing [%s:%d] : <%s> expects <status_code> and <file> as arguments.\n", file, linenum, args[0]);
+ ha_alert("parsing [%s:%d] : %s: expects <status_code> and <file> as arguments.\n",
+ file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
status = atol(args[1]);
- rc = http_parse_errorfile(status, args[2], &chk, &errmsg);
- if (rc == -1) {
+ msg = http_parse_errorfile(status, args[2], &errmsg);
+ if (!msg) {
ha_alert("parsing [%s:%d] : %s: %s\n", file, linenum, args[0], errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
-
- chunk_destroy(&curproxy->errmsg[rc]);
- curproxy->errmsg[rc] = chk;
+ rc = http_get_status_idx(status);
+ curproxy->errmsg[rc] = msg;
}
else {
struct cfg_kw_list *kwl;