首页 > 解决方案 > 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 中,因为我们没有在 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)

标签: google-chromenettyapache-zeppelin

解决方案


推荐阅读