diff options
author | Max Romanov <max.romanov@nginx.com> | 2020-03-19 20:43:35 +0300 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2020-03-19 20:43:35 +0300 |
commit | c26fbbe53a1ce656e05d3e1e86d019c6173715ab (patch) | |
tree | 37b848447ef47dc42cdc5ee3ae09254d230ebedc | |
parent | 93207d4a8c462525cf2160d2099e44b86aa68b27 (diff) | |
download | unit-c26fbbe53a1ce656e05d3e1e86d019c6173715ab.tar.gz unit-c26fbbe53a1ce656e05d3e1e86d019c6173715ab.tar.bz2 |
Completing request header buffers to avoid memory leak.
Before this fix, only persistent connection request buffers were completed.
This issue was introduced in dc403927ab0b.
-rw-r--r-- | src/nxt_h1proto.c | 46 | ||||
-rw-r--r-- | src/nxt_h1proto_websocket.c | 2 | ||||
-rw-r--r-- | src/nxt_http.h | 3 |
3 files changed, 29 insertions, 22 deletions
diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index 35918bd8..19b84108 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -1364,17 +1364,19 @@ nxt_h1p_request_header_send(nxt_task_t *task, nxt_http_request_t *r, void -nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p) +nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_bool_t all) { - size_t size; - nxt_buf_t *b, *in, *next; - nxt_conn_t *c; + size_t size; + nxt_buf_t *b, *in, *next; + nxt_conn_t *c; + nxt_work_queue_t *wq; nxt_debug(task, "h1p complete buffers"); b = h1p->buffers; c = h1p->conn; in = c->read; + wq = &task->thread->engine->fast_work_queue; if (b != NULL) { if (in == NULL) { @@ -1390,8 +1392,7 @@ nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p) next = b->next; b->next = NULL; - nxt_work_queue_add(&task->thread->engine->fast_work_queue, - b->completion_handler, task, b, b->parent); + nxt_work_queue_add(wq, b->completion_handler, task, b, b->parent); b = next; } @@ -1403,9 +1404,9 @@ nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p) if (in != NULL) { size = nxt_buf_mem_used_size(&in->mem); - if (size == 0) { - nxt_work_queue_add(&task->thread->engine->fast_work_queue, - in->completion_handler, task, in, in->parent); + if (size == 0 || all) { + nxt_work_queue_add(wq, in->completion_handler, task, in, + in->parent); c->read = NULL; } @@ -1754,7 +1755,7 @@ nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c) nxt_conn_tcp_nodelay_on(task, c); } - nxt_h1p_complete_buffers(task, h1p); + nxt_h1p_complete_buffers(task, h1p, 0); in = c->read; @@ -1952,20 +1953,25 @@ nxt_h1p_shutdown(nxt_task_t *task, nxt_conn_t *c) h1p = c->socket.data; - if (nxt_slow_path(h1p != NULL && h1p->websocket_timer != NULL)) { - timer = &h1p->websocket_timer->timer; + if (h1p != NULL) { + nxt_h1p_complete_buffers(task, h1p, 1); - if (timer->handler != nxt_h1p_conn_ws_shutdown) { - timer->handler = nxt_h1p_conn_ws_shutdown; - nxt_timer_add(task->thread->engine, timer, 0); + if (nxt_slow_path(h1p->websocket_timer != NULL)) { + timer = &h1p->websocket_timer->timer; - } else { - nxt_debug(task, "h1p already scheduled ws shutdown"); - } + if (timer->handler != nxt_h1p_conn_ws_shutdown) { + timer->handler = nxt_h1p_conn_ws_shutdown; + nxt_timer_add(task->thread->engine, timer, 0); - } else { - nxt_h1p_closing(task, c); + } else { + nxt_debug(task, "h1p already scheduled ws shutdown"); + } + + return; + } } + + nxt_h1p_closing(task, c); } diff --git a/src/nxt_h1proto_websocket.c b/src/nxt_h1proto_websocket.c index c9ff899c..42a50a34 100644 --- a/src/nxt_h1proto_websocket.c +++ b/src/nxt_h1proto_websocket.c @@ -135,7 +135,7 @@ nxt_h1p_websocket_frame_start(nxt_task_t *task, nxt_http_request_t *r, c = h1p->conn; c->read = ws_frame; - nxt_h1p_complete_buffers(task, h1p); + nxt_h1p_complete_buffers(task, h1p, 0); in = c->read; c->read_state = &nxt_h1p_read_ws_frame_header_state; diff --git a/src/nxt_http.h b/src/nxt_http.h index 0e0694e5..36ce74c6 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -320,7 +320,8 @@ void nxt_h1p_websocket_first_frame_start(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *ws_frame); void nxt_h1p_websocket_frame_start(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *ws_frame); -void nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p); +void nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p, + nxt_bool_t all); nxt_msec_t nxt_h1p_conn_request_timer_value(nxt_conn_t *c, uintptr_t data); extern const nxt_conn_state_t nxt_h1p_idle_close_state; |