在 NginX 后面安装的 Apache mod_dav 上,WebDav 重命名失败

在 NginX 后面安装的 Apache mod_dav 上,WebDav 重命名失败

我正在尝试解决通过 WebDav 重命名文件的问题。我们的堆栈由一台机器组成,通过 Nginx、Varnish 和 Apache 提供内容。当您尝试重命名文件时,我们当前使用的堆栈会失败。

要连接到 WebDav,客户端程序必须:

  1. 连接https://主机:443到 NginX
  2. NginX 解开包装并将请求转发到 Varnish 服务器http://本地主机:81
  3. Varnish 将请求转发给 Apachehttp://本地主机:82,通过 mod_dav 提供会话

以下是重命名失败的示例:

$ cadaver https://webdav.domain/
Authentication required for Webdav on server `webdav.domain':
Username: user
Password:

dav:/> cd sandbox
dav:/sandbox/> mkdir test
Creating `test': succeeded.

dav:/sandbox/> ls
Listing collection `/sandbox/': succeeded.
Coll:   test                                   0  Mar 12 16:00

dav:/sandbox/> move test newtest
Moving `/sandbox/test' to `/sandbox/newtest':  redirect to http://webdav.domain/sandbox/test/

dav:/sandbox/> ls
Listing collection `/sandbox/': succeeded.
Coll:   test                                   0  Mar 12 16:00

更多反馈:WebDrive Windows 客户端在重命名操作中记录了错误 502(网关错误)和 303(?)。扩展日志提供了以下信息:

目标 URI 引用不同的方案或端口(https://主机名:443) (想:http://主机名:82)。

其他一些限制:对 NginX 的 Webdav 模块的调查表明,它并不真正符合我们的需求,并且将 webdav 流量转发到 Apache 不是一个选择,因为我们不想启用 Apache SSL。

有什么方法可以欺骗 mod_dav 转发到另一台主机?我愿意听取意见 :)。

答案1

(回到我使用 Subversion 的日子)我在从 Nginx SSL 前端代理到 Apache SVN 时遇到了类似的问题。假设 Nginx SSL 前端是 https ://host ,我们想将连接代理到内部 Apache SVN 服务器 http ://svn

当您尝试复制带有标题的资源时,会出现问题Destination

COPY /path HTTP/1.1
Host: host
Destination: https://host/another_path

如您所见,Destination标题仍包含https架构。修复非常明显——

location / {
    # to avoid 502 Bad Gateway:
    # http://vanderwijk.info/Members/ivo/articles/ComplexSVNSetupFix
    set $destination $http_destination;

    if ($destination ~* ^https(.+)$) {
         set $destination http$1;
    }

    proxy_set_header Destination $destination;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;

    proxy_pass http://svn;
}

答案2

正如@Cnly所说,set如果原始标头和网址中都有特殊字符,则使用指令将不起作用Destination。(我不知道为什么)

我使用 map 指令来解决该问题。

http {
    map $http_destination $http_destination_webdav {
        ~*https://(.+) http://$1;
        default $http_destination;
    }

    server {
        # ...server settings...

        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Destination $http_destination_webdav;

            proxy_pass http://svn;
        }
    }
}

相关内容