diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java index 604746c5ae..f5a6dc1936 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java @@ -451,7 +451,7 @@ public class WebSocket08FrameDecoder extends ByteToMessageDecoder // Must have 2 byte integer within the valid range int statusCode = buffer.readShort(); if (statusCode >= 0 && statusCode <= 999 || statusCode >= 1004 && statusCode <= 1006 - || statusCode >= 1012 && statusCode <= 2999) { + || statusCode >= 1015 && statusCode <= 2999) { protocolViolation(ctx, "Invalid close frame getStatus code: " + statusCode); } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoderTest.java index 547eed6174..029f7db447 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoderTest.java @@ -12,11 +12,20 @@ */ package io.netty.handler.codec.http.websocketx; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import org.junit.Test; +import static org.junit.Assert.*; import org.mockito.Mockito; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + public class WebSocket08FrameDecoderTest { @Test @@ -26,4 +35,50 @@ public class WebSocket08FrameDecoderTest { decoder.channelInactive(ctx); Mockito.verify(ctx).fireChannelInactive(); } + + @Test + public void supportIanaStatusCodes() throws Exception { + Set forbiddenIanaCodes = new HashSet(); + forbiddenIanaCodes.add(1004); + forbiddenIanaCodes.add(1005); + forbiddenIanaCodes.add(1006); + Set validIanaCodes = new HashSet(); + for (int i = 1000; i < 1015; i++) { + validIanaCodes.add(i); + } + validIanaCodes.removeAll(forbiddenIanaCodes); + + ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); + Mockito.when(ctx.alloc()).thenReturn(UnpooledByteBufAllocator.DEFAULT); + + Channel channel = Mockito.mock(Channel.class); + Mockito.when(channel.isActive()).thenReturn(false); + Mockito.when(ctx.channel()).thenReturn(channel); + + List out = new ArrayList(); + + for (int statusCode: validIanaCodes) { + WebSocket08FrameEncoder encoder = new WebSocket08FrameEncoder(true); + WebSocket08FrameDecoder decoder = new WebSocket08FrameDecoder(true, true, 65535, false); + + CloseWebSocketFrame inputFrame = new CloseWebSocketFrame(statusCode, "Bye"); + try { + encoder.encode(ctx, inputFrame, out); + ByteBuf serializedCloseFrame = (ByteBuf) out.get(0); + out.clear(); + + decoder.decode(ctx, serializedCloseFrame, out); + CloseWebSocketFrame outputFrame = (CloseWebSocketFrame) out.get(0); + out.clear(); + + try { + assertEquals(statusCode, outputFrame.statusCode()); + } finally { + outputFrame.release(); + } + } finally { + inputFrame.release(); + } + } + } }