Static: fixing request memory pool leakage in router.

When a static file larger than NXT_HTTP_STATIC_BUF_SIZE (128K) is served, two
buffers are allocated and chained; each retains the whole request memory pool.

Starting from 41331471eee7, the completion handler was called once for a linked
buffer chain, but the second buffer got lost.

This patch improves the completion handler's treatment of static buffers to
handle all linked buffers.
This commit is contained in:
Max Romanov
2020-12-23 11:01:36 +03:00
parent cac762ab7e
commit b7dba90062
2 changed files with 27 additions and 3 deletions

View File

@@ -61,6 +61,13 @@ had appeared in 1.19.0.
</para>
</change>
<change type="bugfix">
<para>
a memory leak occurring in the router process when serving a file larger than
128K; the bug had appeared in 1.13.0.
</para>
</change>
</changes>

View File

@@ -395,12 +395,15 @@ static void
nxt_http_static_buf_completion(nxt_task_t *task, void *obj, void *data)
{
ssize_t n, size;
nxt_buf_t *b, *fb;
nxt_buf_t *b, *fb, *next;
nxt_off_t rest;
nxt_http_request_t *r;
b = obj;
r = data;
complete_buf:
fb = r->out;
if (nxt_slow_path(fb == NULL || r->error)) {
@@ -424,6 +427,8 @@ nxt_http_static_buf_completion(nxt_task_t *task, void *obj, void *data)
goto clean;
}
next = b->next;
if (n == rest) {
nxt_file_close(task, fb->file);
r->out = NULL;
@@ -439,12 +444,24 @@ nxt_http_static_buf_completion(nxt_task_t *task, void *obj, void *data)
b->mem.free = b->mem.pos + n;
nxt_http_request_send(task, r, b);
if (next != NULL) {
b = next;
goto complete_buf;
}
return;
clean:
nxt_mp_free(r->mem_pool, b);
nxt_mp_release(r->mem_pool);
do {
next = b->next;
nxt_mp_free(r->mem_pool, b);
nxt_mp_release(r->mem_pool);
b = next;
} while (b != NULL);
if (fb != NULL) {
nxt_file_close(task, fb->file);