Merge pull request #285 from veebs/3WsMaxFrameLength

Issue #283 - (3.x) Support max frame length for web socket to limit chance of DOS attack
This commit is contained in:
Norman Maurer 2012-04-26 22:22:21 -07:00
commit 99da06bfd1
14 changed files with 317 additions and 39 deletions

View File

@ -114,7 +114,7 @@ public class WebSocketClient {
// Send 10 messages and wait for responses
System.out.println("WebSocket Client sending message");
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 1000; i++) {
ch.write(new TextWebSocketFrame("Message #" + i));
}

View File

@ -35,7 +35,7 @@ public class WebSocket00FrameDecoder extends ReplayingDecoder<VoidEnum> {
private static final int DEFAULT_MAX_FRAME_SIZE = 16384;
private final int maxFrameSize;
private final long maxFrameSize;
private boolean receivedClosingHandshake;
public WebSocket00FrameDecoder() {
@ -52,6 +52,17 @@ public class WebSocket00FrameDecoder extends ReplayingDecoder<VoidEnum> {
public WebSocket00FrameDecoder(int maxFrameSize) {
this.maxFrameSize = maxFrameSize;
}
/**
* Creates a new instance of {@code WebSocketFrameDecoder} with the specified {@code maxFrameSize}. If the client
* sends a frame size larger than {@code maxFrameSize}, the channel will be closed.
*
* @param maxFrameSize
* the maximum frame size to decode
*/
public WebSocket00FrameDecoder(long maxFrameSize) {
this.maxFrameSize = maxFrameSize;
}
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, VoidEnum state)

View File

@ -82,6 +82,7 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
private UTF8Output fragmentedFramesText;
private int fragmentedFramesCount;
private long maxFramePayloadLength;
private boolean frameFinalFlag;
private int frameRsv;
private int frameOpcode;
@ -99,7 +100,7 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
}
/**
* Constructor
* Constructor with default values
*
* @param maskedPayload
* Web socket servers must set this to true processed incoming masked payload. Client implementations
@ -108,9 +109,26 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
* Flag to allow reserved extension bits to be used or not
*/
public WebSocket08FrameDecoder(boolean maskedPayload, boolean allowExtensions) {
this(maskedPayload, allowExtensions, Long.MAX_VALUE);
}
/**
* Constructor
*
* @param maskedPayload
* Web socket servers must set this to true processed incoming masked payload. Client implementations
* must set this to false.
* @param allowExtensions
* Flag to allow reserved extension bits to be used or not
* @param maxFramePayloadLength
* Maximum length of a frame's payload. Setting this to an appropriate value for you application
* helps check for denial of services attacks.
*/
public WebSocket08FrameDecoder(boolean maskedPayload, boolean allowExtensions, long maxFramePayloadLength) {
super(State.FRAME_START);
this.maskedPayload = maskedPayload;
this.allowExtensions = allowExtensions;
this.maxFramePayloadLength = maxFramePayloadLength;
}
@Override
@ -220,6 +238,10 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
framePayloadLength = framePayloadLen1;
}
if (framePayloadLength > this.maxFramePayloadLength) {
protocolViolation(channel, "Max frame length of " + this.maxFramePayloadLength + " has been exceeded.");
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("Decoding WebSocket Frame length=" + framePayloadLength);
}
@ -236,7 +258,7 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
int rbytes = actualReadableBytes();
ChannelBuffer payloadBuffer = null;
int willHaveReadByteCount = framePayloadBytesRead + rbytes;
long willHaveReadByteCount = framePayloadBytesRead + rbytes;
// logger.debug("Frame rbytes=" + rbytes + " willHaveReadByteCount="
// + willHaveReadByteCount + " framePayloadLength=" +
// framePayloadLength);

View File

@ -54,12 +54,13 @@
package org.jboss.netty.handler.codec.http.websocketx;
/**
* Decodes a web socket frame from wire protocol version 13 format. V13 is essentially the same as V8.
* Decodes a web socket frame from wire protocol version 13 format. V13 is
* essentially the same as V8.
*/
public class WebSocket13FrameDecoder extends WebSocket08FrameDecoder {
/**
* Constructor
* Constructor with default values
*
* @param maskedPayload
* Web socket servers must set this to true processed incoming masked payload. Client implementations
@ -68,6 +69,24 @@ public class WebSocket13FrameDecoder extends WebSocket08FrameDecoder {
* Flag to allow reserved extension bits to be used or not
*/
public WebSocket13FrameDecoder(boolean maskedPayload, boolean allowExtensions) {
super(maskedPayload, allowExtensions);
this(maskedPayload, allowExtensions, Long.MAX_VALUE);
}
/**
* Constructor
*
* @param maskedPayload
* Web socket servers must set this to true processed incoming
* masked payload. Client implementations must set this to false.
* @param allowExtensions
* Flag to allow reserved extension bits to be used or not
* @param maxFramePayloadLength
* Maximum length of a frame's payload. Setting this to an
* appropriate value for you application helps check for denial
* of services attacks.
*/
public WebSocket13FrameDecoder(boolean maskedPayload,
boolean allowExtensions, long maxFramePayloadLength) {
super(maskedPayload, allowExtensions, maxFramePayloadLength);
}
}

View File

@ -39,8 +39,10 @@ public abstract class WebSocketClientHandshaker {
protected final Map<String, String> customHeaders;
private final long maxFramePayloadLength;
/**
* Base constructor
* Base constructor with default values
*
* @param webSocketUrl
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
@ -54,10 +56,31 @@ public abstract class WebSocketClientHandshaker {
*/
public WebSocketClientHandshaker(URI webSocketUrl, WebSocketVersion version, String subprotocol,
Map<String, String> customHeaders) {
this(webSocketUrl, version, subprotocol, customHeaders, Long.MAX_VALUE);
}
/**
* Base constructor
*
* @param webSocketUrl
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param version
* Version of web socket specification to use to connect to the server
* @param subprotocol
* Sub protocol request sent to the server.
* @param customHeaders
* Map of custom headers to add to the client request
* @param maxFramePayloadLength
* Maximum length of a frame's payload
*/
public WebSocketClientHandshaker(URI webSocketUrl, WebSocketVersion version, String subprotocol,
Map<String, String> customHeaders, long maxFramePayloadLength) {
this.webSocketUrl = webSocketUrl;
this.version = version;
expectedSubprotocol = subprotocol;
this.customHeaders = customHeaders;
this.maxFramePayloadLength = maxFramePayloadLength;
}
/**
@ -74,6 +97,13 @@ public abstract class WebSocketClientHandshaker {
return version;
}
/**
* Returns the max length for any frame's payload
*/
public long getMaxFramePayloadLength() {
return maxFramePayloadLength;
}
/**
* Flag to indicate if the opening handshake is complete
*/

View File

@ -49,7 +49,7 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
private byte[] expectedChallengeResponseBytes;
/**
* Constructor specifying the destination web socket location and version to initiate
* Constructor with default values
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
@ -63,9 +63,29 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
*/
public WebSocketClientHandshaker00(URI webSocketURL, WebSocketVersion version, String subprotocol,
Map<String, String> customHeaders) {
super(webSocketURL, version, subprotocol, customHeaders);
this(webSocketURL, version, subprotocol, customHeaders, Long.MAX_VALUE);
}
/**
* Constructor
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param version
* Version of web socket specification to use to connect to the server
* @param subprotocol
* Sub protocol request sent to the server.
* @param customHeaders
* Map of custom headers to add to the client request
* @param maxFramePayloadLength
* Maximum length of a frame's payload
*/
public WebSocketClientHandshaker00(URI webSocketURL, WebSocketVersion version, String subprotocol,
Map<String, String> customHeaders, long maxFramePayloadLength) {
super(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
}
/**
* <p>
@ -219,7 +239,8 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
String protocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
setActualSubprotocol(protocol);
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", new WebSocket00FrameDecoder());
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
new WebSocket00FrameDecoder(this.getMaxFramePayloadLength()));
setHandshakeComplete();
}

View File

@ -54,7 +54,7 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
private final boolean allowExtensions;
/**
* Constructor specifying the destination web socket location and version to initiate
* Constructor with default values
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
@ -70,10 +70,33 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
*/
public WebSocketClientHandshaker08(URI webSocketURL, WebSocketVersion version, String subprotocol,
boolean allowExtensions, Map<String, String> customHeaders) {
super(webSocketURL, version, subprotocol, customHeaders);
this(webSocketURL, version, subprotocol, allowExtensions, customHeaders, Long.MAX_VALUE);
}
/**
* Constructor
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param version
* Version of web socket specification to use to connect to the server
* @param subprotocol
* Sub protocol request sent to the server.
* @param allowExtensions
* Allow extensions to be used in the reserved bits of the web socket frame
* @param customHeaders
* Map of custom headers to add to the client request
* @param maxFramePayloadLength
* Maximum length of a frame's payload
*/
public WebSocketClientHandshaker08(URI webSocketURL, WebSocketVersion version, String subprotocol,
boolean allowExtensions, Map<String, String> customHeaders, long maxFramePayloadLength) {
super(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
this.allowExtensions = allowExtensions;
}
/**
* /**
* <p>
@ -204,7 +227,7 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
}
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
new WebSocket08FrameDecoder(false, allowExtensions));
new WebSocket08FrameDecoder(false, allowExtensions, this.getMaxFramePayloadLength()));
setHandshakeComplete();
}

View File

@ -54,7 +54,7 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
private final boolean allowExtensions;
/**
* Constructor specifying the destination web socket location and version to initiate
* Constructor with default values
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
@ -70,7 +70,29 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
*/
public WebSocketClientHandshaker13(URI webSocketURL, WebSocketVersion version, String subprotocol,
boolean allowExtensions, Map<String, String> customHeaders) {
super(webSocketURL, version, subprotocol, customHeaders);
this(webSocketURL, version, subprotocol, allowExtensions, customHeaders, Long.MAX_VALUE);
}
/**
* Constructor
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param version
* Version of web socket specification to use to connect to the server
* @param subprotocol
* Sub protocol request sent to the server.
* @param allowExtensions
* Allow extensions to be used in the reserved bits of the web socket frame
* @param customHeaders
* Map of custom headers to add to the client request
* @param maxFramePayloadLength
* Maximum length of a frame's payload
*/
public WebSocketClientHandshaker13(URI webSocketURL, WebSocketVersion version, String subprotocol,
boolean allowExtensions, Map<String, String> customHeaders, long maxFramePayloadLength) {
super(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
this.allowExtensions = allowExtensions;
}
@ -200,7 +222,7 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
}
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder",
new WebSocket13FrameDecoder(false, allowExtensions));
new WebSocket13FrameDecoder(false, allowExtensions, this.getMaxFramePayloadLength()));
setHandshakeComplete();
}

View File

@ -41,17 +41,42 @@ public class WebSocketClientHandshakerFactory {
*/
public WebSocketClientHandshaker newHandshaker(URI webSocketURL, WebSocketVersion version, String subprotocol,
boolean allowExtensions, Map<String, String> customHeaders) throws WebSocketHandshakeException {
return newHandshaker(webSocketURL, version, subprotocol, allowExtensions, customHeaders, Long.MAX_VALUE);
}
/**
* Instances a new handshaker
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param version
* Version of web socket specification to use to connect to the server
* @param subprotocol
* Sub protocol request sent to the server. Null if no sub-protocol support is required.
* @param allowExtensions
* Allow extensions to be used in the reserved bits of the web socket frame
* @param customHeaders
* Custom HTTP headers to send during the handshake
* @param maxFramePayloadLength
* Maximum allowable frame payload length. Setting this value to your application's requirement may
* reduce denial of service attacks using long data frames.
* @throws WebSocketHandshakeException
*/
public WebSocketClientHandshaker newHandshaker(URI webSocketURL, WebSocketVersion version, String subprotocol,
boolean allowExtensions, Map<String, String> customHeaders, long maxFramePayloadLength) throws WebSocketHandshakeException {
if (version == WebSocketVersion.V13) {
return new WebSocketClientHandshaker13(webSocketURL, version, subprotocol, allowExtensions, customHeaders);
return new WebSocketClientHandshaker13(webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength);
}
if (version == WebSocketVersion.V08) {
return new WebSocketClientHandshaker08(webSocketURL, version, subprotocol, allowExtensions, customHeaders);
return new WebSocketClientHandshaker08(webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength);
}
if (version == WebSocketVersion.V00) {
return new WebSocketClientHandshaker00(webSocketURL, version, subprotocol, customHeaders);
return new WebSocketClientHandshaker00(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
}
throw new WebSocketHandshakeException("Protocol version " + version.toString() + " not supported.");
}
}

View File

@ -35,9 +35,11 @@ public abstract class WebSocketServerHandshaker {
private final WebSocketVersion version;
private final long maxFramePayloadLength;
/**
* {@link ChannelFutureListener} which will call {@link Channels#fireExceptionCaught(org.jboss.netty.channel.ChannelHandlerContext, Throwable)}
* if the {@link ChannelFuture} was not sucessful.
* if the {@link ChannelFuture} was not successful.
*/
public static final ChannelFutureListener HANDSHAKE_LISTENER = new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
@ -47,6 +49,21 @@ public abstract class WebSocketServerHandshaker {
}
};
/**
* Constructor using default values
*
* @param version
* the protocol version
* @param webSocketUrl
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param subprotocols
* CSV of supported protocols. Null if sub protocols not supported.
*/
protected WebSocketServerHandshaker(WebSocketVersion version, String webSocketUrl, String subprotocols) {
this(version, webSocketUrl, subprotocols, Long.MAX_VALUE);
}
/**
* Constructor specifying the destination web socket location
*
@ -57,9 +74,11 @@ public abstract class WebSocketServerHandshaker {
* sent to this URL.
* @param subprotocols
* CSV of supported protocols. Null if sub protocols not supported.
* @param maxFramePayloadLength
* Maximum length of a frame's payload
*/
protected WebSocketServerHandshaker(
WebSocketVersion version, String webSocketUrl, String subprotocols) {
protected WebSocketServerHandshaker(WebSocketVersion version, String webSocketUrl, String subprotocols,
long maxFramePayloadLength) {
this.version = version;
this.webSocketUrl = webSocketUrl;
if (subprotocols != null) {
@ -71,8 +90,10 @@ public abstract class WebSocketServerHandshaker {
} else {
this.subprotocols = new String[0];
}
this.maxFramePayloadLength = maxFramePayloadLength;
}
/**
* Returns the URL of the web socket
*/
@ -98,6 +119,13 @@ public abstract class WebSocketServerHandshaker {
return version;
}
/**
* Returns the max length for any frame's payload
*/
public long getMaxFramePayloadLength() {
return maxFramePayloadLength;
}
/**
* Performs the opening handshake
*

View File

@ -51,7 +51,7 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandshaker00.class);
/**
* Constructor specifying the destination web socket location
* Constructor with default values
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
@ -60,8 +60,24 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
* CSV of supported protocols
*/
public WebSocketServerHandshaker00(String webSocketURL, String subprotocols) {
super(WebSocketVersion.V00, webSocketURL, subprotocols);
this(webSocketURL, subprotocols, Long.MAX_VALUE);
}
/**
* Constructor specifying the destination web socket location
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param subprotocols
* CSV of supported protocols
* @param maxFramePayloadLength
* Maximum allowable frame payload length. Setting this value to your application's requirement may
* reduce denial of service attacks using long data frames.
*/
public WebSocketServerHandshaker00(String webSocketURL, String subprotocols, long maxFramePayloadLength) {
super(WebSocketVersion.V00, webSocketURL, subprotocols, maxFramePayloadLength);
}
/**
* <p>
@ -167,7 +183,8 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
if (p.get(HttpChunkAggregator.class) != null) {
p.remove(HttpChunkAggregator.class);
}
p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket00FrameDecoder());
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket00FrameDecoder(this.getMaxFramePayloadLength()));
ChannelFuture future = channel.write(res);

View File

@ -53,7 +53,7 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
private final boolean allowExtensions;
/**
* Constructor specifying the destination web socket location
* Constructor using defaults
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
@ -64,7 +64,26 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
* Allow extensions to be used in the reserved bits of the web socket frame
*/
public WebSocketServerHandshaker08(String webSocketURL, String subprotocols, boolean allowExtensions) {
super(WebSocketVersion.V08, webSocketURL, subprotocols);
this(webSocketURL, subprotocols, allowExtensions, Long.MAX_VALUE);
}
/**
* Constructor
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param subprotocols
* CSV of supported protocols
* @param allowExtensions
* Allow extensions to be used in the reserved bits of the web socket frame
* @param maxFramePayloadLength
* Maximum allowable frame payload length. Setting this value to your application's requirement may
* reduce denial of service attacks using long data frames.
*/
public WebSocketServerHandshaker08(String webSocketURL, String subprotocols, boolean allowExtensions,
long maxFramePayloadLength) {
super(WebSocketVersion.V08, webSocketURL, subprotocols, maxFramePayloadLength);
this.allowExtensions = allowExtensions;
}
@ -150,7 +169,8 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
p.remove(HttpChunkAggregator.class);
}
p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket08FrameDecoder(true, allowExtensions));
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket08FrameDecoder(true, allowExtensions, this.getMaxFramePayloadLength()));
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false));
return future;

View File

@ -54,7 +54,7 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
private final boolean allowExtensions;
/**
* Constructor specifying the destination web socket location
* Constructor using defaults
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
@ -65,10 +65,30 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
* Allow extensions to be used in the reserved bits of the web socket frame
*/
public WebSocketServerHandshaker13(String webSocketURL, String subprotocols, boolean allowExtensions) {
super(WebSocketVersion.V13, webSocketURL, subprotocols);
this(webSocketURL, subprotocols, allowExtensions, Long.MAX_VALUE);
}
/**
* Constructor specifying the destination web socket location
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* sent to this URL.
* @param subprotocols
* CSV of supported protocols
* @param allowExtensions
* Allow extensions to be used in the reserved bits of the web socket frame
* @param maxFramePayloadLength
* Maximum allowable frame payload length. Setting this value to your application's requirement may
* reduce denial of service attacks using long data frames.
*/
public WebSocketServerHandshaker13(String webSocketURL, String subprotocols, boolean allowExtensions,
long maxFramePayloadLength) {
super(WebSocketVersion.V13, webSocketURL, subprotocols, maxFramePayloadLength);
this.allowExtensions = allowExtensions;
}
/**
* <p>
* Handle the web socket handshake for the web socket specification <a href=
@ -151,7 +171,8 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
p.remove(HttpChunkAggregator.class);
}
p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket13FrameDecoder(true, allowExtensions));
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket13FrameDecoder(true, allowExtensions, this.getMaxFramePayloadLength()));
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false));
return future;

View File

@ -34,8 +34,22 @@ public class WebSocketServerHandshakerFactory {
private final boolean allowExtensions;
private final long maxFramePayloadLength;
/**
* Constructor specifying the destination web socket location
* Constructor
* @param subprotocols
* CSV of supported protocols. Null if sub protocols not supported.
* @param allowExtensions
* Allow extensions to be used in the reserved bits of the web socket frame
*/
public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions) {
this(webSocketURL, subprotocols, allowExtensions, Long.MAX_VALUE);
}
/**
* Constructor
*
* @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
@ -44,13 +58,18 @@ public class WebSocketServerHandshakerFactory {
* CSV of supported protocols. Null if sub protocols not supported.
* @param allowExtensions
* Allow extensions to be used in the reserved bits of the web socket frame
* @param maxFramePayloadLength
* Maximum allowable frame payload length. Setting this value to your application's requirement may
* reduce denial of service attacks using long data frames.
*/
public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions) {
public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions,
long maxFramePayloadLength) {
this.webSocketURL = webSocketURL;
this.subprotocols = subprotocols;
this.allowExtensions = allowExtensions;
this.maxFramePayloadLength = maxFramePayloadLength;
}
/**
* Instances a new handshaker
*
@ -63,16 +82,16 @@ public class WebSocketServerHandshakerFactory {
if (version != null) {
if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) {
// Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification).
return new WebSocketServerHandshaker13(webSocketURL, subprotocols, allowExtensions);
return new WebSocketServerHandshaker13(webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
} else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) {
// Version 8 of the wire protocol - version 10 of the draft hybi specification.
return new WebSocketServerHandshaker08(webSocketURL, subprotocols, allowExtensions);
return new WebSocketServerHandshaker08(webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
} else {
return null;
}
} else {
// Assume version 00 where version header was not specified
return new WebSocketServerHandshaker00(webSocketURL, subprotocols);
return new WebSocketServerHandshaker00(webSocketURL, subprotocols, maxFramePayloadLength);
}
}