From a92fa3b1db115b5b730c4e190b4fb87d800cc4c1 Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Fri, 30 Sep 2011 14:36:19 +0000 Subject: [PATCH] Merging r3986, r4006, r4007, r4073: Request body related fixes: *) Always set timer in discard body handler, this fixes the cases when request for static file is redirected by error_page to an SSI page. *) Correctly set body if it's preread and there are extra data. Previously all available data was used as body, resulting in garbage after real body e.g. in case of pipelined requests. Make sure to use only as many bytes as request's Content-Length specifies. *) Fix body with request_body_in_single_buf. If there were preread data and request body was big enough first part of the request body was duplicated. See report here: http://mailman.nginx.org/pipermail/nginx/2011-July/027756.html *) Bugfix: read event was not blocked after reading body. Read event should be blocked after reading body, else undefined behaviour might occur on additional client activity. This fixes segmentation faults observed with proxy_ignore_client_abort set. --- src/http/ngx_http_request.c | 2 +- src/http/ngx_http_request_body.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index d11b13e4a..5e0b8e891 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -2123,11 +2123,11 @@ ngx_http_finalize_connection(ngx_http_request_t *r) if (r->discard_body) { r->read_event_handler = ngx_http_discarded_request_body_handler; + ngx_add_timer(r->connection->read, clcf->lingering_timeout); if (r->lingering_time == 0) { r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000); - ngx_add_timer(r->connection->read, clcf->lingering_timeout); } } diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c index be311a612..817b48e45 100644 --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -143,6 +143,7 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, r->header_in->pos += (size_t) r->headers_in.content_length_n; r->request_length += r->headers_in.content_length_n; + b->last = r->header_in->pos; if (r->request_body_in_file_only) { if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) { @@ -371,10 +372,14 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r) } } - if (r->request_body_in_file_only && rb->bufs->next) { + if (rb->bufs->next + && (r->request_body_in_file_only || r->request_body_in_single_buf)) + { rb->bufs = rb->bufs->next; } + r->read_event_handler = ngx_http_block_reading; + rb->post_handler(r); return NGX_OK;