我正在尝试使用Apache 2.4的反向代理。
看起来我不能直接使用可怕的mod_proxy
,因为它不支持WebSocket(除非为每个URL手动配置),因此我必须使用可怕的可怕mod_rewrite
。
到目前为止,我的配置如下:
<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>
我试图运行的一个应用程序(可怕的concomplora Online与NextCloud结合使用)将尝试为这样的URL打开WebSocket:ws://collabora.example.com/lool/https%253A%252F%252Fcloud.example.com%252Fapps%252Frichdocuments%252Fwopi%252Ffiles%252F51040%3Faccess_token%3DABCDEF%26permission%3Dedit/ws
。不幸的是,使用上面的配置,这些URL将以解码为%
的所有%25
零件(以及其他)到达后端:ws://collabora.example.com/lool/https%3A%2F%2Fcloud.example.com%2Fapps%2Frichdocuments%2Fwopi%2Ffiles%2F51040?access_token=ABCDEF&permission=edit/ws
。
Collagora将报告这样的错误消息:
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
标志,[B]
标志似乎在谈论与我的问题有关的内容。那里说" mod_rewrite在映射之前必须取消示例URL"(我认为是唯一的原因是最大程度地提高烦恼),因此[B]
标志将在映射后再次重新占用它们。当然,这在这种情况下不起作用,并且将逃脱所有的斜线,即使是以前没有逃脱的斜线:"ws://collabora.example.com%2Flool%2Fhttps%253A%252F%252Fcloud.example.com%252Fapps%252Frichdocuments%252Fwopi%252Ffiles%252F51040%3Faccess_token%3DABCDEF%26permission%3Dedit%2Fws"
有没有办法解决此问题,还是我最终必须摆脱Apache的点?
该领域的一个技巧是使用%{the_request}而不是backReference,因为它将使用原始编码的请求,例如:
<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。我只检查了桌子,但我怀疑它只会通过一些小调整使您通过编码问题。
基于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将再次逃脱)。
collabora更新了文档,我在同一问题中运行。
所以有一个更好的解决方案(在https://www.collaboraoffice.com/code/上找到)
AllowEncodedSlashes NoDecode
ProxyPassMatch "/lool/(.*)/ws$" wss://127.0.0.1:9980/lool/$1/ws nocanon