如何解决Chrome RSV 中的 Zeppelin 和 Netty 反向代理!= 0 并且没有协商扩展,RSV:4
我们正在尝试将 Zeppelin 版本从 0.7.0 升级到 0.8.2,但在 Chrome 中遇到了 WebSockets 问题。 我们的流程是 Zeppelin 用于身份验证的反向代理,基于 Netty。 反向代理使用的是 netty 4.1.50。 在我们尝试升级之前,我们通过反向代理使用 Zeppelin 没有任何问题。
该问题与WebSockets有关,在Netty中抛出异常-
io.netty.handler.codec.CorruptedFrameException: RSV != 0 and no extension negotiated,RSV:4
我们最初认为问题出在 Netty 中,因为我们没有在其中启用扩展
WebSocketServerHandshakerFactory(java.lang.String webSocketURL,java.lang.String subprotocols,boolean allowExtensions)
然而,当我们启用 allowExtensions = true 时,我们仍然看到完全相同的行为。
当我们进一步挖掘时,我们发现在用于连接 WebSocket 的 RFC 中:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued,if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key,if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
RSV1、RSV2、RSV3:各 1 位
MUST be 0 unless an extension is negotiated that defines meanings
for non-zero values. If a nonzero value is received and none of
the negotiated extensions defines the meaning of such a nonzero
value,the receiving endpoint MUST _Fail the WebSocket
Connection_.
所以看起来 Netty 的行为是正确的,而且 Zeppelin 以某种方式发送了 RSV = 4。
看起来 Zeppelin 还负责定义 RSV = 4 的含义:
8.错误处理
8.1. Handling Errors in UTF-8-Encoded Data
When an endpoint is to interpret a byte stream as UTF-8 but finds
that the byte stream is not,in fact,a valid UTF-8 stream,that
endpoint MUST _Fail the WebSocket Connection_. This rule applies
both during the opening handshake and during subsequent data
exchange.
9. Extensions
WebSocket clients MAY request extensions to this specification,and
WebSocket servers MAY accept some or all extensions requested by the
client. A server MUST NOT respond with any extension not requested
by the client. If extension parameters are included in negotiations
between the client and the server,those parameters MUST be chosen in
accordance with the specification of the extension to which the
parameters apply.
最后,相关的堆栈跟踪如下。一旦反向代理成功通过身份验证并转发到 Zeppelin,就会触发此操作。
akka.actor.default-dispatcher-7] .o.p.WebSocketProxyNettyClient - Connecting to -97122421/servername:26698 /notebook/ws
akka.actor.default-dispatcher-7] .o.p.WebSocketProxyNettyClient - 97122421/servername:26698 handshakingWithFrontEnd>got UpgradedToWebSocket
akka.actor.default-dispatcher-7] .o.p.WebSocketProxyNettyClient - 97122421/servername:26698 connect>got BothHandshakesCompleted
akka.actor.default-dispatcher-4] .o.p.WebSocketProxyNettyClient - 97122421/servername:26698 front-end>send frame TextWebSocketFrame size=111
akka.actor.default-dispatcher-4] .o.p.WebSocketProxyNettyClient - 97122421/servername:26698 front-end>send frame TextWebSocketFrame size=102
akka.actor.default-dispatcher-4] .o.p.WebSocketProxyNettyClient - 97122421/servername:26698 front-end>send frame TextWebSocketFrame size=105
[nioEventLoopGroup-4-4] .p.WebSocketNettyClientHandler - ExceptionCaught for -97122421/servername:26698 /notebook/ws
io.netty.handler.codec.CorruptedFrameException: RSV != 0 and no extension negotiated,RSV:4
at io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder.protocolViolation(WebSocket08FrameDecoder.java:412)
at io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder.decode(WebSocket08FrameDecoder.java:188)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1412)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:943)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:141)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。