如果想使用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;
}

打完收工。

最新文章

  1. Python 3.X简史——记录3.0之后的重要更新
  2. linux下不同服务器间数据传输(rcp,scp,rsync,ftp,sftp,lftp,wget,curl)(zz)
  3. tomcat 8在win8.1中的配置
  4. #winhec# 开发人员刷屏看点 (视频)
  5. cvBox2D和RotatedRect中返回的角度angle详解
  6. 安装Ubuntu 14.04后要做的5件事情
  7. Android 再按一次退出程序
  8. javascript 延时执行函数
  9. 在ASP.NET Core下使用SignalR技术
  10. javaScript额外笔记
  11. 【python3之文件操作】
  12. 支持老版本IE的3种解决方案
  13. ss-R:// 链接的含义
  14. Python数据分析Pandas库数据结构(一)
  15. 深度学习原理与框架-Tensorflow卷积神经网络-cifar10图片分类(代码) 1.tf.nn.lrn(局部响应归一化操作) 2.random.sample(在列表中随机选值) 3.tf.one_hot(对标签进行one_hot编码)
  16. 【Java并发编程】9、非阻塞同步算法与CAS(Compare and Swap)无锁算法
  17. transform顺序浅谈
  18. HDU 1711Number Sequence【KMP模板题】
  19. hashCode方法的作用?
  20. MySQL的sql_mode解析与设置,sql文件导入报错解决

热门文章

  1. 常见字体图标库——font-awesome
  2. AppCompatActivity 透明背景
  3. linux上安装 mysql
  4. android采用MVP完整漫画APP、钉钉地图效果、功能完善的音乐播放器、仿QQ动态登录效果、触手app主页等源码
  5. android手机卫士、3D指南针、动画精选、仿bilibli客户端、身份证银行卡识别等源码
  6. Hadoop_ssh免密认证出现的问题
  7. ArcGIS Server10.2忘记密码怎么办?重置ArcGIS Server Manager密码
  8. MySQL中的GIS几何函数和空间分析函数
  9. mysqli存储过程
  10. ReentrantLock(重入锁)的源码解析