[core] fix handling chunked response from backend (fixes #3044)

(thx flynn)

When the backend sends Transfer-Encoding: chunked (which is HTTP/1.1,
not HTTP/1.0) and the client is HTTP/1.1, then lighttpd will transfer
the chunked encoding as it is sent from the backend without excess data
copying involved in decoding and then re-encoding. The bug is that if
the first data chunk (or chunks) is partially received at the same time
as the response headers, then the chunked encoding got corrupted.

x-ref:
  "Socket errors after update to version 1.4.56"
  https://redmine.lighttpd.net/issues/3044
This commit is contained in:
Glenn Strauss 2020-12-09 02:11:21 -05:00
parent adf7aea0e1
commit d15e2286f2
1 changed files with 14 additions and 2 deletions

View File

@ -932,11 +932,23 @@ http_response_write_prepare(request_st * const r)
/* create initial Transfer-Encoding: chunked segment */
buffer * const b =
chunkqueue_prepend_buffer_open(&r->write_queue);
if (r->resp_decode_chunked
&& 0 != r->gw_dechunk->gw_chunked) {
/*(reconstitute initial partially-decoded chunk)*/
off_t gw_chunked = r->gw_dechunk->gw_chunked;
if (gw_chunked > 2)
qlen += gw_chunked - 2;
else if (1 == gw_chunked)
chunkqueue_append_mem(&r->write_queue,
CONST_STR_LEN("\r"));
}
else {
chunkqueue_append_mem(&r->write_queue,
CONST_STR_LEN("\r\n"));
}
buffer_append_uint_hex(b, (uintmax_t)qlen);
buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
chunkqueue_prepend_buffer_commit(&r->write_queue);
chunkqueue_append_mem(&r->write_queue,
CONST_STR_LEN("\r\n"));
}
http_header_response_append(r, HTTP_HEADER_TRANSFER_ENCODING,
CONST_STR_LEN("Transfer-Encoding"),