
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_http.h>


static void ngx_http_read_client_request_body_handler(ngx_event_t *rev);


int ngx_http_read_client_request_body(ngx_http_request_t *r,
                                      int request_buffer_size)
{
    ssize_t       size;
    ngx_hunk_t   *h;
    ngx_chain_t  *cl;

    size = r->header_in->last - r->header_in->pos;

    if (size) {
        ngx_test_null(h, ngx_calloc_hunk(r->pool),
                      NGX_HTTP_INTERNAL_SERVER_ERROR);

        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;

        ngx_alloc_link_and_set_hunk(r->request_hunks, h, r->pool,
                                    NGX_HTTP_INTERNAL_SERVER_ERROR);

        if (size >= r->headers_in.content_length_n) {
            r->header_in->pos += r->headers_in.content_length_n;
            return NGX_OK;
        }
    }

    r->request_body_len = r->headers_in.content_length_n - size;

    if (r->request_body_len < request_buffer_size + (request_buffer_size >> 2))
    {
        size = r->request_body_len;

    } else {
        size = request_buffer_size;
    }

    ngx_test_null(r->request_body_hunk,
                  ngx_create_temp_hunk(r->pool, size, 0, 0),
                  NGX_HTTP_INTERNAL_SERVER_ERROR);

    r->connection->read->event_handler =
                                     ngx_http_read_client_request_body_handler;

    ngx_http_read_client_request_body_handler(r->connection->read);

    ngx_alloc_link_and_set_hunk(cl, r->request_body_hunk, r->pool,
                                NGX_HTTP_INTERNAL_SERVER_ERROR);

    if (r->request_hunks) {
        r->request_hunks->next = cl;

    } else {
        r->request_hunks = cl;
    }

    if (r->request_body_len) {
        return NGX_AGAIN;
    }

    return NGX_OK;
}


static void ngx_http_read_client_request_body_handler(ngx_event_t *rev)
{
    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;
    }

    size = r->request_body_hunk->end - r->request_body_hunk->last;

    if (size > r->request_body_len) {
        size = r->request_body_len;
    }

    n = ngx_recv(c, r->request_body_hunk->last, size);

    if (n == NGX_AGAIN) {
        if (ngx_handle_read_event(rev) == NGX_ERROR) {
            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
        }

        return;
    }

    if (n == 0) {
        ngx_log_error(NGX_LOG_INFO, c->log, 0,
                      "client closed prematurely connection");
    }

    if (n == 0 || n == NGX_ERROR) {
        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
        return;
    }

    r->request_body_hunk->last += n;
    r->request_body_len -= n;

    if (r->request_body_len) {
        return;
    }

    if (r->temp_file->file.fd != NGX_INVALID_FILE) {

        /* 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 */


        h = ngx_calloc_hunk(r->pool);
        if (h == NULL) {
            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
            return;
        }

        h->type = NGX_HUNK_FILE;
        h->file_pos = 0;
        h->file_last = r->temp_file->file.offset;
        h->file = &r->temp_file->file;

        if (r->request_hunks->next) {
            r->request_hunks->next->hunk = h;

        } else {
            r->request_hunks->hunk = h;
        }
    }

    r->request_body_handler(r->data);
}
