Re: Конфликт mirror и dav модулей

Roman Arutyunyan arut на nginx.com
Ср Фев 7 15:18:56 UTC 2018


Здравствуйте, Артем.

On Sat, Feb 03, 2018 at 10:48:42PM -0500, Artem Smorodin wrote:
> Здравствуйте, обнаружил конфликт в работе модулей Dav и Mirror.
> 
>  Пример конфигурации, при которой Dav модуль всегда будет возвращать HTTP
> 500, причем без записи в лог:
> 
> location / {
>     root   /somedir;
> 	aio threads;
> 	
>     client_max_body_size 30m;
>     dav_access user:rw group:rw all:rw;
>     dav_methods PUT;
>     create_full_put_path on;
>     client_body_temp_path /somedir/temp 1 2;
> 	mirror /mirror/127.0.0.2:80;
> }
> 
> location ~* /mirror/(?<backend>.*) {	
> 	internal;
> 	client_max_body_size 0;
> 	proxy_pass http://$backend/$request_uri;
> 	proxy_ignore_client_abort on;
> 	proxy_buffering off; 
> 	proxy_method PUT;
> 	proxy_request_buffering off;
> 	proxy_connect_timeout 5s;
> }
> 
> 
>  Так происходит из-за того, что модуль ngx_http_dav_module, который работает
> в фазе NGX_HTTP_CONTENT_PHASE требует, чтобы тело запроса было сохранено во
> временный файл
> 
> r->request_body_in_file_only = 1;
> r->request_body_in_persistent_file = 1;
> r->request_body_in_clean_file = 1;
> r->request_body_file_group_access = 1;
> r->request_body_file_log_level = 0;
> 
> rc = ngx_http_read_client_request_body(r, ngx_http_dav_put_handler);
> 
> Однако модуль ngx_http_mirror_module, который работает в фазе
> NGX_HTTP_PRECONTENT_PHASE так же считывает содержимое тела запроса, но
> делает это раньше и с параметрами по умолчанию
> 
> Default: client_body_in_file_only off;
> 
> В итоге мы пытаемся повторно считать тело запроса, но метод
> ngx_http_read_client_request_body возвращает уже считанную информацию и
> проверка в методе ngx_http_dav_put_handler  не проходит.
> 
> static void
> ngx_http_dav_put_handler(ngx_http_request_t *r)
> {
> 
>     /****** some code here ******/
> 
>     if (r->request_body == NULL || r->request_body->temp_file == NULL) {
>         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
>         return;
>     }

В этом месте явно недоставало логгирования.  Теперь оно есть:

http://hg.nginx.org/nginx/rev/573f20116163

>  По идее, чтобы сохранить независимость модулей нужно реализовывать сброс
> считанного буфера в файл, но лично я решил проблему просто добавив
> директиву
> 
> client_body_in_file_only clean;

Да, решение выглядит правильным.

> Если я прав, добавьте, пожалуйста, эту информацию в документацию.

Да, стоит добавить.  Спасибо.

-- 
Roman Arutyunyan


Подробная информация о списке рассылки nginx-ru