summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_h1proto.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2018-01-11 09:49:36 +0300
committerIgor Sysoev <igor@sysoev.ru>2018-01-11 09:49:36 +0300
commit2fa203f2da32449dec9886e01dee1a4d85ce1e90 (patch)
tree973ea8ba63c29fa89ef82ff1675b95b0d7753f69 /src/nxt_h1proto.c
parentb09227fa5c5f4b509d9e57da67b0ee79780a9877 (diff)
downloadunit-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.c61
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;