Why use this WebDAV Nginx server?

This server is a single Nginx module attempting to be a fully-fledged WebDAV server in C. It's a fork of existing projects aiming to fix issues they had and merge the codebases. Specifically the goals of this project are:

  • extremely easy setup configuration

  • don't ruin the filesystem, the server filesystem looks like just as it does as a WebDAV mount, copy your files in or out and you're good to go

  • APIs lenient enough to work with all clients in contrast to the native Nginx webdav module

  • WebDAV PROPPATCH method, ideally by calling the server itself to ensure proper function

  • <d:getetag /> checksums for more robust client syncing, the checksums are saved in a file based db in each folder* see below

  • optional locking and unlocking in redis for clusters

  • support of <d:creationdate /> **check the section below

  • support of <d:getcontenttype /> copy the source code of mime.types into the code and use it to discern the content type

  • support of <d:getcontentlanguage /> "en" or dont implement

  • support of <d:quota-available-bytes /> and <d:quota-used-bytes /> used through btrfs apis

  • functional testing suite

* <d:getetag />

There are two choices in order to generate the hash: ngx_hash and the xxhash library. There are also two choices for the storage of the hashes: redis with hiredis (with persistence) and a berkeleydb(https://github.com/berkeleydb/libdb) file named .checksums in each folder.

** <d:creationdate />

To get the creation date of a file ctime(&sb.st_ctime)) can be used (check out man 2 stat). But ctime does not represent file creation time but metadata change (eg inode changes such as hard links). To implement this feature two choices are available, either a .creationtimes database file in each folder that keeps track of the creation time of each file or depending on the crtime api that is supported by some filesystems and keeps track of the birth time of the file.

Was this written from zero?

The native nginx dav_module has been integrated with a few changes for client compatibility. This solves some very difficult problems with client compatibility:

  • trailing slash issues for DELETE requests uris

  • trailing slash issues for MOVE and COPY requests uris and destination headers

  • trailing slash issues for MKCOL request uris

The community nginx_dav_ext_module is integrated as well for proper full WebDAV support.

Usage

There are a few reasonable ways of setting it up.

  1. Standalone mode with authentication
    location / {
        auth_basic           "My closed site, go away!";
        auth_basic_user_file /usr/share/nginx/htpasswd;

        client_body_temp_path /var/nginx/webdav_client_temp;
        webdav_methods PUT DELETE MKCOL COPY MOVE PROPFIND OPTIONS LOCK UNLOCK;
        create_full_put_path  on;
        webdav_access            all:rw;
        webdav_lock zone=foo;

        root   /var/nginx/webdav;
        index  index.html index.htm;
    }
  1. Managed mode with subrequest full cloud functionality with starfields-cloud
    location / {
        auth_request    /cloud/auth/;

        client_body_temp_path /var/nginx/webdav_client_temp;
        webdav_methods PUT DELETE MKCOL COPY MOVE PROPFIND OPTIONS LOCK UNLOCK;
        create_full_put_path  on;
        webdav_access            all:rw;
        webdav_lock zone=foo;

        root   /var/nginx/webdav;
        index  index.html index.htm;
    }

    location = /cloud/auth/ {
        internal;

        proxy_pass_request_headers on;
        proxy_pass_request_body on;
        proxy_set_header X-Original-Method $request_method;
        proxy_set_header X-Original-URI $request_uri;
        proxy_pass  http://localhost:8000/api/v1/cloud/auth/;

        # OR
        # include uwsgi_params;
        # uwsgi_pass_request_headers on;
        # uwsgi_pass_request_body on;
        # uwsgi_param HTTP_X_AUTHORIZATION '$http_authorization';
        # uwsgi_param HTTP_X_ORIGINAL_METHOD '$request_method';
        # uwsgi_param HTTP_X_ORIGINAL_URI '$request_uri';
        # uwsgi_pass unix:/path/to/my/django.sock;
    }

Directives

Directive Specification Context Description
webdav_methods [GET] [PUT] [MKCOL] [DELETE] [PROPFIND] [OPTIONS] [LOCK] [UNLOCK] http, server, location Allowed HTTP methods
create_full_put_path (on | off) http, server, location Whether to allow creating all needed intermediate directories during an PUT request
webdav_access users:permissions http, server, location Sets access permissions for newly created files and directories
min_delete_depth number (0 | 1 | 2 | ...) http, server, location Allows the DELETE method to remove files provided that the number of elements in a request path is not less than the specified number
webdav_lock dav_ext_lock zone=NAME http, server, location Enables WebDAV locking in the specified scope
webdav_lock_zone zone=NAME:SIZE [timeout=TIMEOUT] http Defines a shared zone for WebDAV locks with specified NAME and SIZE. Also, defines a lock expiration TIMEOUT. Default lock timeout value is 1 minute.

Building

  1. After cloning this repository in $gitdir clone the nginx source code in $gitdir/nginx

  2. cd $gitdir/nginx

  3. ./configure --add-dynamic-module=../../nginx-sf-webdav-module/' --with-compat

  4. make

  5. then the module is in $gitdir/nginx/objs/ngx_http_webdav_module.so

to compile the module statically just replace --add-dynamic-module with --add-module

Requirements

  • nginx version >= 1.13.4

  • libxml2 + libxslt

The libxslt library is technically redundant and is only required since this combination is supported by nginx for the xslt module. Using builtin nginx mechanisms for linking against third-party libraries brings certain compatibility benefits. However this redundancy can be easily eliminated in the config file.

Locking

  • Only the exclusive write locks are supported, which is the only type of locks described in the WebDAV specification.

  • All currently held locks are kept in a list. Checking if an object is constrained by a lock requires O(n) operations. A huge number of simultaneously held locks may degrade performance. Thus it is not recommended to have a large lock timeout which would increase the number of locks.

Testing

TODO

Thumbnails and WebDAV SEARCH

We believe that all the users of Cloud Storage services should encrypt their data with tools such as gocryptfs available through KDE and GNOME Vault tools. As far as we are concerned is the only way Cloud Storage can be used. One of the results is that the data resting on the server are encrypted and therefore a binary mess, attempting to get thumbnails and indexing them for WebDAV SEARCH is not possible. We have therefore concluded that these two features will not be implemented at this point in time. Missing these features is not a problem, nothing stops file browsers thumbnailing and indexing the directories over time. In fact this creates a much better user experience.

Description
A module that provides full WebDAV support to Nginx.
Readme 79 KiB
2024-04-16 09:26:08 +00:00
Languages
C 90.1%
Python 9.9%