webdav可以通过HTTP协议对 Web 服务器进行文件读写,并支持文件的版本控制和写文件的加锁及解锁等操作,各平台都有客户端,支持的软件也多,对于没有复杂需求的跨平台网盘,是一个不错的选择。

一、所需模块

  1. ngx_http_dav_module: nginx自带模块,默认未启用,支持webdav的PUT、DELETE、 MKCOL、COPY、MOVE等基础的方法
  2. nginx-dav-ext-module: 提供了额外的PROPFIND、OPTIONS、LOCK、UNLOCK方法支持
  3. headers-more-nginx-module: IOS、windows等默认客户端使用COPY、MOVE等方法时,$http_destination中的URI没有带上"/",导致出现无法删除、重命名文件或文件夹等错误,该模块可以修复该错误,兼容更多的客户端
  4. ngx_http_auth_basic_module:提供基础的用户验证

二、安装依赖及编译

我用的是openresty,默认已经编译了headers-more-nginx-module,nginx默认就已经启用了ngx_http_auth_basic_module,所以编译时只需在原参数后启用http_dav_module及nginx-dav-ext-module及可,先解决openresty和nginx-dav-ext-module模块的依赖关系。

2.1 安装nginx-dav-ext-module 的依赖

dnf install libxml2  libxslt

2.2 安装 openresty 相关依赖

dnf install pcre-devel zlib-devel openssl-devel  gcc gcc-c++ make 

2.3 下载 openresty 和 nginx-dav-ext-module

wget https://openresty.org/download/openresty-1.19.9.1.tar.gz
git clone https://github.com/arut/nginx-dav-ext-module

2.4 编译 openresty

在原有的编译参数后启用 dav 相关的模块:

./configure --prefix=/opt/openresty/ --with-threads --with-http_ssl_module \
--with-http_v2_module --with-http_realip_module --with-http_addition_module \
--with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module \
--with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module\ --with-http_slice_module --with-http_stub_status_module --with-stream --with-stream_ssl_module\ --with-stream_ssl_preread_module  --with-http_flv_module  --with-http_mp4_module \
--with-http_sub_module  --with-http_slice_module  --with-http_stub_status_module \
--with-http_dav_module  --add-module=../nginx-dav-ext-module/

三、配置nginx的dav模块

3.1 nginx配置文件

#在 http 段加入,mac 客户端需要启用锁支持
dav_ext_lock_zone zone=webdav:10m;

server {
    listen 80;
    listen 443 ssl http2;

    server_name 
          dav.nixops.me
          ;

    access_log logs/dav_access.log main;
    error_log  logs/dav_error.log;

    ssl_certificate  "/opt/openresty/nginx/conf/vhosts/keys/nixops.me.crt";
    ssl_certificate_key "/opt/openresty/nginx/conf/vhosts/keys/nixops.me.key";


    location / {

        #设置webdav目录,注意Nginx worker用户对该目录需有读写权限
        root /opt/webdav;

        auth_basic "Private Site";
        auth_basic_user_file /opt/openresty/nginx/conf/vhosts/dav.pass;

        charset utf-8;
        autoindex on;
        autoindex_localtime on;
        autoindex_exact_size off; 
        
        #不限制文件大小
        client_max_body_size 0;

        #启用完整的创建目录支持,默认情况下,Put 方法只能在已存在的目录里创建文件
        create_full_put_path  on;
        dav_access user:rw group:rw all:r;
        
        
        #为各种方法的URI后加上斜杠,解决各平台webdav客户端的兼容性问题
        set $dest $http_destination;
        if (-d $request_filename) {
            rewrite ^(.*[^/])$ $1/;
            set $dest $dest/;
        }

        if ($request_method ~ (MOVE|COPY)) {
            more_set_input_headers 'Destination: $dest';
        }

        if ($request_method ~ MKCOL) {
            rewrite ^(.*[^/])$ $1/ break;
        }

        #支持所有方法
        dav_methods PUT DELETE MKCOL COPY MOVE;
        dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK;
        dav_ext_lock zone=webdav;
    }
}

3.2 设置webdav用户和密码

有两种方式,第一种使用openssl:

printf "nixops:$(openssl passwd      -crypt nixops.me)\n" >>/opt/openresty/nginx/conf/vhosts/dav.pass

第二种使用htpasswd命令,需要安装httpd-tools工具:

htpasswd -b -c /opt/openresty/nginx/conf/vhosts/dav.pass nixops nixops.me

经过以上配置,webdav就可以完美兼容mac、IOS(documents app)、windows及linux客户端了

四、测试

mac、IOS(documents app)、windows及linux客户端下连接webdav的方法就不介绍了。只说一下使用curl命令的测试方法,方便在shell脚本中使用webdav。

webdav支持以下方法:

  • OPTIONS : 检索服务
  • GET :获取文件
  • PUT、POST : 上传文件
  • DELETE : 删除文件或集合
  • COPY : 复制文件
  • MOVE : 移动文件
  • MKCOL : 创建由一个或多个文件 URI 组成的新集合
  • PROPFIND : 获取属性(创建日期、文件作者等),实现文件的查找与管理
  • LOCK、UNLOCK : 添加、删除文件锁,实现写操作保护

使用curl 测试时,URI后面一定要带'/',不然就会报错

创建目录:

curl -X MKCOL -u USER:PASSWORD https://dav.nixops.me/test/ 

上传文件:

curl -T FILE -u USER:PASSWORD  https://dav.nixops.me/test/

改名:

curl -X MOVE -u USER:PASSWORD --header 'Destination:https://dav.nixops.me/test/newname' https://dav.nixops.me/test/File 

删除:

curl -X DELETE -u USER:PASSWORD  https://dav.nixops.me/test/File 

五、其它的一些设置

Mac挂载webdav后会自动写入很多文件,可以通过nginx配置屏蔽掉,保持webdav目录的干净

location ~ \.(_.*|DS_Store|Spotlight-V100|TemporaryItems|Trashes|hidden|localized)$ {
    access_log  off;
    error_log   off;

    if ($request_method = PUT) {
        return 403;
    }
    return 404;
}

location ~ \.metadata_never_index$ {
    return 200 "Don't index this drive, Finder!";
}

参考文章:
http://www.weixueyuan.net/a/738.html
https://www.robpeck.com/2020/06/making-webdav-actually-work-on-nginx/