diff src/http/ngx_http_request_body.c @ 28:7ca9bdc82b3f NGINX_0_1_14

nginx 0.1.14 *) Feature: the autoconfiguration directives: --http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH, and --http-fastcgi-temp-path=PATH *) Change: the directory name for the temporary files with the client request body is specified by directive client_body_temp_path, by default it is <prefix>/client_body_temp. *) Feature: the ngx_http_fastcgi_module and the directives: fastcgi_pass, fastcgi_root, fastcgi_index, fastcgi_params, fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout, fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers, fastcgi_busy_buffers_size, fastcgi_temp_path, fastcgi_max_temp_file_size, fastcgi_temp_file_write_size, fastcgi_next_upstream, and fastcgi_x_powered_by. *) Bugfix: the "[alert] zero size buf" error; bug appeared in 0.1.3. *) Change: the URI must be specified after the host name in the proxy_pass directive. *) Change: the %3F symbol in the URI was considered as the argument string start. *) Feature: the unix domain sockets support in the ngx_http_proxy_module. *) Feature: the ssl_engine and ssl_ciphers directives. Thanks to Sergey Skvortsov for SSL-accelerator.
author Igor Sysoev <http://sysoev.ru>
date Tue, 18 Jan 2005 00:00:00 +0300
parents 420dd3f9e703
children 72eb30262aac
line wrap: on
line diff
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -11,31 +11,67 @@
 
 
 static void ngx_http_read_client_request_body_handler(ngx_event_t *rev);
-static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
+static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r,
+                                                      ngx_connection_t *c);
 
+/*
+ * on completion ngx_http_read_client_request_body() adds to
+ * r->request_body->bufs one or two bufs:
+ *    *) one memory buf that was preread in r->header_in;
+ *    *) one memory or file buf that contains the rest of the body
+ */
 
-ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r)
+ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r,
+                                  ngx_http_client_body_handler_pt post_handler)
+
 {
     ssize_t                    size;
     ngx_buf_t                 *b;
     ngx_chain_t               *cl;
+    ngx_http_request_body_t   *rb;
     ngx_http_core_loc_conf_t  *clcf;
 
+    if (!(rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)))) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    r->request_body = rb;
+
+    if (r->headers_in.content_length_n <= 0) {
+        post_handler(r);
+        return NGX_OK;
+    }
+
+    rb->post_handler = post_handler;
+
+    /*
+     * set by ngx_pcalloc():
+     *
+     *     rb->bufs = NULL;
+     *     rb->buf = NULL;
+     *     rb->rest = 0;
+     */
+
     size = r->header_in->last - r->header_in->pos;
 
     if (size) {
 
         /* there is the pre-read part of the request body */
 
-        ngx_test_null(b, ngx_calloc_buf(r->pool),
-                      NGX_HTTP_INTERNAL_SERVER_ERROR);
+        if (!(b = ngx_calloc_buf(r->pool))) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
 
         b->temporary = 1;
         b->start = b->pos = r->header_in->pos;
         b->end = b->last = r->header_in->last;
 
-        ngx_alloc_link_and_set_buf(r->request_body->bufs, b, r->pool,
-                                    NGX_HTTP_INTERNAL_SERVER_ERROR);
+        if (!(rb->bufs = ngx_alloc_chain_link(r->pool))) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        rb->bufs->buf = b;
+        rb->bufs->next = NULL;
 
         if (size >= r->headers_in.content_length_n) {
 
@@ -44,7 +80,7 @@ ngx_int_t ngx_http_read_client_request_b
             r->header_in->pos += r->headers_in.content_length_n;
             r->request_length += r->headers_in.content_length_n;
 
-            r->request_body->handler(r->request_body->data);
+            post_handler(r);
 
             return NGX_OK;
         }
@@ -56,35 +92,39 @@ ngx_int_t ngx_http_read_client_request_b
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
-    r->request_body->rest = r->headers_in.content_length_n - size;
+    rb->rest = r->headers_in.content_length_n - size;
 
-    if (r->request_body->rest
-                             < clcf->client_body_buffer_size
+    if (rb->rest < clcf->client_body_buffer_size
                                         + (clcf->client_body_buffer_size >> 2))
     {
-        size = r->request_body->rest;
+        size = rb->rest;
 
     } else {
         size = clcf->client_body_buffer_size;
     }
 
-    ngx_test_null(r->request_body->buf, ngx_create_temp_buf(r->pool, size),
-                  NGX_HTTP_INTERNAL_SERVER_ERROR);
+    if (!(rb->buf = ngx_create_temp_buf(r->pool, size))) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
 
-    ngx_alloc_link_and_set_buf(cl, r->request_body->buf, r->pool,
-                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+    if (!(cl = ngx_alloc_chain_link(r->pool))) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
 
-    if (r->request_body->bufs) {
-        r->request_body->bufs->next = cl;
+    cl->buf = rb->buf;
+    cl->next = NULL;
+
+    if (rb->bufs) {
+        rb->bufs->next = cl;
 
     } else {
-        r->request_body->bufs = cl;
+        rb->bufs = cl;
     }
 
     r->connection->read->event_handler =
                                      ngx_http_read_client_request_body_handler;
 
-    return ngx_http_do_read_client_request_body(r);
+    return ngx_http_do_read_client_request_body(r, r->connection);
 }
 
 
@@ -102,7 +142,7 @@ static void ngx_http_read_client_request
         return;
     }
 
-    rc = ngx_http_do_read_client_request_body(r);
+    rc = ngx_http_do_read_client_request_body(r, c);
 
     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
         ngx_http_finalize_request(r, rc);
@@ -110,24 +150,45 @@ static void ngx_http_read_client_request
 }
 
 
-static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r)
+static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r,
+                                                      ngx_connection_t *c)
 {
     size_t                     size;
     ssize_t                    n;
     ngx_buf_t                 *b;
-    ngx_connection_t          *c;
+    ngx_temp_file_t           *tf;
+    ngx_http_request_body_t   *rb;
     ngx_http_core_loc_conf_t  *clcf;
 
-    c = r->connection;
+    rb = r->request_body;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http read client request body");
 
     for ( ;; ) {
-        if (r->request_body->buf->last == r->request_body->buf->end) {
-            n = ngx_write_chain_to_temp_file(r->request_body->temp_file,
-                     r->request_body->bufs->next ? r->request_body->bufs->next:
-                                                   r->request_body->bufs);
+        if (rb->buf->last == rb->buf->end) {
+
+            if (rb->temp_file == NULL) {
+                if (!(tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)))) {
+                    return NGX_ERROR;
+                }
+
+                clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+                tf->file.fd = NGX_INVALID_FILE;
+                tf->file.log = r->connection->log;
+                tf->path = clcf->client_body_temp_path;
+                tf->pool = r->pool;
+                tf->warn = "a client request body is buffered "
+                           "to a temporary file";
+
+                rb->temp_file = tf;
+
+            }
+
+            n = ngx_write_chain_to_temp_file(rb->temp_file,
+                                             rb->bufs->next ? rb->bufs->next:
+                                                              rb->bufs);
 
             /* TODO: n == 0 or not complete and level event */
 
@@ -135,19 +196,19 @@ static ngx_int_t ngx_http_do_read_client
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
-            r->request_body->temp_file->offset += n;
+            rb->temp_file->offset += n;
 
-            r->request_body->buf->pos = r->request_body->buf->start;
-            r->request_body->buf->last = r->request_body->buf->start;
+            rb->buf->pos = rb->buf->start;
+            rb->buf->last = rb->buf->start;
         }
 
-        size = r->request_body->buf->end - r->request_body->buf->last;
+        size = rb->buf->end - rb->buf->last;
 
-        if (size > r->request_body->rest) {
-            size = r->request_body->rest;
+        if (size > rb->rest) {
+            size = rb->rest;
         }
 
-        n = c->recv(c, r->request_body->buf->last, size);
+        n = c->recv(c, rb->buf->last, size);
 
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                        "http client request body recv %z", n);
@@ -173,33 +234,33 @@ static ngx_int_t ngx_http_do_read_client
             return NGX_HTTP_BAD_REQUEST;
         }
 
-        r->request_body->buf->last += n;
-        r->request_body->rest -= n;
+        rb->buf->last += n;
+        rb->rest -= n;
         r->request_length += n;
 
-        if (r->request_body->rest == 0) {
+        if (rb->rest == 0) {
             break;
         }
 
-        if (r->request_body->buf->last < r->request_body->buf->end) {
+        if (rb->buf->last < rb->buf->end) {
             break;
         }
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                   "http client request body rest %uz",
-                   r->request_body->rest);
+                   "http client request body rest %uz", rb->rest);
 
-    if (r->request_body->rest) {
+    if (rb->rest) {
         return NGX_AGAIN;
     }
 
-    if (r->request_body->temp_file->file.fd != NGX_INVALID_FILE) {
+    if (rb->temp_file) {
 
         /* save the last part */
-        n = ngx_write_chain_to_temp_file(r->request_body->temp_file,
-                     r->request_body->bufs->next ? r->request_body->bufs->next:
-                                                   r->request_body->bufs);
+
+        n = ngx_write_chain_to_temp_file(rb->temp_file,
+                                         rb->bufs->next ? rb->bufs->next:
+                                                          rb->bufs);
 
         /* TODO: n == 0 or not complete and level event */
 
@@ -213,18 +274,18 @@ static ngx_int_t ngx_http_do_read_client
 
         b->in_file = 1;
         b->file_pos = 0;
-        b->file_last = r->request_body->temp_file->file.offset;
-        b->file = &r->request_body->temp_file->file;
+        b->file_last = rb->temp_file->file.offset;
+        b->file = &rb->temp_file->file;
 
-        if (r->request_body->bufs->next) {
-            r->request_body->bufs->next->buf = b;
+        if (rb->bufs->next) {
+            rb->bufs->next->buf = b;
 
         } else {
-            r->request_body->bufs->buf = b;
+            rb->bufs->buf = b;
         }
     }
 
-    r->request_body->handler(r->request_body->data);
+    rb->post_handler(r);
 
     return NGX_OK;
 }