Collabora“未知资源”,因为Apache mod_rewrite代理unescaping%2F斜杠

时间:2016-12-22 16:21:26

标签: apache mod-rewrite url-encoding mod-proxy

我正在尝试使用Apache 2.4设置反向代理。

看起来我不能直接使用可怕的mod_proxy,因为它不支持websockets(除非为每个URL手动配置),所以我必须使用可怕的可怕mod_rewrite。< / p>

到目前为止,我的配置如下所示:

<VirtualHost *:80>
    ServerName collabora.example.com
    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} =websocket
    RewriteRule ^(/.*)?$ wss://collabora-backend$1 [P]
    RewriteCond %{HTTP:Upgrade} !=websocket
    RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/?
    RewriteRule ^(/.*)?$ https://collabora-backend$1 [P]
</VirtualHost>

我正在尝试运行的一个应用程序(可怕的Collabora Online in combination with NextCloud)将尝试打开W​​ebSockets到这样的URL:ws://collabora.example.com/lool/https%253A%252F%252Fcloud.example.com%252Fapps%252Frichdocuments%252Fwopi%252Ffiles%252F51040%3Faccess_token%3DABCDEF%26permission%3Dedit/ws。遗憾的是,通过上述配置,这些网址将在后端到达,所有%25部分都已解码为%(以及其他部分):ws://collabora.example.com/lool/https%3A%2F%2Fcloud.example.com%2Fapps%2Frichdocuments%2Fwopi%2Ffiles%2F51040?access_token=ABCDEF&permission=edit/ws

Collabora将报告如下错误消息:

wsd-00026-0195 0:01:27.448231 [ client_ws_0003 ] ERR Unknown resource: /lool//ws/lool/https%253A%252F%252Fowncloud.mydomain.fr%252Findex.php%252Fapps%252Frichdocuments%252Fwopi%252Ffiles%252F5%3Faccess_token=R...c&permission=edit/ws| LOOLWSD.cpp:1154

并且WebSocket连接将在浏览器中出现400 Bad Request错误时失败。

AllowEncodedSlashes设置为OnNoDecode不会改变这一点。 (据我所知,这只会影响PATH_INFO的价值。)

通过RewriteRule flags阅读,[B]标志似乎与我的问题有关。在那里它说“mod_rewrite必须在映射它们之前对其进行unescape”(我假设这是最大化烦恼的唯一原因),因此[B]标志将在映射后再次重新转义它们。这当然在这种情况下不起作用,并且将逃脱所有斜线,甚至是那些之前未被转义的斜杠:"ws://collabora.example.com%2Flool%2Fhttps%253A%252F%252Fcloud.example.com%252Fapps%252Frichdocuments%252Fwopi%252Ffiles%252F51040%3Faccess_token%3DABCDEF%26permission%3Dedit%2Fws"

有没有办法解决这个问题,或者这是我最终必须彻底摆脱Apache的问题?

3 个答案:

答案 0 :(得分:0)

此区域的一个技巧是使用%{THE_REQUEST}的捕获而不是反向引用,因为它将使用请求原始编码,例如:

<VirtualHost *:80>
    ServerName collabora.example.com
    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} =websocket
    RewriteCond %{THE_REQUEST} "^GET /(.*) HTTP/1.?$"
    RewriteRule ^(/.*)?$ wss://collabora-backend/%1 [P]
    RewriteCond %{HTTP:Upgrade} !=websocket
    RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/?
    RewriteRule ^(/.*)?$ https://collabora-backend$1 [P]
</VirtualHost>

我只添加了捕获的新条件,并将$ 1更改为%1。我只是经过桌面检查,但我怀疑它只会通过一些小的调整来解决你的编码问题。

答案 1 :(得分:0)

根据covener的回答,我现在提出了以下有效的配置:

<VirtualHost *:80>
    ServerName collabora.example.com
    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteCond %{THE_REQUEST} "^[a-zA-Z]+ /(.*) HTTP/\d+(\.\d+)?$"
    RewriteRule .? wss://collabora-backend/%1 [P,NE]
    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
    RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/?
    RewriteCond %{THE_REQUEST} "^[a-zA-Z]+ /(.*) HTTP/\d+(\.\d+)?$"
    RewriteRule .? https://collabora-backend/%1 [P,NE]
</VirtualHost>

我调整了covener的答案来支持所有类型的HTTP请求,我不得不添加NE标志(否则请求URI将再次被转义)。

答案 2 :(得分:0)

Collabora更新了文档,我遇到了同样的问题。

所以有一个更好的解决方案(在https://www.collaboraoffice.com/code/找到)

  AllowEncodedSlashes NoDecode
  ProxyPassMatch "/lool/(.*)/ws$" wss://127.0.0.1:9980/lool/$1/ws nocanon