aboutsummaryrefslogtreecommitdiff
path: root/src/http/ngx_http_request_body.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-10-27 08:53:49 +0000
committerIgor Sysoev <igor@sysoev.ru>2003-10-27 08:53:49 +0000
commit10fc9ef77503ec4db5f5006557aeffc1939043ca (patch)
tree48dd22fcf5c6defd2960156f24a8b07757a7c6da /src/http/ngx_http_request_body.c
parent6414b96ebc50f42bf878aa84839921ab0aa9f4df (diff)
downloadnginx-10fc9ef77503ec4db5f5006557aeffc1939043ca.tar.gz
nginx-10fc9ef77503ec4db5f5006557aeffc1939043ca.zip
nginx-0.0.1-2003-10-27-11:53:49 import
Diffstat (limited to 'src/http/ngx_http_request_body.c')
-rw-r--r--src/http/ngx_http_request_body.c248
1 files changed, 104 insertions, 144 deletions
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index b95406698..c079a4615 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -1,196 +1,156 @@
#include <ngx_config.h>
#include <ngx_core.h>
+#include <ngx_event.h>
#include <ngx_http.h>
-int ngx_http_init_client_request_body(ngx_http_request_t *r, int size)
-{
- int header_in_part, len;
- ngx_hunk_t *h;
- ngx_http_request_body_t *rb;
-
- ngx_test_null(rb, ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)),
- NGX_HTTP_INTERNAL_SERVER_ERROR);
-
- header_in_part = r->header_in->end - r->header_in->pos;
-
- if (header_in_part) {
- rb->header_in_pos = r->header_in->pos;
- }
-
- if (header_in_part > r->headers_in.content_length_n) {
- header_in_part = r->headers_in.content_length_n;
+static void ngx_http_read_client_request_body_handler(ngx_event_t *rev);
- } else {
- len = r->headers_in.content_length_n - header_in_part;
- if (len > size) {
- len = size;
-
- } else if (len > NGX_PAGE_SIZE) {
- len = ((len + NGX_PAGE_SIZE - 1) / NGX_PAGE_SIZE) * NGX_PAGE_SIZE;
- }
-
- if (len) {
- ngx_test_null(rb->hunk, ngx_create_temp_hunk(r->pool, len, 0, 0),
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- }
- }
- r->request_body = rb;
-
- return NGX_OK;
-}
-
-
-int ngx_http_read_client_request_body(ngx_http_request_t *r)
+int ngx_http_read_client_request_body(ngx_http_request_t *r,
+ int request_buffer_size)
{
- int size, n, rc;
- ngx_chain_t *entry;
- ngx_http_request_body_t *rb;
-
- rb = r->request_body;
+ ssize_t size;
+ ngx_hunk_t *h;
+ ngx_chain_t *cl;
- do {
- if (r->header_in->last < r->header_in->end) {
- rb->chain[0].hunk = r->header_in;
+ size = r->header_in->last - r->header_in->pos;
- if (rb->hunk) {
- rb->chain[0].next = &rb->chain[1];
- rb->chain[1].hunk = rb->hunk;
- rb->chain[1].next = NULL;
+ if (size) {
+ ngx_test_null(h, ngx_calloc_hunk(r->pool),
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
- } else {
- rb->chain[0].next = NULL;
- }
+ h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
+ h->start = h->pos = r->header_in->pos;
+ h->end = h->last = r->header_in->last;
- } else {
- rb->chain[0].hunk = rb->hunk;
- rb->chain[0].next = NULL;
- }
-
- n = ngx_recv_chain(r->connection, rb->chain);
+ ngx_alloc_link_and_set_hunk(r->request_hunks, h, r->pool,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
- if (n == NGX_ERROR) {
- return NGX_ERROR;
+ if (size >= r->headers_in.content_length_n) {
+ r->header_in->pos += r->headers_in.content_length_n;
+ return NGX_OK;
}
+ }
- if (n == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- for (entry = rb->chain; entry; entry = entry->next) {
- size = entry->hunk->end - entry->hunk->last;
-
- if (n >= size) {
- n -= size;
- entry->hunk->last = entry->hunk->end;
-
- continue;
- }
+ r->request_body_len = r->headers_in.content_length_n - size;
- entry->hunk->last += n;
+ if (r->request_body_len < request_buffer_size + (request_buffer_size >> 2))
+ {
+ size = r->request_body_len;
- break;
- }
+ } else {
+ size = request_buffer_size;
+ }
- if (rb->hunk && rb->hunk->last == rb->hunk->end) {
- if (rb->temp_file.fd == NGX_INVALID_FILE) {
- rc = ngx_create_temp_file(&rb->temp_file, rb->temp_path,
- r->pool, 0);
+ ngx_test_null(r->request_body_hunk,
+ ngx_create_temp_hunk(r->pool, size, 0, 0),
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
+ r->connection->read->event_handler =
+ ngx_http_read_client_request_body_handler;
- if (rc == NGX_AGAIN) {
- return NGX_AGAIN;
- }
- }
+ ngx_http_read_client_request_body_handler(r->connection->read);
- n = ngx_write_file(&rb->temp_file, rb->hunk->pos,
- rb->hunk->last - rb->hunk->pos, rb->offset);
+ ngx_alloc_link_and_set_hunk(cl, r->request_body_hunk, r->pool,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
+ if (r->request_hunks) {
+ r->request_hunks->next = cl;
- rb->offset += n;
- rb->hunk->last = rb->hunk->pos;
- }
+ } else {
+ r->request_hunks = cl;
+ }
- } while (r->connection->read->ready);
+ if (r->request_body_len) {
+ return NGX_AGAIN;
+ }
return NGX_OK;
}
-int ngx_http_init_client_request_body_chain(ngx_http_request_t *r)
+static void ngx_http_read_client_request_body_handler(ngx_event_t *rev)
{
- int i;
- ngx_hunk_t *h;
- ngx_http_request_body_t *rb;
-
- rb = r->request_body;
+ ssize_t n, size;
+ ngx_hunk_t *h;
+ ngx_connection_t *c;
+ ngx_http_request_t *r;
+
+ c = rev->data;
+ r = c->data;
+
+ if (r->request_body_hunk->end - r->request_body_hunk->last == 0) {
+ n = ngx_write_chain_to_temp_file(r->temp_file,
+ r->request_hunks->next ? r->request_hunks->next:
+ r->request_hunks);
+ /* TODO: n == 0 or not complete and level event */
+
+ r->request_body_hunk->pos = r->request_body_hunk->start;
+ r->request_body_hunk->last = r->request_body_hunk->start;
+ }
- rb->chain[0].hunk = rb->header_out;
- i = 0;
+ size = r->request_body_hunk->end - r->request_body_hunk->last;
- if (r->header_in->pos < r->header_in->last) {
- rb->chain[i].next = &rb->chain[i + 1];
- i++;
- rb->chain[i].hunk = r->header_in;
+ if (size > r->request_body_len) {
+ size = r->request_body_len;
}
- if (rb->temp_file.fd != NGX_INVALID_FILE) {
+ n = ngx_recv(c, r->request_body_hunk->last, size);
- if (rb->file_hunk == NULL) {
- ngx_test_null(h, ngx_alloc_hunk(r->pool), NGX_ERROR);
+ if (n == NGX_AGAIN) {
+ if (ngx_handle_read_event(rev) == NGX_ERROR) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ }
- h->type = NGX_HUNK_FILE;
- h->pos = h->start = h->pre_start = 0;
- h->last = h->end = h->post_end = 0;
- h->file_pos = 0;
- h->file_last = rb->offset;
- h->file = &rb->temp_file;
- h->shadow = NULL;
- h->tag = 0;
+ return;
+ }
- rb->file_hunk = h;
- }
+ if (n == 0) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client closed prematurely connection");
+ }
- rb->chain[i].next = &rb->chain[i + 1];
- i++;
- rb->chain[i].hunk = rb->file_hunk;
+ if (n == 0 || n == NGX_ERROR) {
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+ return;
}
- if (rb->hunk && rb->hunk->pos < rb->hunk->last) {
- rb->chain[i].next = &rb->chain[i + 1];
- i++;
- rb->chain[i].hunk = h;
+ r->request_body_hunk->last += n;
+ r->request_body_len -= n;
+
+ if (r->request_body_len) {
+ return;
}
- rb->chain[i].next = NULL;
+ if (r->temp_file->file.fd != NGX_INVALID_FILE) {
- return NGX_OK;
-}
+ /* save the last part */
+ n = ngx_write_chain_to_temp_file(r->temp_file,
+ r->request_hunks->next ? r->request_hunks->next:
+ r->request_hunks);
+ /* TODO: n == 0 or not complete and level event */
-void ngx_http_reinit_client_request_body_hunks(ngx_http_request_t *r)
-{
- ngx_http_request_body_t *rb;
+ h = ngx_calloc_hunk(r->pool);
+ if (h == NULL) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return;
+ }
- rb = r->request_body;
+ h->type = NGX_HUNK_FILE;
+ h->file_pos = 0;
+ h->file_last = r->temp_file->file.offset;
+ h->file = &r->temp_file->file;
- if (rb->header_in_pos) {
- r->header_in->pos = rb->header_in_pos;
- }
+ if (r->request_hunks->next) {
+ r->request_hunks->next->hunk = h;
- if (rb->file_hunk) {
- rb->file_hunk->file_pos = 0;
+ } else {
+ r->request_hunks->hunk = h;
+ }
}
- if (rb->hunk) {
- rb->hunk->pos = rb->hunk->start;
- }
+ r->request_body_handler(r->data);
}