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:
@@ -61,6 +61,13 @@ had appeared in 1.19.0.
|
|||||||
</para>
|
</para>
|
||||||
</change>
|
</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>
|
</changes>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -395,12 +395,15 @@ static void
|
|||||||
nxt_http_static_buf_completion(nxt_task_t *task, void *obj, void *data)
|
nxt_http_static_buf_completion(nxt_task_t *task, void *obj, void *data)
|
||||||
{
|
{
|
||||||
ssize_t n, size;
|
ssize_t n, size;
|
||||||
nxt_buf_t *b, *fb;
|
nxt_buf_t *b, *fb, *next;
|
||||||
nxt_off_t rest;
|
nxt_off_t rest;
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
|
|
||||||
b = obj;
|
b = obj;
|
||||||
r = data;
|
r = data;
|
||||||
|
|
||||||
|
complete_buf:
|
||||||
|
|
||||||
fb = r->out;
|
fb = r->out;
|
||||||
|
|
||||||
if (nxt_slow_path(fb == NULL || r->error)) {
|
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;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next = b->next;
|
||||||
|
|
||||||
if (n == rest) {
|
if (n == rest) {
|
||||||
nxt_file_close(task, fb->file);
|
nxt_file_close(task, fb->file);
|
||||||
r->out = NULL;
|
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;
|
b->mem.free = b->mem.pos + n;
|
||||||
|
|
||||||
nxt_http_request_send(task, r, b);
|
nxt_http_request_send(task, r, b);
|
||||||
|
|
||||||
|
if (next != NULL) {
|
||||||
|
b = next;
|
||||||
|
goto complete_buf;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
||||||
nxt_mp_free(r->mem_pool, b);
|
do {
|
||||||
nxt_mp_release(r->mem_pool);
|
next = b->next;
|
||||||
|
|
||||||
|
nxt_mp_free(r->mem_pool, b);
|
||||||
|
nxt_mp_release(r->mem_pool);
|
||||||
|
|
||||||
|
b = next;
|
||||||
|
} while (b != NULL);
|
||||||
|
|
||||||
if (fb != NULL) {
|
if (fb != NULL) {
|
||||||
nxt_file_close(task, fb->file);
|
nxt_file_close(task, fb->file);
|
||||||
|
|||||||
Reference in New Issue
Block a user