Send a websocket close frame with status code when receiving invalid frames

Motivation:

According to the websocket specification peers may send a close frame when
they detect a protocol violation (with status code 1002). The current
implementation simply closes the connection. This update should add this
functionality. The functionality is optional - but it might help other
implementations with debugging when they receive such a frame.

Modification:

When a protocol violation in the decoder is detected and a close was not
already initiated by the remote peer a close frame is
sent.

Result:

Remotes which will send an invalid frame will now get a close frame that
indicates the protocol violation instead of only seeing a closed
connection.
This commit is contained in:
Matthias Einwag 2014-09-26 22:47:27 +02:00 committed by Norman Maurer
parent 01b0691ee0
commit ea3c26b65e

View File

@ -314,8 +314,8 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
return; return;
} }
if (frameOpcode == OPCODE_CLOSE) { if (frameOpcode == OPCODE_CLOSE) {
checkCloseFrameBody(ctx, framePayload);
receivedClosingHandshake = true; receivedClosingHandshake = true;
checkCloseFrameBody(ctx, framePayload);
out.add(new CloseWebSocketFrame(frameFinalFlag, frameRsv, framePayload)); out.add(new CloseWebSocketFrame(frameFinalFlag, frameRsv, framePayload));
framePayload = null; framePayload = null;
return; return;
@ -414,7 +414,13 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
private void protocolViolation(ChannelHandlerContext ctx, CorruptedFrameException ex) { private void protocolViolation(ChannelHandlerContext ctx, CorruptedFrameException ex) {
checkpoint(State.CORRUPT); checkpoint(State.CORRUPT);
if (ctx.channel().isActive()) { if (ctx.channel().isActive()) {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); Object closeMessage;
if (receivedClosingHandshake) {
closeMessage = Unpooled.EMPTY_BUFFER;
} else {
closeMessage = new CloseWebSocketFrame(1002, null);
}
ctx.writeAndFlush(closeMessage).addListener(ChannelFutureListener.CLOSE);
} }
throw ex; throw ex;
} }