[nginx] svn commit: r4958 - in branches/stable-1.2: . src/http

mdounin at mdounin.ru mdounin at mdounin.ru
Tue Dec 11 13:18:50 UTC 2012


Author: mdounin
Date: 2012-12-11 13:18:50 +0000 (Tue, 11 Dec 2012)
New Revision: 4958
URL: http://trac.nginx.org/nginx/changeset/4958/nginx

Log:
Merge of r4921, r4922, r4923, r4924, r4925: request body fixes.

*) Request body: fixed "501 Not Implemented" error handling.

   It is not about "Method" but a generic message, and is expected to be used
   e.g. if specified Transfer-Encoding is not supported.  Fixed message to
   match RFC 2616.

   Additionally, disable keepalive on such errors as we won't be able to read
   request body correctly if we don't understand Transfer-Encoding used.

*) Request body: $request_body variable generalization.

   The $request_body variable was assuming there can't be more than two
   buffers.  While this is currently true due to request body reading
   implementation details, this is not a good thing to depend on and may
   change in the future.

*) Request body: code duplication reduced, no functional changes.

   The r->request_body_in_file_only with empty body case is now handled in
   ngx_http_write_request_body().

*) Request body: fixed socket leak on errors.

   The r->main->count reference counter was always incremented in
   ngx_http_read_client_request_body(), while it is only needs to be
   incremented on positive returns.

*) Request body: properly handle events while discarding body.

   An attempt to call ngx_handle_read_event() before actually reading
   data from a socket might result in read event being disabled, which is
   wrong.  Catched by body.t test on Solaris.


Modified:
   branches/stable-1.2/
   branches/stable-1.2/src/http/ngx_http_header_filter_module.c
   branches/stable-1.2/src/http/ngx_http_request_body.c
   branches/stable-1.2/src/http/ngx_http_special_response.c
   branches/stable-1.2/src/http/ngx_http_variables.c

Index: branches/stable-1.2
===================================================================
--- branches/stable-1.2	2012-12-10 18:17:32 UTC (rev 4957)
+++ branches/stable-1.2	2012-12-11 13:18:50 UTC (rev 4958)

Property changes on: branches/stable-1.2
___________________________________________________________________
Modified: svn:mergeinfo
## -1 +1 ##
-/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4920,4933-4934,4939
+/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939
\ No newline at end of property
Modified: branches/stable-1.2/src/http/ngx_http_header_filter_module.c
===================================================================
--- branches/stable-1.2/src/http/ngx_http_header_filter_module.c	2012-12-10 18:17:32 UTC (rev 4957)
+++ branches/stable-1.2/src/http/ngx_http_header_filter_module.c	2012-12-11 13:18:50 UTC (rev 4958)
@@ -112,7 +112,7 @@
 #define NGX_HTTP_OFF_5XX   (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
 
     ngx_string("500 Internal Server Error"),
-    ngx_string("501 Method Not Implemented"),
+    ngx_string("501 Not Implemented"),
     ngx_string("502 Bad Gateway"),
     ngx_string("503 Service Temporarily Unavailable"),
     ngx_string("504 Gateway Time-out"),

Modified: branches/stable-1.2/src/http/ngx_http_request_body.c
===================================================================
--- branches/stable-1.2/src/http/ngx_http_request_body.c	2012-12-10 18:17:32 UTC (rev 4957)
+++ branches/stable-1.2/src/http/ngx_http_request_body.c	2012-12-11 13:18:50 UTC (rev 4958)
@@ -31,9 +31,9 @@
 {
     size_t                     preread;
     ssize_t                    size;
+    ngx_int_t                  rc;
     ngx_buf_t                 *b;
     ngx_chain_t               *cl, **next;
-    ngx_temp_file_t           *tf;
     ngx_http_request_body_t   *rb;
     ngx_http_core_loc_conf_t  *clcf;
 
@@ -45,12 +45,14 @@
     }
 
     if (ngx_http_test_expect(r) != NGX_OK) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        goto done;
     }
 
     rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
     if (rb == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        goto done;
     }
 
     r->request_body = rb;
@@ -65,32 +67,10 @@
     if (r->headers_in.content_length_n == 0) {
 
         if (r->request_body_in_file_only) {
-            tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
-            if (tf == NULL) {
-                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            if (ngx_http_write_request_body(r, NULL) != NGX_OK) {
+                rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+                goto done;
             }
-
-            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";
-            tf->log_level = r->request_body_file_log_level;
-            tf->persistent = r->request_body_in_persistent_file;
-            tf->clean = r->request_body_in_clean_file;
-
-            if (r->request_body_file_group_access) {
-                tf->access = 0660;
-            }
-
-            rb->temp_file = tf;
-
-            if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
-                                     tf->persistent, tf->clean, tf->access)
-                != NGX_OK)
-            {
-                return NGX_HTTP_INTERNAL_SERVER_ERROR;
-            }
         }
 
         post_handler(r);
@@ -119,7 +99,8 @@
 
         b = ngx_calloc_buf(r->pool);
         if (b == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+            goto done;
         }
 
         b->temporary = 1;
@@ -130,7 +111,8 @@
 
         rb->bufs = ngx_alloc_chain_link(r->pool);
         if (rb->bufs == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+            goto done;
         }
 
         rb->bufs->buf = b;
@@ -148,7 +130,8 @@
 
             if (r->request_body_in_file_only) {
                 if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) {
-                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                    rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+                    goto done;
                 }
             }
 
@@ -175,7 +158,8 @@
 
             r->read_event_handler = ngx_http_read_client_request_body_handler;
 
-            return ngx_http_do_read_client_request_body(r);
+            rc = ngx_http_do_read_client_request_body(r);
+            goto done;
         }
 
         next = &rb->bufs->next;
@@ -205,12 +189,14 @@
 
     rb->buf = ngx_create_temp_buf(r->pool, size);
     if (rb->buf == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        goto done;
     }
 
     cl = ngx_alloc_chain_link(r->pool);
     if (cl == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        goto done;
     }
 
     cl->buf = rb->buf;
@@ -235,7 +221,15 @@
 
     r->read_event_handler = ngx_http_read_client_request_body_handler;
 
-    return ngx_http_do_read_client_request_body(r);
+    rc = ngx_http_do_read_client_request_body(r);
+
+done:
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+        r->main->count--;
+    }
+
+    return rc;
 }
 
 
@@ -419,6 +413,19 @@
         }
 
         rb->temp_file = tf;
+
+        if (body == NULL) {
+            /* empty body with r->request_body_in_file_only */
+
+            if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
+                                     tf->persistent, tf->clean, tf->access)
+                != NGX_OK)
+            {
+                return NGX_ERROR;
+            }
+
+            return NGX_OK;
+        }
     }
 
     n = ngx_write_chain_to_temp_file(rb->temp_file, body);
@@ -475,20 +482,22 @@
         }
     }
 
+    if (ngx_http_read_discarded_request_body(r) == NGX_OK) {
+        r->lingering_close = 0;
+        return NGX_OK;
+    }
+
+    /* == NGX_AGAIN */
+
     r->read_event_handler = ngx_http_discarded_request_body_handler;
 
     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    if (ngx_http_read_discarded_request_body(r) == NGX_OK) {
-        r->lingering_close = 0;
+    r->count++;
+    r->discard_body = 1;
 
-    } else {
-        r->count++;
-        r->discard_body = 1;
-    }
-
     return NGX_OK;
 }
 

Modified: branches/stable-1.2/src/http/ngx_http_special_response.c
===================================================================
--- branches/stable-1.2/src/http/ngx_http_special_response.c	2012-12-10 18:17:32 UTC (rev 4957)
+++ branches/stable-1.2/src/http/ngx_http_special_response.c	2012-12-11 13:18:50 UTC (rev 4958)
@@ -260,9 +260,9 @@
 
 static char ngx_http_error_501_page[] =
 "<html>" CRLF
-"<head><title>501 Method Not Implemented</title></head>" CRLF
+"<head><title>501 Not Implemented</title></head>" CRLF
 "<body bgcolor=\"white\">" CRLF
-"<center><h1>501 Method Not Implemented</h1></center>" CRLF
+"<center><h1>501 Not Implemented</h1></center>" CRLF
 ;
 
 
@@ -384,6 +384,7 @@
             case NGX_HTTPS_CERT_ERROR:
             case NGX_HTTPS_NO_CERT:
             case NGX_HTTP_INTERNAL_SERVER_ERROR:
+            case NGX_HTTP_NOT_IMPLEMENTED:
                 r->keepalive = 0;
         }
     }

Modified: branches/stable-1.2/src/http/ngx_http_variables.c
===================================================================
--- branches/stable-1.2/src/http/ngx_http_variables.c	2012-12-10 18:17:32 UTC (rev 4957)
+++ branches/stable-1.2/src/http/ngx_http_variables.c	2012-12-11 13:18:50 UTC (rev 4958)
@@ -1767,7 +1767,7 @@
 {
     u_char       *p;
     size_t        len;
-    ngx_buf_t    *buf, *next;
+    ngx_buf_t    *buf;
     ngx_chain_t  *cl;
 
     if (r->request_body == NULL
@@ -1792,18 +1792,26 @@
         return NGX_OK;
     }
 
-    next = cl->next->buf;
-    len = (buf->last - buf->pos) + (next->last - next->pos);
+    len = buf->last - buf->pos;
+    cl = cl->next;
 
+    for ( /* void */ ; cl; cl = cl->next) {
+        buf = cl->buf;
+        len += buf->last - buf->pos;
+    }
+
     p = ngx_pnalloc(r->pool, len);
     if (p == NULL) {
         return NGX_ERROR;
     }
 
     v->data = p;
+    cl = r->request_body->bufs;
 
-    p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
-    ngx_memcpy(p, next->pos, next->last - next->pos);
+    for ( /* void */ ; cl; cl = cl->next) {
+        buf = cl->buf;
+        p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
+    }
 
     v->len = len;
     v->valid = 1;



More information about the nginx-devel mailing list