如果想使用WebDAV来实现文件共享,尤其是想使用操作系统内置功能来挂载文件系统的话,省心的话还是用Apache吧。

下文介绍如何用Nginx来实现这个目标。Windows内置的客户端是Microsoft-WebDAV-MiniRedir,macOS是WebDAVFS Darwin,Linux是gvfs。

首先需要nginx-dav-ext-module,不然任何WebDAV客户端都无法工作,因为不支持PROPFIND指令无法列目录。Windows/macOS写文件需要LOCK指令,Linux不需要。

按照文档配置好了之后,挂载网络盘,OK,然后发现无法新建文件夹和重命名文件夹……没有一个操作系统能幸免……

下面介绍两种方法:

修改源代码自己编译

只要删代码就行了,不需要写任何新代码,这就导致你都不好意思向官方提BUG——不能用不是我的错,是Windows/macOS/Linux的错,它们不按规矩出牌。

ngx_http_dav_module.c

504行,判断MKCOL指令的uri必须用“/”结尾,最后传给操作系统层的时候去掉了“/”,实际上操作系统的mkdir函数能兼容“a”和“a/”两种格式。

Windows/macOS/Linux挂载后不能创建文件夹的原因。

    // if (r->uri.data[r->uri.len - 1] != '/') {
// ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
// "MKCOL can create a collection only");
// return NGX_HTTP_CONFLICT;
// } p = ngx_http_map_uri_to_path(r, &path, &root, );
if (p == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
} // *(p - 1) = '\0';
// r->uri.len--;

636行,判断MOVE指令的uri和Destination的结尾的“/”必须匹配,实际上操作系统的rename函数同样能兼容“a”和“a/”,并不能把文件改成文件夹。

macOS不能重命名文件夹的原因之一——uri以/结尾,Destination没有以/结尾。

 // if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/')
// || (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/'))
// {
// ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
// "both URI \"%V\" and \"Destination\" URI \"%V\" "
// "should be either collections or non-collections",
// &r->uri, &dest->value);
// return NGX_HTTP_CONFLICT;
// }

764行,如果MOVE的类型是文件夹的话,uri必须以“/”结尾,同上,操作系统的rename函数能够兼容。

Windows/Linux不能重命名文件夹的原因,macOS不能重命名文件夹的原因之二。

        // if (r->uri.data[r->uri.len - 1] != '/') {
// ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
// "\"%V\" is collection", &r->uri);
// return NGX_HTTP_BAD_REQUEST;
// }

改完之后重新编译,Windows/macOS/Linux挂载网络盘后就基本可用了。

但是Windows上,可以新建文件,上传文件依然不可用。Windows复制文件后固执的要把新文件的时间改成和原文件一样的,因为缺少PROPPATCH指令,无法完成这个操作就罢工了,macOS/Linux就不做这个操作。实际上Windows这个习性对make之类的靠文件时间来判断是否更新的工具很不友好,经常误判。用Apache做WebDAV的时候,有时我就发现上传新文件的时候无法触发更新脚本,就是因为上传的文件的时间落后于服务器时间。

有人提供了一个fake PROPPATCH实现,就是直接当成PROPFIND指令处理。在我看来比正确的实现还要好,可以避免Windows的固执行为带来的让人烦躁的错误。

配置文件

如果不想自己编译,用配置文件也是可以解决的。

MKCOL不以/结尾

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

Windows下MOVE文件夹不以/结尾

if (-d $request_filename) {
rewrite ^(.*[^/])$ $/;
set $md /;
}

重命名文件夹Destination不以/结尾,需要headers-more-nginx-module

set $x $http_destination$request_method;
if ($x ~ [^/]MOVE) {
more_set_input_headers -r "Destination: ${http_destination}${md}";
}

没有PROPPATCH指令,用PROPFIND处理。

proxy_method PROPFIND;
include proxy_params;
if ($request_method = PROPPATCH) {
proxy_pass http://127.0.0.1;
}

打完收工。

修复Nginx的WebDAV功能的更多相关文章

  1. Nginx range filter模块数字错误漏洞修复 (Nginx平滑升级) 【转】

    对线上生产环境服务器进行漏洞扫描, 发现有两台前置机器存在Nginx range filter模块数字错误漏洞, 当使用nginx标准模块时,攻击者可以通过发送包含恶意构造range域的header ...

  2. Nginx 状态信息功能配置

    Nginx 状态信息功能介绍 Nginx 有一个 ngx_http_stub_status_module 模块,主要功能是记录 Nginx 的基本访问状态信息,让使用者了解 Nginx 的工作状态 要 ...

  3. Nginx启动SSL功能

    Nginx启动SSL功能,并进行功能优化,你看这个就足够了 一:开始Nginx的SSL模块 1.1 Nginx如果未开启SSL模块,配置Https时提示错误 nginx: [emerg] the &q ...

  4. 启动Nginx目录浏览功能及 让用户通过用户名密码认证访问web站点

    一.启动Nginx目录浏览功能  [root@abcdocker extra]# cat w.conf server { listen 80; server_name IP地址; location / ...

  5. Nginx代理缓存功能

    Nginx代理缓存功能      Nginx缓存主要是用于减轻后端服务器的负载,提高网站并发量,提升用户体验度. 注意:Nginx反向代理的缓存功能是由ngx_http_proxy_module提供, ...

  6. Nginx 反向代理功能-动静分离

    Nginx 反向代理功能-动静分离 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  7. Nginx 反向代理功能-实现Nginx tcp负载均衡

    Nginx 反向代理功能-实现Nginx tcp负载均衡 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  8. Nginx 反向代理功能-实现http反向代理

    Nginx 反向代理功能-实现http反向代理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  9. Nginx Rewrite相关功能-防盗链

    Nginx Rewrite相关功能-防盗链 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

随机推荐

  1. 004.前端开发知识,前端基础CSS(2020-01-09)

    一.CSS字体样式属性 1.font-size:字号大小 2.font-family:字体 font-family属性用于设置字体.网页中常用的字体有宋体.微软雅黑.黑体等. * { /*font-f ...

  2. 002.前端开发知识,前端基础HTML(2020-01-07)

    一.列表标签 1.无序列表 ul <ul> <li>列表项1</li> <li>列表项2</li> <li>列表项3</l ...

  3. Windows下 webstorm安装tomcat配置svn并使用

    先附上所需要的软件的下载地址:https://pan.baidu.com/s/1c2ripd2 1.下载并安装jdk以及配置jdk的环境变量 1)下载jdk,选择安装目录安装,我选择的是默认路径,安装 ...

  4. supervisor安装与配置实践版

    应用场景 系统:centos7 需求:监控一个swooleWebSocket.php文件,程序使用的是8080端口,挂了自动被supervisor拉起来 一.首先要安装supervisor软件 yum ...

  5. [LC] 438. Find All Anagrams in a String

    Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings ...

  6. 蓝桥杯-PREV28-地宫取宝

    先自己用dp解了一遍,然后看了官方讲解视频是用记忆化搜索做的.感觉那位老师的方法比较容易实现(效率上和我的差不多的):记录一下三种方法. 动态规划 地宫取宝 1.195KB C++ 正确 100 15 ...

  7. deeplearning.ai 构建机器学习项目 Week 1 机器学习策略 I

    这门课是讲一些分析机器学习问题的方法,如何更快速高效的优化机器学习系统,以及NG自己的工程经验和教训. 1. 正交化(Othogonalization) 设计机器学习系统时需要面对一个问题是:可以尝试 ...

  8. Mybatis工作流程及其原理与解析

    Mybatis简介:    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBat ...

  9. Java完成生产者消费者模型

    生产者和消费者模型,是多线程中的典型模型,这里使用Java完成该模型 ServerTest.java 生产者代码 package com.orange.threadmodel; import java ...

  10. Nginx笔记总结六:Nginx location配置

    语法规则:location [= | ~ | ~* | ^~] /uri/ {....} = 表示精确匹配 ^~ 表示uri以某个常规字符串开头 ~ 表示区分大小写的正则表达式 ~* 表示不区分大小写 ...