diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2021-08-29 22:21:03 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2021-08-29 22:21:03 +0300 |
commit | 2a709213800fd3fd2809881374eb110562b53c08 (patch) | |
tree | a884cfd5f63699a150021854c3fdfe314f0a37d7 | |
parent | fd9d43b087b4247f8cb5f91845be46bd624c175a (diff) | |
download | nginx-2a709213800fd3fd2809881374eb110562b53c08.tar.gz |
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.
-rw-r--r-- | src/http/ngx_http_request.h | 1 | ||||
-rw-r--r-- | src/http/ngx_http_request_body.c | 68 |
2 files changed, 54 insertions, 15 deletions
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index 63576274e..896657890 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -302,6 +302,7 @@ typedef struct { 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; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c index c5401fd42..4a31db0bc 100644 --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -69,6 +69,7 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, * rb->busy = NULL; * rb->chunked = NULL; * rb->received = 0; + * rb->last_saved = 0; */ rb->rest = -1; @@ -941,15 +942,32 @@ ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in) 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; - } - out = NULL; - ll = &out; + if (rb->rest == 0) { + + tl = ngx_chain_get_free_buf(r->pool, &rb->free); + if (tl == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + 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 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in) 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 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in) 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_int_t 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; -#if 0 for (cl = rb->bufs; cl; cl = cl->next) { + +#if 0 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 @@ ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) 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,16 +1239,32 @@ ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) cl->buf->last - cl->buf->pos, cl->buf->file_pos, cl->buf->file_last - cl->buf->file_pos); - } -#endif + if (cl->buf->last_buf) { - /* TODO: coalesce neighbouring buffers */ + 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; + } - if (ngx_chain_add_copy(r->pool, &rb->bufs, in) != NGX_OK) { - 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; } + *ll = NULL; + if (r->request_body_no_buffering) { return NGX_OK; } |