diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2020-12-15 00:32:24 -0500 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2020-12-16 02:00:17 -0500 |
commit | 903024d711187dc65a61c60d77d9c5539671ed83 (patch) | |
tree | f912c99b467b152a905c9a52ab9b977524b9efff /src/http_chunk.c | |
parent | e9309ae6e6b5aac1725b7794bc776f270a01f90f (diff) | |
download | lighttpd-git-903024d711187dc65a61c60d77d9c5539671ed83.tar.gz |
[core] track Content-Length from backend (fixes #3046)
track Content-Length from backend in r->resp_body_scratchpad
x-ref:
"Failure on second request in http proxy backend"
https://redmine.lighttpd.net/issues/3046
Diffstat (limited to 'src/http_chunk.c')
-rw-r--r-- | src/http_chunk.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/http_chunk.c b/src/http_chunk.c index 5abb06fb..3bebff2f 100644 --- a/src/http_chunk.c +++ b/src/http_chunk.c @@ -483,8 +483,26 @@ int http_chunk_decode_append_buffer(request_st * const r, buffer * const mem) /*(called by funcs receiving data from backends, which might be chunked)*/ /*(separate from http_chunk_append_buffer() called by numerous others)*/ - if (!r->resp_decode_chunked) + if (!r->resp_decode_chunked) { + if (r->resp_body_scratchpad > 0) { + off_t len = (off_t)buffer_string_length(mem); + r->resp_body_scratchpad -= len; + if (r->resp_body_scratchpad <= 0) { + r->resp_body_finished = 1; + if (r->resp_body_scratchpad < 0) { + /*(silently truncate if data exceeds Content-Length)*/ + len += r->resp_body_scratchpad; + r->resp_body_scratchpad = 0; + buffer_string_set_length(mem, (uint32_t)len); + } + } + } + else if (0 == r->resp_body_scratchpad) { + /*(silently truncate if data exceeds Content-Length)*/ + return 0; + } return http_chunk_append_buffer(r, mem); + } /* might avoid copy by transferring buffer if buffer is all data that is * part of large chunked block, but choosing to *not* expand that out here*/ @@ -508,12 +526,28 @@ int http_chunk_decode_append_buffer(request_st * const r, buffer * const mem) return 0; } -int http_chunk_decode_append_mem(request_st * const r, const char * const mem, const size_t len) +int http_chunk_decode_append_mem(request_st * const r, const char * const mem, size_t len) { /*(called by funcs receiving data from backends, which might be chunked)*/ /*(separate from http_chunk_append_mem() called by numerous others)*/ - if (!r->resp_decode_chunked) + if (!r->resp_decode_chunked) { + if (r->resp_body_scratchpad > 0) { + r->resp_body_scratchpad -= (off_t)len; + if (r->resp_body_scratchpad <= 0) { + r->resp_body_finished = 1; + if (r->resp_body_scratchpad < 0) { + /*(silently truncate if data exceeds Content-Length)*/ + len = (size_t)(r->resp_body_scratchpad + (off_t)len); + r->resp_body_scratchpad = 0; + } + } + } + else if (0 == r->resp_body_scratchpad) { + /*(silently truncate if data exceeds Content-Length)*/ + return 0; + } return http_chunk_append_mem(r, mem, len); + } if (0 != http_chunk_decode_append_data(r, mem, (off_t)len)) return -1; |