diff options
author | Igor Sysoev <igor@sysoev.ru> | 2018-01-11 09:49:36 +0300 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2018-01-11 09:49:36 +0300 |
commit | 2fa203f2da32449dec9886e01dee1a4d85ce1e90 (patch) | |
tree | 973ea8ba63c29fa89ef82ff1675b95b0d7753f69 /src/nxt_h1proto.c | |
parent | b09227fa5c5f4b509d9e57da67b0ee79780a9877 (diff) | |
download | unit-2fa203f2da32449dec9886e01dee1a4d85ce1e90.tar.gz unit-2fa203f2da32449dec9886e01dee1a4d85ce1e90.tar.bz2 |
HTTP: fixed large header buffers allocation and deallocation.
This closes #74 issue on GitHub.
Diffstat (limited to 'src/nxt_h1proto.c')
-rw-r--r-- | src/nxt_h1proto.c | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index 12be4172..35e66e4b 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -289,8 +289,8 @@ nxt_h1p_header_parse(nxt_task_t *task, void *obj, void *data) size = nxt_buf_mem_used_size(&in->mem); b->mem.free = nxt_cpymem(b->mem.pos, in->mem.pos, size); - in->next = b; - nxt_buf_chain_add(&h1p->buffers, in); + in->next = h1p->buffers; + h1p->buffers = in; c->read = b; } @@ -351,14 +351,17 @@ static void nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) { size_t size, rest_length; - nxt_buf_t *b; + nxt_buf_t *in, *b; nxt_conn_t *c; + nxt_h1proto_t *h1p; nxt_http_status_t status; + h1p = r->proto.h1; + nxt_debug(task, "h1p body read %O te:%d", - r->content_length_n, r->proto.h1->transfer_encoding); + r->content_length_n, h1p->transfer_encoding); - switch (r->proto.h1->transfer_encoding) { + switch (h1p->transfer_encoding) { case NXT_HTTP_TE_CHUNKED: status = NXT_HTTP_LENGTH_REQUIRED; @@ -396,9 +399,9 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) r->body = b; } - c = r->proto.h1->conn; + in = h1p->conn->read; - size = nxt_buf_mem_used_size(&c->read->mem); + size = nxt_buf_mem_used_size(&in->mem); if (size != 0) { if (size >= rest_length) { @@ -409,8 +412,8 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) rest_length -= size; } - b->mem.free = nxt_cpymem(b->mem.free, c->read->mem.pos, size); - c->read->mem.pos += size; + b->mem.free = nxt_cpymem(b->mem.free, in->mem.pos, size); + in->mem.pos += size; } nxt_debug(task, "h1p body rest: %O", rest_length); @@ -418,6 +421,10 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) r->rest_length = rest_length; if (rest_length != 0) { + in->next = h1p->buffers; + h1p->buffers = in; + + c = h1p->conn; c->read = b; c->read_state = &nxt_h1p_read_body_state; @@ -434,7 +441,7 @@ ready: error: - r->proto.h1->keepalive = 0; + h1p->keepalive = 0; nxt_http_request_error(task, r, status); } @@ -479,6 +486,7 @@ nxt_h1p_body_read(nxt_task_t *task, void *obj, void *data) nxt_conn_read(task->thread->engine, c); } else { + c->read = NULL; nxt_work_queue_add(&task->thread->engine->fast_work_queue, r->state->ready_handler, task, r, NULL); } @@ -866,21 +874,24 @@ nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c) in = c->read; - size = nxt_buf_mem_used_size(&in->mem); + if (in == NULL) { + /* A request with large body. */ + in = b; + c->read = in; - if (size == 0) { - if (b != NULL) { - in = b; - c->read = in; + b = in->next; + in->next = NULL; + } - for (b = b->next; b != NULL; b = next) { - next = b->next; - nxt_mp_free(c->mem_pool, b); - } + while (b != NULL) { + next = b->next; + nxt_mp_free(c->mem_pool, b); + b = next; + } - in->next = NULL; - } + size = nxt_buf_mem_used_size(&in->mem); + if (size == 0) { in->mem.pos = in->mem.start; in->mem.free = in->mem.start; @@ -896,14 +907,6 @@ nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c) } else { nxt_debug(task, "h1p pipelining"); - if (b != NULL) { - do { - next = b->next; - nxt_mp_free(c->mem_pool, b); - b = next; - } while (b != in); - } - nxt_memmove(in->mem.start, in->mem.pos, size); in->mem.pos = in->mem.start; |