lolly/docs/nginx/37-nginx-dav-module.md
xfy 972eab4267 refactor(docs): 重构文档目录结构,nginx 文档移至子目录
将 docs/ 根目录下的 nginx 相关文档统一移动到 docs/nginx/ 子目录,
提高文档组织性和可维护性。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 10:48:14 +08:00

688 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nginx WebDAV 模块完整指南
## 1. WebDAV 模块概述
### 1.1 模块简介
`ngx_http_dav_module` 是 Nginx 的文件管理自动化模块,通过 WebDAV (Web Distributed Authoring and Versioning) 协议支持远程文件操作。
### 1.2 主要用途
- 文件上传与管理
- 远程文件编辑
- 目录结构创建
- 文件复制与移动
- 简单的文件服务器
### 1.3 编译要求
该模块**不会默认构建**,需要在编译时显式启用:
```bash
./configure --with-http_dav_module
```
### 1.4 支持的 HTTP 方法
| 方法 | 说明 |
|------|------|
| `PUT` | 上传/创建文件 |
| `DELETE` | 删除文件或目录 |
| `MKCOL` | 创建目录 (Make Collection) |
| `COPY` | 复制文件或目录 |
| `MOVE` | 移动文件或目录 |
> **注意**Nginx WebDAV 模块仅支持上述 5 种方法。需要其他 WebDAV 方法(如 PROPFIND、PROPPATCH、OPTIONS、LOCK、UNLOCK的客户端将无法与此模块配合工作。
---
## 2. 指令详解
### 2.1 dav_methods
启用指定的 HTTP 方法。
**语法:**
```nginx
dav_methods off | PUT | DELETE | MKCOL | COPY | MOVE ...;
```
**默认值:** `off`
**上下文:** `http`, `server`, `location`
**说明:**
- `off` - 禁止此模块的所有方法
- 可以指定一个或多个方法
- 未列出的方法将被禁止
**示例:**
```nginx
# 仅启用 PUT 和 DELETE
dav_methods PUT DELETE;
# 启用全部支持的方法
dav_methods PUT DELETE MKCOL COPY MOVE;
# 禁用所有 WebDAV 方法
dav_methods off;
```
---
### 2.2 create_full_put_path
允许创建所有必需的中间目录。
**语法:**
```nginx
create_full_put_path on | off;
```
**默认值:** `off`
**上下文:** `http`, `server`, `location`
**说明:**
- WebDAV 规范通常要求目标目录必须已存在
- 设置为 `on`PUT 请求可以自动创建路径中的所有中间目录
- 对于深度嵌套的文件上传非常有用
**示例:**
```nginx
# 允许 PUT /files/a/b/c/file.txt 自动创建 a/b/c/ 目录
create_full_put_path on;
```
---
### 2.3 dav_access
设置新创建的文件和目录的访问权限。
**语法:**
```nginx
dav_access users:permissions ...;
```
**默认值:** `user:rw`
**上下文:** `http`, `server`, `location`
**权限格式:**
```
user:permissions # 文件所有者权限
group:permissions # 组权限
all:permissions # 所有用户权限
```
**权限值:**
- `r` - 读
- `w` - 写
- `x` - 执行(目录为进入)
**示例:**
```nginx
# 默认:用户可读写
dav_access user:rw;
# 用户读写,组读,其他用户只读
dav_access user:rw group:r all:r;
# 用户完全权限,组读执行,其他无权限
dav_access user:rwx group:rx all:;
# 多组权限
dav_access group:rw all:r;
```
---
### 2.4 min_delete_depth
设置 DELETE 操作允许删除的最小路径深度。
**语法:**
```nginx
min_delete_depth number;
```
**默认值:** `0`
**上下文:** `http`, `server`, `location`
**说明:**
- 用于防止意外删除重要目录
- 路径深度计算以 `/` 分隔的元素数量
- 请求 URI 的元素数量必须 >= 设定值才能执行 DELETE
**示例:**
```nginx
# 至少需要 4 层深度才能删除
min_delete_depth 4;
# 允许删除DELETE /users/00/00/name (4 层)
# 禁止删除DELETE /users/00/00 (3 层)
```
---
## 3. 配置示例
### 3.1 基础文件共享服务器
```nginx
server {
listen 80;
server_name dav.example.com;
location / {
# 根目录
root /data/www;
# 临时文件目录(与根目录同一文件系统以获得最佳性能)
client_body_temp_path /data/client_temp;
# 启用 WebDAV 方法
dav_methods PUT DELETE MKCOL COPY MOVE;
# 允许创建中间目录
create_full_put_path on;
# 设置文件权限
dav_access group:rw all:r;
# 限制写操作的访问
limit_except GET {
allow 192.168.1.0/24;
deny all;
}
}
}
```
### 3.2 只读文件服务器(带选择性上传)
```nginx
server {
listen 80;
server_name files.example.com;
# 公共只读区域
location /public/ {
root /data/files;
dav_methods off; # 禁止写操作
autoindex on; # 启用目录列表
}
# 受限上传区域
location /uploads/ {
root /data/files;
dav_methods PUT DELETE;
dav_access user:rw;
# 仅允许特定 IP 上传
limit_except GET {
allow 10.0.0.0/8;
deny all;
}
}
}
```
### 3.3 支持深度目录的上传服务
```nginx
server {
listen 80;
server_name upload.example.com;
location /storage/ {
root /data/storage;
dav_methods PUT DELETE MKCOL;
create_full_put_path on; # 自动创建嵌套目录
dav_access user:rw group:r;
# 防止删除顶层目录
min_delete_depth 3;
# 限制请求体大小
client_max_body_size 100M;
# 限制写操作
limit_except GET PUT {
allow 192.168.0.0/16;
deny all;
}
}
}
```
### 3.4 带认证的 WebDAV 服务
```nginx
server {
listen 80;
server_name secure-dav.example.com;
location / {
root /data/secure;
dav_methods PUT DELETE MKCOL COPY MOVE;
create_full_put_path on;
dav_access user:rw;
# HTTP 基本认证
auth_basic "WebDAV Access";
auth_basic_user_file /etc/nginx/.dav_passwd;
# 限制客户端大小
client_max_body_size 500M;
}
}
```
生成密码文件:
```bash
htpasswd -c /etc/nginx/.dav_passwd username
```
### 3.5 带 SSL 的 WebDAV 服务器
```nginx
server {
listen 80;
server_name dav.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name dav.example.com;
ssl_certificate /etc/nginx/ssl/dav.crt;
ssl_certificate_key /etc/nginx/ssl/dav.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
root /data/www;
dav_methods PUT DELETE MKCOL COPY MOVE;
create_full_put_path on;
dav_access user:rw group:r all:r;
client_max_body_size 1G;
}
}
```
---
## 4. 客户端使用指南
### 4.1 使用 curl
```bash
# 上传文件PUT
curl -T localfile.txt http://dav.example.com/remotefile.txt
# 创建目录MKCOL
curl -X MKCOL http://dav.example.com/newdir/
# 删除文件DELETE
curl -X DELETE http://dav.example.com/file.txt
# 复制文件COPY
curl -X COPY -H "Destination: http://dav.example.com/copy.txt" \
http://dav.example.com/original.txt
# 移动文件MOVE
curl -X MOVE -H "Destination: http://dav.example.com/moved.txt" \
http://dav.example.com/original.txt
# 带认证上传
curl -T file.txt -u username:password \
http://dav.example.com/file.txt
# 查看文件内容GET
curl http://dav.example.com/file.txt
# 列出目录内容(需要客户端支持 PROPFIND
curl -X PROPFIND http://dav.example.com/
```
### 4.2 使用 cadaver命令行 WebDAV 客户端)
```bash
# 安装
# Debian/Ubuntu
apt-get install cadaver
# macOS
brew install cadaver
# 连接
cadaver http://dav.example.com/
# cadaver 常用命令
dav:> ls # 列出目录
dav:> cd directory # 进入目录
dav:> put file.txt # 上传文件
dav:> get file.txt # 下载文件
dav:> mkdir newdir # 创建目录
dav:> rm file.txt # 删除文件
dav:> mv old new # 移动/重命名
dav:> quit # 退出
```
### 4.3 使用 GNOME Nautilus文件管理器
1. 打开 Nautilus 文件管理器
2.`Ctrl+L` 或选择"其他位置"
3. 输入地址:`dav://dav.example.com/`
4. 输入凭据(如需要)
5. 可像本地文件夹一样操作
### 4.4 挂载为本地文件系统Linux
使用 davfs2
```bash
# 安装
apt-get install davfs2
# 挂载
mount -t davfs http://dav.example.com/ /mnt/webdav
# 或使用 /etc/fstab 自动挂载
http://dav.example.com/ /mnt/webdav davfs user,noauto 0 0
```
### 4.5 Windows 资源管理器
1. 打开"此电脑"
2. 右键 -> "添加网络位置"
3. 输入:`http://dav.example.com/`
4. 完成向导
或使用 `net use`
```cmd
net use * http://dav.example.com/
```
### 4.6 macOS Finder
1. Finder -> "前往" -> "连接服务器"
2. 输入:`http://dav.example.com/`
3. 点击"连接"
---
## 5. 与 Lolly 项目的关系
### 5.1 Lolly 项目概述
Lolly 是一个用 Go 编写的高性能 HTTP 服务器/代理工具,提供:
- 灵活的路由和重写规则
- 中间件支持
- 反向代理功能
- 性能分析工具pprof
### 5.2 与 Nginx WebDAV 的对比
| 特性 | Nginx WebDAV | Lolly |
|------|--------------|-------|
| 协议支持 | WebDAV (有限) | 标准 HTTP |
| 配置方式 | 声明式配置 | Go 代码 |
| 扩展性 | 需重新编译 | 热插拔中间件 |
| 性能分析 | 第三方模块 | 内置 pprof |
| 学习曲线 | 低 | 中(需 Go 基础) |
### 5.3 建议与集成方案
#### 方案一Nginx + Lolly 组合架构
```
客户端 -> Nginx (WebDAV/静态文件) -> Lolly (动态请求/代理)
```
```nginx
server {
listen 80;
server_name example.com;
# WebDAV 文件存储
location /dav/ {
root /data/storage;
dav_methods PUT DELETE MKCOL;
create_full_put_path on;
dav_access user:rw group:r;
}
# 动态请求代理到 Lolly
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 静态文件由 Nginx 直接服务
location /static/ {
root /data/www;
expires 30d;
}
}
```
#### 方案二Lolly 实现类似 WebDAV 功能
如需在 Lolly 中实现类似 WebDAV 的文件上传功能,可参考以下思路:
```go
// 概念示例 - 实际实现请参考 Lolly 代码
router.PUT("/files/*filepath", func(c *gin.Context) {
filepath := c.Param("filepath")
fullPath := "/data/storage/" + filepath
// 创建中间目录(类似 create_full_put_path on
os.MkdirAll(path.Dir(fullPath), 0755)
// 保存上传的文件
c.SaveUploadedFile(file, fullPath)
// 设置权限(类似 dav_access
os.Chmod(fullPath, 0644)
c.Status(http.StatusCreated)
})
router.DELETE("/files/*filepath", func(c *gin.Context) {
filepath := c.Param("filepath")
fullPath := "/data/storage/" + filepath
// 检查深度(类似 min_delete_depth
depth := len(strings.Split(filepath, "/"))
if depth < 4 {
c.JSON(http.StatusForbidden, gin.H{"error": "path too shallow"})
return
}
os.Remove(fullPath)
c.Status(http.StatusNoContent)
})
```
#### 方案三Lolly 作为 WebDAV 后端代理
```nginx
location /webdav/ {
# 认证和限流在 Nginx 层处理
auth_basic "WebDAV";
auth_basic_user_file /etc/nginx/.passwd;
# 限流
limit_req zone=webdav burst=10;
# 代理到 Lolly
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Destination $http_destination;
}
```
### 5.4 选择建议
| 场景 | 推荐方案 |
|------|----------|
| 简单文件共享 | Nginx WebDAV |
| 需要复杂业务逻辑 | Lolly |
| 高性能静态文件 | Nginx |
| 需要自定义协议扩展 | Lolly |
| 快速部署 | Nginx WebDAV |
| 深度集成应用 | Lolly |
---
## 6. 性能优化建议
### 6.1 文件系统建议
**强烈推荐**:临时目录和数据目录使用**同一文件系统**。
```nginx
location / {
root /data/www; # 数据目录
client_body_temp_path /data/client_temp; # 临时目录(同文件系统)
dav_methods PUT DELETE;
}
```
**原因:**
- 同文件系统:文件上传使用 `rename()` 系统调用(原子操作,极快)
- 不同文件系统:文件上传需要 `copy + delete`(慢,占用双倍空间)
### 6.2 客户端大小限制
```nginx
# 限制上传文件大小,防止资源耗尽
client_max_body_size 100M;
# 调整缓冲区
client_body_buffer_size 128k;
```
### 6.3 超时设置
```nginx
# WebDAV 操作可能需要较长时间
client_body_timeout 300s;
send_timeout 300s;
```
---
## 7. 故障排查
### 7.1 常见问题
| 问题 | 可能原因 | 解决方案 |
|------|----------|----------|
| 405 Method Not Allowed | 方法未启用 | 检查 `dav_methods` 配置 |
| 403 Forbidden | 权限不足或 IP 限制 | 检查 `dav_access``limit_except` |
| 409 Conflict | 目录不存在 | 设置 `create_full_put_path on` |
| 423 Locked | 文件被锁定 | Nginx 不支持锁,换客户端 |
| 500 Internal Error | 路径过深或循环 | 检查 `min_delete_depth` |
### 7.2 启用调试日志
```nginx
error_log /var/log/nginx/error.log debug;
```
查看日志:
```bash
tail -f /var/log/nginx/error.log | grep dav
```
### 7.3 验证配置
```bash
# 测试配置文件语法
nginx -t
# 重新加载配置
nginx -s reload
```
---
## 8. 完整配置模板
```nginx
# /etc/nginx/conf.d/webdav.conf
server {
listen 80;
server_name dav.example.com;
# 访问日志
access_log /var/log/nginx/webdav_access.log;
error_log /var/log/nginx/webdav_error.log;
# 客户端限制
client_max_body_size 500M;
client_body_buffer_size 128k;
client_body_timeout 300s;
send_timeout 300s;
location / {
# 根目录
root /data/webdav;
# 临时目录(与根目录同文件系统)
client_body_temp_path /data/webdav_tmp;
# 启用 WebDAV 方法
dav_methods PUT DELETE MKCOL COPY MOVE;
# 允许自动创建中间目录
create_full_put_path on;
# 文件权限设置
dav_access user:rw group:r all:r;
# 防止误删顶层目录
min_delete_depth 2;
# HTTP 基本认证
auth_basic "WebDAV Repository";
auth_basic_user_file /etc/nginx/.webdav_passwd;
# 访问控制
limit_except GET {
# 允许内网
allow 192.168.0.0/16;
allow 10.0.0.0/8;
allow 127.0.0.1;
# 拒绝其他
deny all;
}
# 目录列表(可选)
autoindex on;
autoindex_format html;
autoindex_localtime on;
}
}
```
---
## 9. 参考资源
- [Nginx 官方文档 - ngx_http_dav_module](https://nginx.org/en/docs/http/ngx_http_dav_module.html)
- [WebDAV RFC 4918](https://tools.ietf.org/html/rfc4918)
- [cadaver 客户端](http://www.webdav.org/cadaver/)
- [davfs2 - Linux WebDAV 挂载](http://savannah.nongnu.org/projects/davfs2/)