summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMax Romanov <max.romanov@nginx.com>2020-03-19 20:43:35 +0300
committerMax Romanov <max.romanov@nginx.com>2020-03-19 20:43:35 +0300
commitc26fbbe53a1ce656e05d3e1e86d019c6173715ab (patch)
tree37b848447ef47dc42cdc5ee3ae09254d230ebedc
parent93207d4a8c462525cf2160d2099e44b86aa68b27 (diff)
downloadunit-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.c46
-rw-r--r--src/nxt_h1proto_websocket.c2
-rw-r--r--src/nxt_http.h3
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;