我正在尝试使用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)将尝试打开WebSockets到这样的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
设置为On
或NoDecode
不会改变这一点。 (据我所知,这只会影响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的问题?
答案 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