On Mon, Nov 11, 2019 at 05:23:55PM +0300, Михаил Монашёв wrote: > Здравствуйте. > > Оказалось, что client_max_body_size не работает внутри if-а . > > Хотел ограничивать размер GET- и POST-запросов, не ограничивая размер > PUT-запросов, поступающих с доверенных ip. Конфиг планировался > примерно такой: > > server { > listen 80; > server_name xxxxx; > > expires 1y; > > location / { > root /xxxx/yyyyy; > > if ($request_method == PUT ) { > client_max_body_size 0; # disable request size checks > } > > client_body_temp_path /xxxx/webdav-tmp; > > dav_methods PUT DELETE MKCOL COPY MOVE; > create_full_put_path on; > dav_access user:rw group:rw all:r; > > limit_except GET { > allow 127.0.0.0/8; > allow 10.0.0.0/8; > > deny all; > } > } > } > > Добавить NGX_HTTP_LIF_CONF в ngx_http_core_module.c не проблема. Но > если есть возможность менять client_max_body_size внутри if-ов в самом > nginx-е, было бы здорово. Если против этого, конечно же, нет никаких > возражений.
Всё не так просто. Сейчас для обычного (не-chunked) тела запроса проверка на данное ограничение встроена в фазу FIND_CONFIG, обработчик которой вызывается при исходном выборе location'а, а также каждый раз, когда location выбирается при помощи директивы rewrite. Можно передвинуть проверку на ограничение в фазу POST_REWRITE. От этого становится чуть лучше, и client_max_body_size начинает работать внутри "if" (добавления только NGX_HTTP_LIF_CONF недостаточно), но ограничение всё равно будет проверяться по числу выборов новых location'ов, и в целом идея работать не будет, т.к. фактически будет срабатывать наименьшее из ограничений: location /1 { client_max_body_size 8; rewrite /1 /2; } location /2 { client_max_body_size 9; rewrite /2 /3; } location /3 { client_max_body_size 10; } } Кроме того, фазы POST_REWRITE может и не быть, так что туда нельзя. Аналогично, не подходит и фаза POST_ACCESS (её также может не быть). Остаётся убрать это в CONTENT-фазу, но насколько это хорошее изменение, я пока не до конца понимаю. Proof of concept патч: # HG changeset patch # User Ruslan Ermilov <r...@nginx.com> # Date 1573570198 -10800 # Tue Nov 12 17:49:58 2019 +0300 # Node ID f50e2acbb576cbd699307a647da3e4ec2dbe5b48 # Parent 1ab95c51955e9c9fc9954b4d43d287c87a97fe0e Enabled client_max_body_size inside "if". diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -343,7 +343,8 @@ static ngx_command_t ngx_http_core_comm NULL }, { ngx_string("client_max_body_size"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF + |NGX_CONF_TAKE1, ngx_conf_set_off_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, client_max_body_size), @@ -961,25 +962,6 @@ ngx_http_core_find_config_phase(ngx_http ngx_http_update_location_config(r); - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http cl:%O max:%O", - r->headers_in.content_length_n, clcf->client_max_body_size); - - if (r->headers_in.content_length_n != -1 - && !r->discard_body - && clcf->client_max_body_size - && clcf->client_max_body_size < r->headers_in.content_length_n) - { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "client intended to send too large body: %O bytes", - r->headers_in.content_length_n); - - r->expect_tested = 1; - (void) ngx_http_discard_request_body(r); - ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE); - return NGX_OK; - } - if (rc == NGX_DONE) { ngx_http_clear_location(r); @@ -1160,9 +1142,31 @@ ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph) { - size_t root; - ngx_int_t rc; - ngx_str_t path; + size_t root; + ngx_int_t rc; + ngx_str_t path; + ngx_http_core_loc_conf_t *clcf; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http cl:%O max:%O", + r->headers_in.content_length_n, clcf->client_max_body_size); + + if (r->headers_in.content_length_n != -1 + && !r->discard_body + && clcf->client_max_body_size + && clcf->client_max_body_size < r->headers_in.content_length_n) + { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "client intended to send too large body: %O bytes", + r->headers_in.content_length_n); + + r->expect_tested = 1; + (void) ngx_http_discard_request_body(r); + ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE); + return NGX_OK; + } if (r->content_handler) { r->write_event_handler = ngx_http_request_empty_handler; _______________________________________________ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru