[BUG] "client_body_in_file_only on" no longer works with upstream modules in nginx 1.3.9+

Maxim Dounin mdounin at mdounin.ru
Mon Jan 28 11:30:35 UTC 2013


Hello!

On Sun, Jan 27, 2013 at 12:07:37AM -0800, agentzh wrote:

> Hello!
> 
> I've noticed that for nginx 1.3.9+, "client_body_in_file_only on" no
> longer always sets r->request_body->bufs, which makes upstream modules
> like ngx_proxy send empty request bodies to the backend server.
> 
> Here's a minimal example that demonstrates the issue:
> 
>     location = /t {
>         client_body_in_file_only on;
>         proxy_pass http://127.0.0.1:1234;
>     }
> 
> And run nc to listen on the local port 1234:
> 
>     $ nc -l 1234
> 
> Then issue a simple POST request to location = /t:
> 
>     $ curl -d 'hello world' localhost/t
> 
> When using nginx 1.3.9+, we get the raw HTTP request sent by ngx_proxy:
> 
>     $ nc -l 1234
>     POST /t HTTP/1.0
>     Host: 127.0.0.1:1234
>     Connection: close
>     Content-Length: 11
>     User-Agent: curl/7.24.0 (x86_64-redhat-linux-gnu) libcurl/7.24.0 ...
>     Accept: */*
>     Content-Type: application/x-www-form-urlencoded
> 
> That is, when the request body is completely preread into the client
> header buffer, the request body will only be hooked into
> r->request_body->temp_file but not r->request_body->bufs.
> 
> But when the request body is big enough that it is not completely
> preread into the client header buffer, then the a in-file buf will
> still be properly inserted into r->request_body->bufs and we can get
> the expected request body sent from ngx_proxy.

Thnx, the test for client_body_in_file_only actually checked file, 
so it wasn't noticed.  :)

The following patch should fix this:

# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1359372279 -14400
# Node ID 1f6b73a7b7c9992d2e6853413a8f2c599c1e8ea8
# Parent  153d131f0b7aa28fde12a94fd6a7e78a20743a3a
Request body: fixed client_body_in_file_only.

Broken while introducing chunked request body reading support in 1.3.9.

diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -35,7 +35,8 @@ ngx_http_read_client_request_body(ngx_ht
     size_t                     preread;
     ssize_t                    size;
     ngx_int_t                  rc;
-    ngx_chain_t                out;
+    ngx_buf_t                 *b;
+    ngx_chain_t                out, *cl;
     ngx_http_request_body_t   *rb;
     ngx_http_core_loc_conf_t  *clcf;
 
@@ -128,6 +129,21 @@ ngx_http_read_client_request_body(ngx_ht
                 rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
                 goto done;
             }
+
+            cl = ngx_chain_get_free_buf(r->pool, &rb->free);
+            if (cl == NULL) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+                
+            b = cl->buf;
+                
+            ngx_memzero(b, sizeof(ngx_buf_t));
+            
+            b->in_file = 1;
+            b->file_last = rb->temp_file->file.offset;
+            b->file = &rb->temp_file->file;
+         
+            rb->bufs = cl;
         }
 
         post_handler(r);


-- 
Maxim Dounin
http://nginx.com/support.html



More information about the nginx-devel mailing list