BUG/MEDIUM: h2: don't close after the first DATA frame on tunnelled responses

Tunnelled responses are those without a content-length nor a chunked
encoding. They are specially dealt with in the current code but the
behaviour is not correct. The fact that the chunk size is left to zero
with a state artificially set to CHUNK_SIZE validates the test on
whether or not to set the end of stream flag. Thus the first DATA
frame always carries the ES flag and subsequent ones remain blocked.

This patch fixes it in two ways :
  - update h1m->curr_len to the size of the current buffer so that it
    is properly subtracted later to find the real end ;
  - don't set the state to CHUNK_SIZE when there's no content-length
    and instead set it to CHUNK_SIZE only when there's chunking.

This fix needs to be backported to 1.8.
This commit is contained in:
Willy Tarreau 2017-12-14 10:55:21 +01:00
parent c4134ba8b0
commit 13e4e94dae

View File

@ -2938,7 +2938,7 @@ static int h2s_frt_make_resp_headers(struct h2s *h2s, struct buffer *buf)
goto end;
}
else
h1m->state = (h1m->flags & H1_MF_CLEN) ? HTTP_MSG_BODY : HTTP_MSG_CHUNK_SIZE;
h1m->state = (h1m->flags & H1_MF_CHNK) ? HTTP_MSG_CHUNK_SIZE : HTTP_MSG_BODY;
end:
//fprintf(stderr, "[%d] sent simple H2 response (sid=%d) = %d bytes (%d in, ep=%u, es=%s)\n", h2c->st0, h2s->id, outbuf.len, ret, h1m->err_pos, h1_msg_state_str(h1m->err_state));
@ -3004,6 +3004,7 @@ static int h2s_frt_make_resp_data(struct h2s *h2s, struct buffer *buf)
switch (h1m->flags & (H1_MF_CLEN|H1_MF_CHNK)) {
case 0: /* no content length, read till SHUTW */
size = buf->o;
h1m->curr_len = size;
break;
case H1_MF_CLEN: /* content-length: read only h2m->body_len */
size = buf->o;