Mercurial > hg > nginx
changeset 7913:185c86b830ef
Request body: introduced rb->last_saved flag.
It indicates that the last buffer was received by the save filter,
and can be used to check this at higher levels. To be used in the
following changes.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 29 Aug 2021 22:21:03 +0300 |
parents | 96e09beaa2cf |
children | 9cf043a5d9ca |
files | src/http/ngx_http_request.h src/http/ngx_http_request_body.c |
diffstat | 2 files changed, 56 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/ngx_http_request.h Sun Aug 29 22:20:54 2021 +0300 +++ b/src/http/ngx_http_request.h Sun Aug 29 22:21:03 2021 +0300 @@ -302,6 +302,7 @@ ngx_chain_t *busy; ngx_http_chunked_t *chunked; ngx_http_client_body_handler_pt post_handler; + unsigned last_saved:1; } ngx_http_request_body_t;
--- a/src/http/ngx_http_request_body.c Sun Aug 29 22:20:54 2021 +0300 +++ b/src/http/ngx_http_request_body.c Sun Aug 29 22:21:03 2021 +0300 @@ -69,6 +69,7 @@ * rb->busy = NULL; * rb->chunked = NULL; * rb->received = 0; + * rb->last_saved = 0; */ rb->rest = -1; @@ -941,15 +942,32 @@ rb = r->request_body; + out = NULL; + ll = &out; + if (rb->rest == -1) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http request body content length filter"); rb->rest = r->headers_in.content_length_n; - } + + if (rb->rest == 0) { + + tl = ngx_chain_get_free_buf(r->pool, &rb->free); + if (tl == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } - out = NULL; - ll = &out; + b = tl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + + b->last_buf = 1; + + *ll = tl; + ll = &tl->next; + } + } for (cl = in; cl; cl = cl->next) { @@ -1013,6 +1031,9 @@ rb = r->request_body; + out = NULL; + ll = &out; + if (rb->rest == -1) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -1029,9 +1050,6 @@ rb->rest = cscf->large_client_header_buffers.size; } - out = NULL; - ll = &out; - for (cl = in; cl; cl = cl->next) { b = NULL; @@ -1188,15 +1206,16 @@ ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) { ngx_buf_t *b; - ngx_chain_t *cl; + ngx_chain_t *cl, *tl, **ll; ngx_http_request_body_t *rb; rb = r->request_body; -#if (NGX_DEBUG) + ll = &rb->bufs; + + for (cl = rb->bufs; cl; cl = cl->next) { #if 0 - for (cl = rb->bufs; cl; cl = cl->next) { ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, "http body old buf t:%d f:%d %p, pos %p, size: %z " "file: %O, size: %O", @@ -1205,10 +1224,13 @@ cl->buf->last - cl->buf->pos, cl->buf->file_pos, cl->buf->file_last - cl->buf->file_pos); - } #endif + ll = &cl->next; + } + for (cl = in; cl; cl = cl->next) { + ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, "http body new buf t:%d f:%d %p, pos %p, size: %z " "file: %O, size: %O", @@ -1217,15 +1239,31 @@ cl->buf->last - cl->buf->pos, cl->buf->file_pos, cl->buf->file_last - cl->buf->file_pos); + + if (cl->buf->last_buf) { + + if (rb->last_saved) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "duplicate last buf in save filter"); + *ll = NULL; + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + rb->last_saved = 1; + } + + tl = ngx_alloc_chain_link(r->pool); + if (tl == NULL) { + *ll = NULL; + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + tl->buf = cl->buf; + *ll = tl; + ll = &tl->next; } -#endif - - /* TODO: coalesce neighbouring buffers */ - - if (ngx_chain_add_copy(r->pool, &rb->bufs, in) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } + *ll = NULL; if (r->request_body_no_buffering) { return NGX_OK;