mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-29 06:40:59 +01:00
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:
parent
bfa3e81a7b
commit
40e6b550ce
@ -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
|
* 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
|
* more is performed. It is used for 1xx informational messages. Otherwise, the
|
||||||
* transaction is terminated and the request is emptied. On success 1 is
|
* 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)
|
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) {
|
if (http_reply_message(s, msg) == -1) {
|
||||||
/* On error, return a 500 error message, but don't rewrite it if
|
/* 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->flags |= TX_CONST_REPLY;
|
||||||
|
}
|
||||||
s->txn->status = 500;
|
s->txn->status = 500;
|
||||||
s->txn->http_reply = NULL;
|
s->txn->http_reply = NULL;
|
||||||
return http_reply_and_close(s, s->txn->status, http_error_message(s));
|
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];
|
return &http_err_replies[msgnum];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Produces an HTX message from an http reply. Depending on the http reply type, a,
|
/* Produces an HTX message from an http reply. Depending on the http reply type,
|
||||||
* errorfile, an raw file or a log-format string is used. On success, it returns
|
* a, errorfile, an raw file or a log-format string is used. On success, it
|
||||||
* 0. If an error occurs -1 is returned.
|
* 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)
|
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
|
/* 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)
|
int http_reply_message(struct stream *s, struct http_reply *reply)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user