BUG/MEDIUM: http-ana: Don't loop trying to generate a malformed 500 response

When HAProxy generates a 500 response, if the formatting failed, for instance
because the message is larger than a buffer, it retries to format it in loop. To
fix the bug, we must stop trying to send a response if it is a non-rewritable
response (TX_CONST_REPLY flag is set on the HTTP transaction).

Because this part is not trivial, some comments have been added.

No backport is needed.
This commit is contained in:
Christopher Faulet 2020-06-25 16:04:50 +02:00
parent bfa3e81a7b
commit 40e6b550ce

View File

@ -4548,7 +4548,8 @@ static void http_end_response(struct stream *s)
* function forwards all pending incoming data. If <final> is set to 0, nothing
* more is performed. It is used for 1xx informational messages. Otherwise, the
* transaction is terminated and the request is emptied. On success 1 is
* returned. If an error occurred, 0 is returned.
* returned. If an error occurred, 0 is returned. If it fails, this function
* only exits. It is the caller responsibility to do the cleanup.
*/
int http_forward_proxy_resp(struct stream *s, int final)
{
@ -4600,10 +4601,14 @@ void http_reply_and_close(struct stream *s, short status, struct http_reply *msg
if (http_reply_message(s, msg) == -1) {
/* On error, return a 500 error message, but don't rewrite it if
* it is already an internal error.
* it is already an internal error. If it was already a "const"
* 500 error, just fail.
*/
if (s->txn->status == 500)
if (s->txn->status == 500) {
if (s->txn->flags & TX_CONST_REPLY)
goto end;
s->txn->flags |= TX_CONST_REPLY;
}
s->txn->status = 500;
s->txn->http_reply = NULL;
return http_reply_and_close(s, s->txn->status, http_error_message(s));
@ -4636,9 +4641,10 @@ struct http_reply *http_error_message(struct stream *s)
return &http_err_replies[msgnum];
}
/* Produces an HTX message from an http reply. Depending on the http reply type, a,
* errorfile, an raw file or a log-format string is used. On success, it returns
* 0. If an error occurs -1 is returned.
/* Produces an HTX message from an http reply. Depending on the http reply type,
* a, errorfile, an raw file or a log-format string is used. On success, it
* returns 0. If an error occurs -1 is returned. If it fails, this function only
* exits. It is the caller responsibility to do the cleanup.
*/
int http_reply_to_htx(struct stream *s, struct htx *htx, struct http_reply *reply)
{
@ -4750,7 +4756,11 @@ int http_reply_to_htx(struct stream *s, struct htx *htx, struct http_reply *repl
}
/* Send an http reply to the client. On success, it returns 0. If an error
* occurs -1 is returned.
* occurs -1 is returned and the response channel is truncated, removing this
* way the faulty reply. This function may fail when the reply is formatted
* (http_reply_to_htx) or when the reply is forwarded
* (http_forward_proxy_resp). On the last case, it is because a
* http-after-response rule fails.
*/
int http_reply_message(struct stream *s, struct http_reply *reply)
{