简体   繁体   English

Apache websocket 适用于 ProxyPass 但不适用于 RewriteRule

[英]Apache websocket works with ProxyPass but not RewriteRule

I'm trying to enable websockets on an AWS ElasticBeanstalk Tomcat 8.5 web app.我正在尝试在 AWS ElasticBeanstalk Tomcat 8.5 Web 应用程序上启用 websocket。 I have a custom apache config (abbreviated):我有一个自定义的 apache 配置(缩写):

RewriteEngine On
RewriteOptions Inherit

ProxyRequests Off
ProxyPreserveHost on

# send websocket requests to tomcat with the websocket protocol
RewriteCond ${HTTP:Connection}  "Upgrade" [NC]
RewriteCond ${HTTP:Upgrade}     "websocket" [NC]
RewriteRule /(.*) "ws://localhost:8080/$1" [P,L]

# send all other requests to tomcat
ProxyPass           /   http://localhost:8080/  retry=0
ProxyPassReverse    /   http://localhost:8080/

In the web app, when I try to connect the client websocket to the server endpoint, I get this error:在 Web 应用程序中,当我尝试将客户端 websocket 连接到服务器端点时,出现此错误:

websocket.js:372 WebSocket connection to 'wss://example.com/ws/sales' failed: Error during WebSocket handshake: Unexpected response code: 404 websocket.js:372 与“wss://example.com/ws/sales”的 WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:404

I verified in Chrome's developer tools that the Connection and Upgrade headers sent in the request to the above endpoint are correct.我在 Chrome 的开发人员工具中验证了在请求中发送到上述端点的 Connection 和 Upgrade 标头是正确的。 (Obviously I'm really connecting to my website, not example.com) (显然我真的连接到我的网站,而不是 example.com)

When I change the apache config to use ProxyPass instead of RewriteRule, it works perfectly!当我将 apache 配置更改为使用 ProxyPass 而不是 RewriteRule 时,它​​运行良好! I don't want to do it this way because I don't want to proxy to ws simply based on the URI.我不想这样做,因为我不想仅仅根据 URI 代理到 ws。 I want to check the headers like you're supposed to!我想像你应该的那样检查标题!

ProxyRequests Off
ProxyPreserveHost on

# send websocket requests to tomcat with the websocket protocol
ProxyPass           /ws/    ws://localhost:8080/ws/ retry=0
ProxyPassReverse    /ws/    ws://localhost:8080/ws/

# send all other requests to tomcat
ProxyPass           /   http://localhost:8080/  retry=0
ProxyPassReverse    /   http://localhost:8080/

I stumbled upon the solution to this simply by trial and error, which is to remove the L (last) flag from the RewriteRule .我只是通过反复试验偶然发现了解决方案,即从RewriteRule删除L (最后一个)标志。 What I don't understand still is why that fixes it.我仍然不明白的是为什么会修复它。 I figured it would be good to post this answer anyway.我认为无论如何发布这个答案会很好。

RewriteEngine On
RewriteOptions Inherit

ProxyRequests Off
ProxyPreserveHost on

# send websocket requests to tomcat with the websocket protocol
RewriteCond %{HTTP:Upgrade}     "websocket" [NC]
RewriteCond %{HTTP:Connection}  "Upgrade" [NC]
RewriteRule .* "ws://localhost:8080%{REQUEST_URI}" [P]

# send all other requests to tomcat
ProxyPass           /   http://localhost:8080/  retry=0
ProxyPassReverse    /   http://localhost:8080/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM