diff options
author | Igor Sysoev <igor@sysoev.ru> | 2003-10-27 08:53:49 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2003-10-27 08:53:49 +0000 |
commit | 10fc9ef77503ec4db5f5006557aeffc1939043ca (patch) | |
tree | 48dd22fcf5c6defd2960156f24a8b07757a7c6da /src/http/ngx_http_request_body.c | |
parent | 6414b96ebc50f42bf878aa84839921ab0aa9f4df (diff) | |
download | nginx-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.c | 248 |
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); } |