|
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