mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-24 15:49:14 -04:00
BUG/MEDIUM: h2: always consume any trailing data after end of output buffers
In case a stream tries to emit more data than advertised by the chunks or content-length headers, the extra data remains in the channel's output buffer until the channel's timeout expires. It can easily happen when sending malformed error files making use of a wrong content-length or having extra CRLFs after the empty chunk. It may also be possible to forge such a bad response using Lua. The H1 to H2 encoder must protect itself against this by marking the data presented to it as consumed if it decides to discard them, so that the sending stream doesn't wait for the timeout to trigger. The visible effect of this problem is a huge memory usage and a high concurrent connection count during benchmarks when using such bad data (a typical place where this easily happens). This fix must be backported to 1.8.
This commit is contained in:
parent
929b52d8a1
commit
35a62705df
1 changed files with 12 additions and 1 deletions
13
src/mux_h2.c
13
src/mux_h2.c
|
|
@ -3030,6 +3030,9 @@ static int h2s_frt_make_resp_headers(struct h2s *h2s, struct buffer *buf)
|
|||
* body or directly end in TRL2.
|
||||
*/
|
||||
if (es_now) {
|
||||
// trim any possibly pending data (eg: inconsistent content-length)
|
||||
bo_del(buf, buf->o);
|
||||
|
||||
h1m->state = HTTP_MSG_DONE;
|
||||
h2s->flags |= H2_SF_ES_SENT;
|
||||
if (h2s->st == H2_SS_OPEN)
|
||||
|
|
@ -3279,8 +3282,12 @@ static int h2s_frt_make_resp_data(struct h2s *h2s, struct buffer *buf)
|
|||
else
|
||||
h2c_stream_close(h2c, h2s);
|
||||
|
||||
if (!(h1m->flags & H1_MF_CHNK))
|
||||
if (!(h1m->flags & H1_MF_CHNK)) {
|
||||
// trim any possibly pending data (eg: inconsistent content-length)
|
||||
bo_del(buf, buf->o);
|
||||
|
||||
h1m->state = HTTP_MSG_DONE;
|
||||
}
|
||||
|
||||
h2s->flags |= H2_SF_ES_SENT;
|
||||
}
|
||||
|
|
@ -3329,6 +3336,10 @@ static int h2_snd_buf(struct conn_stream *cs, struct buffer *buf, int flags)
|
|||
}
|
||||
total += count;
|
||||
bo_del(buf, count);
|
||||
|
||||
// trim any possibly pending data (eg: extra CR-LF, ...)
|
||||
bo_del(buf, buf->o);
|
||||
|
||||
h2s->res.state = HTTP_MSG_DONE;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue