|
44 | 44 | import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; |
45 | 45 | import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory; |
46 | 46 | import io.netty.util.AttributeKey; |
| 47 | +import java.util.Arrays; |
| 48 | +import java.util.Objects; |
47 | 49 | import java.util.Optional; |
48 | 50 | import java.util.function.BiFunction; |
49 | 51 | import java.util.function.Consumer; |
| 52 | +import java.util.logging.Level; |
| 53 | +import java.util.logging.Logger; |
50 | 54 | import org.openqa.selenium.internal.Require; |
| 55 | +import org.openqa.selenium.remote.http.CloseMessage; |
51 | 56 | import org.openqa.selenium.remote.http.Message; |
52 | 57 |
|
53 | 58 | // Plenty of code in this class is taken from Netty's own |
|
56 | 61 |
|
57 | 62 | class WebSocketUpgradeHandler extends ChannelInboundHandlerAdapter { |
58 | 63 |
|
| 64 | + private static final Logger LOG = Logger.getLogger(WebSocketUpgradeHandler.class.getName()); |
59 | 65 | private final AttributeKey<Consumer<Message>> key; |
60 | 66 | private final BiFunction<String, Consumer<Message>, Optional<Consumer<Message>>> factory; |
61 | 67 | private WebSocketServerHandshaker handshaker; |
@@ -180,6 +186,27 @@ private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame fram |
180 | 186 |
|
181 | 187 | @Override |
182 | 188 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { |
183 | | - ctx.close(); |
| 189 | + try { |
| 190 | + Consumer<Message> consumer = ctx.channel().attr(key).get(); |
| 191 | + |
| 192 | + if (consumer != null) { |
| 193 | + byte[] reason = Objects.toString(cause).getBytes(UTF_8); |
| 194 | + |
| 195 | + // the spec defines it as max 123 bytes encoded in UTF_8 |
| 196 | + if (reason.length > 123) { |
| 197 | + reason = Arrays.copyOf(reason, 123); |
| 198 | + Arrays.fill(reason, 120, 123, (byte) '.'); |
| 199 | + } |
| 200 | + |
| 201 | + try { |
| 202 | + consumer.accept(new CloseMessage(1011, new String(reason, UTF_8))); |
| 203 | + } catch (Exception ex) { |
| 204 | + LOG.log(Level.FINE, "failed to send the close message", ex); |
| 205 | + } |
| 206 | + } |
| 207 | + } finally { |
| 208 | + LOG.log(Level.FINE, "exception caught, close the context", cause); |
| 209 | + ctx.close(); |
| 210 | + } |
184 | 211 | } |
185 | 212 | } |
0 commit comments