diff --git a/include/proto/http_htx.h b/include/proto/http_htx.h index 40e608a93..4e9c7c861 100644 --- a/include/proto/http_htx.h +++ b/include/proto/http_htx.h @@ -61,6 +61,7 @@ unsigned int http_get_htx_fhdr(const struct htx *htx, const struct ist hdr, int http_str_to_htx(struct buffer *buf, struct ist raw); void release_http_reply(struct http_reply *http_reply); +int http_check_http_reply(struct http_reply *reply, struct proxy*px, char **errmsg); struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struct proxy *px, int default_status, char **errmsg); diff --git a/src/http_act.c b/src/http_act.c index d15030378..b7a6603c9 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -1939,42 +1939,18 @@ static enum act_return http_action_return(struct act_rule *rule, struct proxy *p goto leave; } -/* Check an "http-request return" action when an http-errors section is referenced. - * - * The function returns 1 in success case, otherwise, it returns 0 and err is - * filled. +/* Check an "http-request return" action. The function returns 1 in success + * case, otherwise, it returns 0 and err is filled. */ static int check_http_return_action(struct act_rule *rule, struct proxy *px, char **err) { struct http_reply *reply = rule->arg.http_reply; - struct http_errors *http_errs; - int ret = 1; - if (reply->type != HTTP_REPLY_ERRFILES) - goto end; - - list_for_each_entry(http_errs, &http_errors_list, list) { - if (strcmp(http_errs->id, reply->body.http_errors) == 0) { - reply->type = HTTP_REPLY_ERRMSG; - free(reply->body.http_errors); - reply->body.errmsg = http_errs->errmsg[http_get_status_idx(reply->status)]; - if (!reply->body.errmsg) - ha_warning("Proxy '%s': status '%d' referenced by http return rule " - "not declared in http-errors section '%s'.\n", - px->id, reply->status, http_errs->id); - break; - } - } - - if (&http_errs->list == &http_errors_list) { - memprintf(err, "unknown http-errors section '%s' referenced by http return rule", - reply->body.http_errors); + if (!http_check_http_reply(reply, px, err)) { release_http_return(rule); - ret = 0; + return 0; } - - end: - return ret; + return 1; } /* Parse a "return" action. It returns ACT_RET_PRS_OK on success, diff --git a/src/http_htx.c b/src/http_htx.c index 3015320ec..d98b2b994 100644 --- a/src/http_htx.c +++ b/src/http_htx.c @@ -1241,6 +1241,46 @@ out: return buf; } +/* Check an "http reply" and, for replies referencing an http-errors section, + * try to find the right section and the right error message in this section. If + * found, the reply is updated. If the http-errors section exists but the error + * message is not found, no error message is set to fallback on the default + * ones. Otherwise (unknown section) an error is returned. + * + * The function returns 1 in success case, otherwise, it returns 0 and errmsg is + * filled. + */ +int http_check_http_reply(struct http_reply *reply, struct proxy *px, char **errmsg) +{ + struct http_errors *http_errs; + int ret = 1; + + if (reply->type != HTTP_REPLY_ERRFILES) + goto end; + + list_for_each_entry(http_errs, &http_errors_list, list) { + if (strcmp(http_errs->id, reply->body.http_errors) == 0) { + reply->type = HTTP_REPLY_ERRMSG; + free(reply->body.http_errors); + reply->body.errmsg = http_errs->errmsg[http_get_status_idx(reply->status)]; + if (!reply->body.errmsg) + ha_warning("Proxy '%s': status '%d' referenced by an http reply " + "not declared in http-errors section '%s'.\n", + px->id, reply->status, http_errs->id); + break; + } + } + + if (&http_errs->list == &http_errors_list) { + memprintf(errmsg, "unknown http-errors section '%s' referenced by an http reply ", + reply->body.http_errors); + ret = 0; + } + + end: + return ret; +} + /* Parse an "http reply". It returns the reply on success or NULL on error. This * function creates one of the following http replies : *