Support 1012, 1013 and 1014 WebSocket status code
Motivation: RFC 6455 doesn't define status codes 1012, 1013 and 1014. Yet, since then, IANA has defined them, web browsers support them, applications in the wild do use them but it's currently not possible to buid a Netty based client for those services. From https://www.iana.org/assignments/websocket/websocket.xhtml: * 1012: Service Restart * 1013: Try Again Later * 1014: The server was acting as a gateway or proxy and received an invalid response from the upstream server. This is similar to 502 HTTP Status Code. Modification: Make status codes 1012, 1013 and 1014 legit. Result: WebSocket status codes as defined by IANA are supported.
This commit is contained in:
parent
83ab4ef5e3
commit
db6d94f82a
@ -451,7 +451,7 @@ public class WebSocket08FrameDecoder extends ByteToMessageDecoder
|
|||||||
// Must have 2 byte integer within the valid range
|
// Must have 2 byte integer within the valid range
|
||||||
int statusCode = buffer.readShort();
|
int statusCode = buffer.readShort();
|
||||||
if (statusCode >= 0 && statusCode <= 999 || statusCode >= 1004 && statusCode <= 1006
|
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);
|
protocolViolation(ctx, "Invalid close frame getStatus code: " + statusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,11 +12,20 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http.websocketx;
|
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 io.netty.channel.ChannelHandlerContext;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class WebSocket08FrameDecoderTest {
|
public class WebSocket08FrameDecoderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -26,4 +35,50 @@ public class WebSocket08FrameDecoderTest {
|
|||||||
decoder.channelInactive(ctx);
|
decoder.channelInactive(ctx);
|
||||||
Mockito.verify(ctx).fireChannelInactive();
|
Mockito.verify(ctx).fireChannelInactive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void supportIanaStatusCodes() throws Exception {
|
||||||
|
Set<Integer> forbiddenIanaCodes = new HashSet<Integer>();
|
||||||
|
forbiddenIanaCodes.add(1004);
|
||||||
|
forbiddenIanaCodes.add(1005);
|
||||||
|
forbiddenIanaCodes.add(1006);
|
||||||
|
Set<Integer> validIanaCodes = new HashSet<Integer>();
|
||||||
|
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<Object> out = new ArrayList<Object>();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user