diff --git a/include/proto/http_htx.h b/include/proto/http_htx.h index 8bf1b99db..0cec9db58 100644 --- a/include/proto/http_htx.h +++ b/include/proto/http_htx.h @@ -50,6 +50,8 @@ 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); int http_load_errorfile(const char *file, struct buffer *buf, char **errmsg); +int http_load_errormsg(const struct ist msg, struct buffer *buf, char **errmsg); int http_parse_errorfile(int status, const char *file, struct buffer *buf, char **errmsg); +int http_parse_errorloc(int errloc, int status, const char *url, struct buffer *buf, char **errmsg); #endif /* _PROTO_HTTP_HTX_H */ diff --git a/src/http_htx.c b/src/http_htx.c index fbe250227..2b368a4ec 100644 --- a/src/http_htx.c +++ b/src/http_htx.c @@ -890,6 +890,26 @@ int http_load_errorfile(const char *file, struct buffer *buf, char **errmsg) return ret; } +/* Convert the raw http message into an HTX message. On success, the + * result is stored in and 1 is returned. On error, 0 is returned and an + * error message is written into the buffer. It is this function + * responsibility to allocate and to release it if an error occurred. + */ +int http_load_errormsg(const struct ist msg, struct buffer *buf, char **errmsg) +{ + int ret = 0; + + /* Convert the error file into an HTX message */ + if (!http_str_to_htx(buf, msg)) { + memprintf(errmsg, "unable to convert message in HTX."); + goto out; + } + ret = 1; + + out: + return ret; +} + /* This function parses the raw HTTP error file for the status code * . On success, it returns the HTTP_ERR_* value corresponding to the @@ -913,6 +933,46 @@ int http_parse_errorfile(int status, const char *file, struct buffer *buf, char return ret; } +/* This function creates HTX error message corresponding to a redirect message + * for the status code . is used as location url for the + * redirect. is used to know if it is a 302 or a 303 redirect. On + * success, it returns the HTTP_ERR_* value corresponding to the specified + * status code and it allocated and fills the buffer with the HTX + * message. On error, it returns -1 and nothing is allocated. + */ +int http_parse_errorloc(int errloc, int status, const char *url, struct buffer *buf, char **errmsg) +{ + const char *msg; + char *err = NULL; + int rc, errlen; + int ret = -1; + + for (rc = 0; rc < HTTP_ERR_SIZE; rc++) { + if (http_err_codes[rc] == status) { + /* Create the error message */ + msg = (errloc == 302 ? HTTP_302 : HTTP_303); + errlen = strlen(msg) + strlen(url) + 5; + err = malloc(errlen); + if (!err) { + memprintf(errmsg, "out of memory."); + goto out; + } + errlen = snprintf(err, errlen, "%s%s\r\n\r\n", msg, url); + + /* Load it */ + if (http_load_errormsg(ist2(err, errlen), buf, errmsg)) + ret = rc; + break; + } + } + + if (rc >= HTTP_ERR_SIZE) + memprintf(errmsg, "status code '%d' not handled.", status); +out: + free(err); + return ret; +} + /************************************************************************/ /* HTX sample fetches */ /************************************************************************/