[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