Add max frame length for web socket to limit chance of DOS attack (#283)
- Contributed by @veebs
This commit is contained in:
parent
ec43aa121f
commit
67ee22e23a
@ -34,7 +34,7 @@ public class WebSocket00FrameDecoder extends ReplayingDecoder<WebSocketFrame, Vo
|
||||
|
||||
private static final int DEFAULT_MAX_FRAME_SIZE = 16384;
|
||||
|
||||
private final int maxFrameSize;
|
||||
private final long maxFrameSize;
|
||||
private boolean receivedClosingHandshake;
|
||||
|
||||
public WebSocket00FrameDecoder() {
|
||||
@ -48,7 +48,7 @@ public class WebSocket00FrameDecoder extends ReplayingDecoder<WebSocketFrame, Vo
|
||||
* @param maxFrameSize
|
||||
* the maximum frame size to decode
|
||||
*/
|
||||
public WebSocket00FrameDecoder(int maxFrameSize) {
|
||||
public WebSocket00FrameDecoder(long maxFrameSize) {
|
||||
this.maxFrameSize = maxFrameSize;
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,7 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocketFrame, We
|
||||
private UTF8Output fragmentedFramesText;
|
||||
private int fragmentedFramesCount;
|
||||
|
||||
private final long maxFramePayloadLength;
|
||||
private boolean frameFinalFlag;
|
||||
private int frameRsv;
|
||||
private int frameOpcode;
|
||||
@ -105,11 +106,15 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocketFrame, We
|
||||
* 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) {
|
||||
public WebSocket08FrameDecoder(boolean maskedPayload, boolean allowExtensions, long maxFramePayloadLength) {
|
||||
super(State.FRAME_START);
|
||||
this.maskedPayload = maskedPayload;
|
||||
this.allowExtensions = allowExtensions;
|
||||
this.maxFramePayloadLength = maxFramePayloadLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -219,6 +224,11 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocketFrame, We
|
||||
framePayloadLength = framePayloadLen1;
|
||||
}
|
||||
|
||||
if (framePayloadLength > maxFramePayloadLength) {
|
||||
protocolViolation(ctx, "Max frame length of " + maxFramePayloadLength + " has been exceeded.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Decoding WebSocket Frame length=" + framePayloadLength);
|
||||
}
|
||||
@ -235,7 +245,7 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocketFrame, We
|
||||
int rbytes = actualReadableBytes();
|
||||
ChannelBuffer payloadBuffer = null;
|
||||
|
||||
int willHaveReadByteCount = framePayloadBytesRead + rbytes;
|
||||
long willHaveReadByteCount = framePayloadBytesRead + rbytes;
|
||||
// logger.debug("Frame rbytes=" + rbytes + " willHaveReadByteCount="
|
||||
// + willHaveReadByteCount + " framePayloadLength=" +
|
||||
// framePayloadLength);
|
||||
|
@ -60,14 +60,17 @@ public class WebSocket13FrameDecoder extends WebSocket08FrameDecoder {
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
super(maskedPayload, allowExtensions);
|
||||
public WebSocket13FrameDecoder(boolean maskedPayload, boolean allowExtensions, long maxFramePayloadLength) {
|
||||
super(maskedPayload, allowExtensions, maxFramePayloadLength);
|
||||
}
|
||||
}
|
||||
|
@ -15,13 +15,13 @@
|
||||
*/
|
||||
package io.netty.handler.codec.http.websocketx;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base class for web socket client handshake implementations
|
||||
*/
|
||||
@ -39,6 +39,8 @@ public abstract class WebSocketClientHandshaker {
|
||||
|
||||
protected final Map<String, String> customHeaders;
|
||||
|
||||
private final long maxFramePayloadLength;
|
||||
|
||||
/**
|
||||
* Base constructor
|
||||
*
|
||||
@ -51,13 +53,16 @@ public abstract class WebSocketClientHandshaker {
|
||||
* 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) {
|
||||
Map<String, String> customHeaders, long maxFramePayloadLength) {
|
||||
this.webSocketUrl = webSocketUrl;
|
||||
this.version = version;
|
||||
expectedSubprotocol = subprotocol;
|
||||
this.customHeaders = customHeaders;
|
||||
this.maxFramePayloadLength = maxFramePayloadLength;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,6 +79,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
|
||||
*/
|
||||
|
@ -60,10 +60,12 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
||||
* 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) {
|
||||
super(webSocketURL, version, subprotocol, customHeaders);
|
||||
Map<String, String> customHeaders, long maxFramePayloadLength) {
|
||||
super(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
|
||||
|
||||
}
|
||||
|
||||
@ -219,7 +221,9 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
||||
String protocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||
setActualSubprotocol(protocol);
|
||||
|
||||
channel.pipeline().replace(HttpResponseDecoder.class, "ws-decoder", new WebSocket00FrameDecoder());
|
||||
channel.pipeline().replace(
|
||||
HttpResponseDecoder.class, "ws-decoder",
|
||||
new WebSocket00FrameDecoder(getMaxFramePayloadLength()));
|
||||
|
||||
setHandshakeComplete();
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
private final boolean allowExtensions;
|
||||
|
||||
/**
|
||||
* Constructor specifying the destination web socket location and version to initiate
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param webSocketURL
|
||||
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||
@ -67,10 +67,12 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
* 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) {
|
||||
super(webSocketURL, version, subprotocol, customHeaders);
|
||||
boolean allowExtensions, Map<String, String> customHeaders, long maxFramePayloadLength) {
|
||||
super(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
|
||||
this.allowExtensions = allowExtensions;
|
||||
}
|
||||
|
||||
@ -196,7 +198,7 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
}
|
||||
|
||||
channel.pipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
||||
new WebSocket08FrameDecoder(false, allowExtensions));
|
||||
new WebSocket08FrameDecoder(false, allowExtensions, getMaxFramePayloadLength()));
|
||||
|
||||
setHandshakeComplete();
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
private final boolean allowExtensions;
|
||||
|
||||
/**
|
||||
* Constructor specifying the destination web socket location and version to initiate
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param webSocketURL
|
||||
* URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||
@ -67,10 +67,12 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
* 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) {
|
||||
super(webSocketURL, version, subprotocol, customHeaders);
|
||||
boolean allowExtensions, Map<String, String> customHeaders, long maxFramePayloadLength) {
|
||||
super(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
|
||||
this.allowExtensions = allowExtensions;
|
||||
}
|
||||
|
||||
@ -196,7 +198,7 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
}
|
||||
|
||||
channel.pipeline().replace(HttpResponseDecoder.class, "ws-decoder",
|
||||
new WebSocket13FrameDecoder(false, allowExtensions));
|
||||
new WebSocket13FrameDecoder(false, allowExtensions, getMaxFramePayloadLength()));
|
||||
|
||||
setHandshakeComplete();
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ import java.util.Map;
|
||||
public class WebSocketClientHandshakerFactory {
|
||||
|
||||
/**
|
||||
* Instances a new handshaker
|
||||
*
|
||||
* Creates 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.
|
||||
@ -37,21 +37,44 @@ public class WebSocketClientHandshakerFactory {
|
||||
* Allow extensions to be used in the reserved bits of the web socket frame
|
||||
* @param customHeaders
|
||||
* Custom HTTP headers to send during the handshake
|
||||
* @throws WebSocketHandshakeException
|
||||
*/
|
||||
public WebSocketClientHandshaker newHandshaker(URI webSocketURL, WebSocketVersion version, String subprotocol,
|
||||
boolean allowExtensions, Map<String, String> customHeaders) throws WebSocketHandshakeException {
|
||||
public WebSocketClientHandshaker newHandshaker(
|
||||
URI webSocketURL, WebSocketVersion version, String subprotocol,
|
||||
boolean allowExtensions, Map<String, String> customHeaders) {
|
||||
return newHandshaker(webSocketURL, version, subprotocol, allowExtensions, customHeaders, 65536);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates 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.
|
||||
*/
|
||||
public WebSocketClientHandshaker newHandshaker(
|
||||
URI webSocketURL, WebSocketVersion version, String subprotocol,
|
||||
boolean allowExtensions, Map<String, String> customHeaders, long maxFramePayloadLength) {
|
||||
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.");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -15,13 +15,13 @@
|
||||
*/
|
||||
package io.netty.handler.codec.http.websocketx;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Base class for server side web socket opening and closing handshakes
|
||||
*/
|
||||
@ -33,6 +33,8 @@ public abstract class WebSocketServerHandshaker {
|
||||
|
||||
private final WebSocketVersion version;
|
||||
|
||||
private final long maxFramePayloadLength;
|
||||
|
||||
/**
|
||||
* Constructor specifying the destination web socket location
|
||||
*
|
||||
@ -43,9 +45,12 @@ 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) {
|
||||
WebSocketVersion version, String webSocketUrl, String subprotocols,
|
||||
long maxFramePayloadLength) {
|
||||
this.version = version;
|
||||
this.webSocketUrl = webSocketUrl;
|
||||
if (subprotocols != null) {
|
||||
@ -57,6 +62,7 @@ public abstract class WebSocketServerHandshaker {
|
||||
} else {
|
||||
this.subprotocols = new String[0];
|
||||
}
|
||||
this.maxFramePayloadLength = maxFramePayloadLength;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +77,7 @@ public abstract class WebSocketServerHandshaker {
|
||||
*/
|
||||
public Set<String> getSubprotocols() {
|
||||
Set<String> ret = new LinkedHashSet<String>();
|
||||
for (String p: this.subprotocols) {
|
||||
for (String p: subprotocols) {
|
||||
ret.add(p);
|
||||
}
|
||||
return ret;
|
||||
@ -84,6 +90,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
|
||||
*
|
||||
|
@ -57,9 +57,12 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
||||
* 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) {
|
||||
super(WebSocketVersion.V00, webSocketURL, subprotocols);
|
||||
public WebSocketServerHandshaker00(String webSocketURL, String subprotocols, long maxFramePayloadLength) {
|
||||
super(WebSocketVersion.V00, webSocketURL, subprotocols, maxFramePayloadLength);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,7 +169,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(getMaxFramePayloadLength()));
|
||||
|
||||
ChannelFuture future = channel.write(res);
|
||||
|
||||
|
@ -58,9 +58,12 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
|
||||
* 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) {
|
||||
super(WebSocketVersion.V08, webSocketURL, subprotocols);
|
||||
public WebSocketServerHandshaker08(String webSocketURL, String subprotocols, boolean allowExtensions, long maxFramePayloadLength) {
|
||||
super(WebSocketVersion.V08, webSocketURL, subprotocols, maxFramePayloadLength);
|
||||
this.allowExtensions = allowExtensions;
|
||||
}
|
||||
|
||||
@ -141,7 +144,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, getMaxFramePayloadLength()));
|
||||
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false));
|
||||
|
||||
return future;
|
||||
|
@ -59,9 +59,12 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
||||
* 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) {
|
||||
super(WebSocketVersion.V13, webSocketURL, subprotocols);
|
||||
public WebSocketServerHandshaker13(String webSocketURL, String subprotocols, boolean allowExtensions, long maxFramePayloadLength) {
|
||||
super(WebSocketVersion.V13, webSocketURL, subprotocols, maxFramePayloadLength);
|
||||
this.allowExtensions = allowExtensions;
|
||||
}
|
||||
|
||||
@ -142,7 +145,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, getMaxFramePayloadLength()));
|
||||
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false));
|
||||
|
||||
return future;
|
||||
|
@ -17,11 +17,11 @@ package io.netty.handler.codec.http.websocketx;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.handler.codec.http.DefaultHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
|
||||
/**
|
||||
* Instances the appropriate handshake class to use for servers
|
||||
@ -34,9 +34,11 @@ public class WebSocketServerHandshakerFactory {
|
||||
|
||||
private final boolean allowExtensions;
|
||||
|
||||
private final long maxFramePayloadLength;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -45,15 +47,37 @@ public class WebSocketServerHandshakerFactory {
|
||||
* @param allowExtensions
|
||||
* Allow extensions to be used in the reserved bits of the web socket frame
|
||||
*/
|
||||
public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions) {
|
||||
public WebSocketServerHandshakerFactory(
|
||||
String webSocketURL, String subprotocols, boolean allowExtensions) {
|
||||
this(webSocketURL, subprotocols, allowExtensions, 65536);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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. 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,
|
||||
long maxFramePayloadLength) {
|
||||
this.webSocketURL = webSocketURL;
|
||||
this.subprotocols = subprotocols;
|
||||
this.allowExtensions = allowExtensions;
|
||||
this.maxFramePayloadLength = maxFramePayloadLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instances a new handshaker
|
||||
*
|
||||
*
|
||||
* @return A new WebSocketServerHandshaker for the requested web socket version. Null if web socket version is not
|
||||
* supported.
|
||||
*/
|
||||
@ -63,22 +87,22 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return that we need cannot not support the web socket version
|
||||
*
|
||||
*
|
||||
* @param channel
|
||||
* Channel
|
||||
*/
|
||||
|
@ -18,6 +18,7 @@ package io.netty.handler.codec.http;
|
||||
import static org.junit.Assert.*;
|
||||
import io.netty.buffer.ChannelBuffer;
|
||||
import io.netty.buffer.ChannelBuffers;
|
||||
import io.netty.handler.codec.CodecException;
|
||||
import io.netty.handler.codec.PrematureChannelClosureException;
|
||||
import io.netty.handler.codec.embedder.DecoderEmbedder;
|
||||
import io.netty.handler.codec.embedder.EncoderEmbedder;
|
||||
@ -72,7 +73,7 @@ public class HttpClientCodecTest {
|
||||
try {
|
||||
encoder.finish();
|
||||
fail();
|
||||
} catch (CodecEmbedderException e) {
|
||||
} catch (CodecException e) {
|
||||
assertTrue(e.getCause() instanceof PrematureChannelClosureException);
|
||||
}
|
||||
|
||||
@ -92,7 +93,7 @@ public class HttpClientCodecTest {
|
||||
encoder.finish();
|
||||
decoder.finish();
|
||||
fail();
|
||||
} catch (CodecEmbedderException e) {
|
||||
} catch (CodecException e) {
|
||||
assertTrue(e.getCause() instanceof PrematureChannelClosureException);
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ public class WebSocketServerHandshaker00Test {
|
||||
ChannelBuffer buffer = ChannelBuffers.copiedBuffer("^n:ds[4U", Charset.defaultCharset());
|
||||
req.setContent(buffer);
|
||||
|
||||
WebSocketServerHandshaker00 handsaker = new WebSocketServerHandshaker00("ws://example.com/chat", "chat");
|
||||
WebSocketServerHandshaker00 handsaker = new WebSocketServerHandshaker00("ws://example.com/chat", "chat", Long.MAX_VALUE);
|
||||
handsaker.handshake(channelMock, req);
|
||||
|
||||
Assert.assertEquals("ws://example.com/chat", res.getValue().getHeader(Names.SEC_WEBSOCKET_LOCATION));
|
||||
|
@ -67,7 +67,7 @@ public class WebSocketServerHandshaker08Test {
|
||||
req.setHeader(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat");
|
||||
req.setHeader(Names.SEC_WEBSOCKET_VERSION, "8");
|
||||
|
||||
WebSocketServerHandshaker08 handsaker = new WebSocketServerHandshaker08("ws://example.com/chat", "chat", false);
|
||||
WebSocketServerHandshaker08 handsaker = new WebSocketServerHandshaker08("ws://example.com/chat", "chat", false, Long.MAX_VALUE);
|
||||
handsaker.handshake(channelMock, req);
|
||||
|
||||
Assert.assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.getValue().getHeader(Names.SEC_WEBSOCKET_ACCEPT));
|
||||
|
@ -66,7 +66,7 @@ public class WebSocketServerHandshaker13Test {
|
||||
req.setHeader(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com");
|
||||
req.setHeader(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat");
|
||||
req.setHeader(Names.SEC_WEBSOCKET_VERSION, "13");
|
||||
WebSocketServerHandshaker13 handsaker = new WebSocketServerHandshaker13("ws://example.com/chat", "chat", false);
|
||||
WebSocketServerHandshaker13 handsaker = new WebSocketServerHandshaker13("ws://example.com/chat", "chat", false, Long.MAX_VALUE);
|
||||
handsaker.handshake(channelMock, req);
|
||||
|
||||
Assert.assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.getValue().getHeader(Names.SEC_WEBSOCKET_ACCEPT));
|
||||
|
Loading…
Reference in New Issue
Block a user