mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 22:31:28 +02:00
BUG/MINOR: http-ana: Don't overwrite outgoing data when an error is reported
When an error is returned to a client, the right message is injected into the response buffer. It is performed by http_server_error() or http_replay_and_close(). Both ignore any data already present into the channel's buffer. While it is legitimate to remove all input data, it is important to not remove any outgoing data. So now, we try to append the error message to the response buffer, only removing input data. We rely on the channel_htx_copy_msg() function to do so. So this patch depends on the following two commits: * MINOR: htx: Add a function to append an HTX message to another one * MINOR: htx/channel: Add a function to copy an HTX message in a channel's buffer This patch must be backported as far as 1.9. However, above patches must be backported first.
This commit is contained in:
parent
7651362e52
commit
637259e044
@ -4547,6 +4547,7 @@ void http_server_error(struct stream *s, struct stream_interface *si, int err,
|
|||||||
channel_abort(si_oc(si));
|
channel_abort(si_oc(si));
|
||||||
channel_auto_close(si_oc(si));
|
channel_auto_close(si_oc(si));
|
||||||
channel_htx_erase(si_oc(si), htxbuf(&(si_oc(si))->buf));
|
channel_htx_erase(si_oc(si), htxbuf(&(si_oc(si))->buf));
|
||||||
|
channel_htx_truncate(si_ic(si), htxbuf(&(si_ic(si))->buf));
|
||||||
channel_auto_close(si_ic(si));
|
channel_auto_close(si_ic(si));
|
||||||
channel_auto_read(si_ic(si));
|
channel_auto_read(si_ic(si));
|
||||||
|
|
||||||
@ -4555,14 +4556,16 @@ void http_server_error(struct stream *s, struct stream_interface *si, int err,
|
|||||||
if (msg && !b_is_null(msg)) {
|
if (msg && !b_is_null(msg)) {
|
||||||
struct channel *chn = si_ic(si);
|
struct channel *chn = si_ic(si);
|
||||||
struct htx *htx;
|
struct htx *htx;
|
||||||
|
size_t data;
|
||||||
|
|
||||||
FLT_STRM_CB(s, flt_http_reply(s, s->txn->status, msg));
|
FLT_STRM_CB(s, flt_http_reply(s, s->txn->status, msg));
|
||||||
chn->buf.data = msg->data;
|
|
||||||
memcpy(chn->buf.area, msg->area, msg->data);
|
|
||||||
htx = htx_from_buf(&chn->buf);
|
htx = htx_from_buf(&chn->buf);
|
||||||
|
if (channel_htx_copy_msg(chn, htx, msg)) {
|
||||||
htx->flags |= HTX_FL_PROXY_RESP;
|
htx->flags |= HTX_FL_PROXY_RESP;
|
||||||
c_adv(chn, htx->data);
|
data = htx->data - co_data(chn);
|
||||||
chn->total += htx->data;
|
c_adv(chn, data);
|
||||||
|
chn->total += data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!(s->flags & SF_ERR_MASK))
|
if (!(s->flags & SF_ERR_MASK))
|
||||||
s->flags |= err;
|
s->flags |= err;
|
||||||
@ -4582,18 +4585,19 @@ void http_reply_and_close(struct stream *s, short status, struct buffer *msg)
|
|||||||
|
|
||||||
/* <msg> is an HTX structure. So we copy it in the response's
|
/* <msg> is an HTX structure. So we copy it in the response's
|
||||||
* channel */
|
* channel */
|
||||||
/* FIXME: It is a problem for now if there is some outgoing data */
|
|
||||||
if (msg && !b_is_null(msg)) {
|
if (msg && !b_is_null(msg)) {
|
||||||
struct channel *chn = &s->res;
|
struct channel *chn = &s->res;
|
||||||
struct htx *htx;
|
struct htx *htx;
|
||||||
|
size_t data;
|
||||||
|
|
||||||
FLT_STRM_CB(s, flt_http_reply(s, s->txn->status, msg));
|
FLT_STRM_CB(s, flt_http_reply(s, s->txn->status, msg));
|
||||||
chn->buf.data = msg->data;
|
|
||||||
memcpy(chn->buf.area, msg->area, msg->data);
|
|
||||||
htx = htx_from_buf(&chn->buf);
|
htx = htx_from_buf(&chn->buf);
|
||||||
|
if (channel_htx_copy_msg(chn, htx, msg)) {
|
||||||
htx->flags |= HTX_FL_PROXY_RESP;
|
htx->flags |= HTX_FL_PROXY_RESP;
|
||||||
c_adv(chn, htx->data);
|
data = htx->data - co_data(chn);
|
||||||
chn->total += htx->data;
|
c_adv(chn, data);
|
||||||
|
chn->total += data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->res.wex = tick_add_ifset(now_ms, s->res.wto);
|
s->res.wex = tick_add_ifset(now_ms, s->res.wto);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user