Opened 6 years ago

Closed 6 years ago

#510 closed defect (wontfix)

DAV module COPY & MOVE can't handle regex destination URI

Reported by: Qiang Yu Owned by:
Priority: minor Milestone:
Component: nginx-module Version: 1.5.x
Keywords: DAV COPY MOVE Cc:
uname -a: Linux yuq-Vostro-270 3.2.0-54-generic-pae #82-Ubuntu SMP Tue Sep 10 20:29:22 UTC 2013 i686 i686 i386 GNU/Linux
nginx -V: configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/ --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --add-module=/home/yuq/code/nginx/nginx-1.5.10/debian/modules/nginx-dav-ext-module --with-http_spdy_module --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro' --with-ipv6


I configure NGINX to be a WebDAV server:

server {
listen 8283;

root /home;

charset utf-8;
create_full_put_path on;

dav_ext_methods PROPFIND OPTIONS;
dav_access user:rw group:rw all:r;

location / {
deny all;

location ~ ^/users/(\w+)(/.*)?$ {
alias /home/$1$2;
auth_basic "emNAS";
auth_basic_user_file /opt/emnas/etc/webdav/$;
autoindex on;

I tested COPY and MOVE not work. Track the code with GDB, the problem
is in function ngx_http_dav_copy_move_handler() which calls ngx_http_map_uri_to_path()
to map destination URI to destination path. But it map destination URI to source path.
So the MOVE does nothing, the COPY report file exists error.

For example,
MOVE http://localhost:8283/users/admin/aaa to http://localhost:8283/users/admin/bbb
results an FS op
RENAME /home/admin/aaa to /home/admin/aaa
which does nothing.

The wrong path from correct URI is generated by ngx_http_script_run().
ngx_http_dav_copy_move_handler() calls ngx_http_map_uri_to_path() first time
to convert source URI to source file path, then second time for destination URI.
It seems the previous regex capture result is not regenerated in the second run
of ngx_http_map_uri_to_path() within the same HTPP request.

Change History (3)

comment:1 by Ruslan Ermilov, 6 years ago

DAV module uses configuration matching the request URI to map both source and destination URIs to filenames. The problem with a location defined using regular expression is that captures ($1 and $2) used in alias are computed only once, when a matching location is looked up by a request URI, so alias computes the same filename for both source and destination URI.

See if regex location can be avoided. For example, instead of the quoted case, the following should work:

location /users/ {
    alias /home/;

in reply to:  1 comment:2 by Qiang Yu, 6 years ago

Replying to Ruslan Ermilov:

See if regex location can be avoided.

Thanks for your reply.

I think regex can not be avoided in my case, because of

auth_basic_user_file /opt/emnas/etc/webdav/$;

The username is extracted to specify an auth file for each user.

My WebDAV requirement:

  1. each user export their home dir (/home/username)
  2. each user can only auth to see their own dir location. but NUTTX does not have a APACHE like Require configure for using one htpasswd. So I have to create one for each user which contains the user only.

Can your suggestion or other method solve these needs?

Besides, is the alias-compute-once a BUG or expected action?

comment:3 by Maxim Dounin, 6 years ago

Resolution: wontfix
Status: newclosed

Regex location can be easily avoided by using a map, something like this should do the trick:

map $uri $user {
     "~^/users/(?<user>\w+)" $user;

An alternative aproach would be to use a single auth file and check username using the "if" check.

Note though that it may not be a good idea to allow COPY / MOVE in such a configuration, as COPY / MOVE can be done to any destination within the server{} (or, rather, under server's root). Authentication is checked on a source URI of a request, but not on destination.

As for alias, it's expected behaviour. Alias in regexp locations is rather limited and can't be used in many cases like this one.

Note: See TracTickets for help on using tickets.