Allow to turn off Utf8FrameValidator creation for websocket with Bina… (#9417)
…ryWebSocketFrames Motivation: `Utf8FrameValidator` is always created and added to the pipeline in `WebSocketServerProtocolHandler.handlerAdded` method. However, for websocket connection with only `BinaryWebSocketFrame`'s UTF8 validator is unnecessary overhead. Adding of `Utf8FrameValidator` could be easily avoided by extending of `WebSocketDecoderConfig` with additional property. Specification requires UTF-8 validation only for `TextWebSocketFrame`. Modification: Added `boolean WebSocketDecoderConfig.withUTF8Validator` that allows to avoid adding of `Utf8FrameValidator` during pipeline initialization. Result: Less overhead when using only `BinaryWebSocketFrame`within web socket.
This commit is contained in:
parent
ca2e8c3b69
commit
10ee697557
@ -27,6 +27,7 @@ public final class WebSocketDecoderConfig {
|
||||
private final boolean allowMaskMismatch;
|
||||
private final boolean allowExtensions;
|
||||
private final boolean closeOnProtocolViolation;
|
||||
private final boolean withUTF8Validator;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -44,14 +45,20 @@ public final class WebSocketDecoderConfig {
|
||||
* Flag to allow reserved extension bits to be used or not
|
||||
* @param closeOnProtocolViolation
|
||||
* Flag to send close frame immediately on any protocol violation.ion.
|
||||
* @param withUTF8Validator
|
||||
* Allows you to avoid adding of Utf8FrameValidator to the pipeline on the
|
||||
* WebSocketServerProtocolHandler creation. This is useful (less overhead)
|
||||
* when you use only BinaryWebSocketFrame within your web socket connection.
|
||||
*/
|
||||
private WebSocketDecoderConfig(int maxFramePayloadLength, boolean expectMaskedFrames, boolean allowMaskMismatch,
|
||||
boolean allowExtensions, boolean closeOnProtocolViolation) {
|
||||
boolean allowExtensions, boolean closeOnProtocolViolation,
|
||||
boolean withUTF8Validator) {
|
||||
this.maxFramePayloadLength = maxFramePayloadLength;
|
||||
this.expectMaskedFrames = expectMaskedFrames;
|
||||
this.allowMaskMismatch = allowMaskMismatch;
|
||||
this.allowExtensions = allowExtensions;
|
||||
this.closeOnProtocolViolation = closeOnProtocolViolation;
|
||||
this.withUTF8Validator = withUTF8Validator;
|
||||
}
|
||||
|
||||
public int maxFramePayloadLength() {
|
||||
@ -74,6 +81,10 @@ public final class WebSocketDecoderConfig {
|
||||
return closeOnProtocolViolation;
|
||||
}
|
||||
|
||||
public boolean withUTF8Validator() {
|
||||
return withUTF8Validator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WebSocketDecoderConfig" +
|
||||
@ -82,6 +93,7 @@ public final class WebSocketDecoderConfig {
|
||||
", allowMaskMismatch=" + allowMaskMismatch +
|
||||
", allowExtensions=" + allowExtensions +
|
||||
", closeOnProtocolViolation=" + closeOnProtocolViolation +
|
||||
", withUTF8Validator=" + withUTF8Validator +
|
||||
"]";
|
||||
}
|
||||
|
||||
@ -99,6 +111,7 @@ public final class WebSocketDecoderConfig {
|
||||
private boolean allowMaskMismatch;
|
||||
private boolean allowExtensions;
|
||||
private boolean closeOnProtocolViolation = true;
|
||||
private boolean withUTF8Validator = true;
|
||||
|
||||
private Builder() {
|
||||
/* No-op */
|
||||
@ -111,6 +124,7 @@ public final class WebSocketDecoderConfig {
|
||||
allowMaskMismatch = decoderConfig.allowMaskMismatch();
|
||||
allowExtensions = decoderConfig.allowExtensions();
|
||||
closeOnProtocolViolation = decoderConfig.closeOnProtocolViolation();
|
||||
withUTF8Validator = decoderConfig.withUTF8Validator();
|
||||
}
|
||||
|
||||
public Builder maxFramePayloadLength(int maxFramePayloadLength) {
|
||||
@ -138,10 +152,15 @@ public final class WebSocketDecoderConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withUTF8Validator(boolean withUTF8Validator) {
|
||||
this.withUTF8Validator = withUTF8Validator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WebSocketDecoderConfig build() {
|
||||
return new WebSocketDecoderConfig(
|
||||
maxFramePayloadLength, expectMaskedFrames, allowMaskMismatch,
|
||||
allowExtensions, closeOnProtocolViolation);
|
||||
allowExtensions, closeOnProtocolViolation, withUTF8Validator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler {
|
||||
new WebSocketServerProtocolHandshakeHandler(
|
||||
websocketPath, subprotocols, checkStartsWith, handshakeTimeoutMillis, decoderConfig));
|
||||
}
|
||||
if (cp.get(Utf8FrameValidator.class) == null) {
|
||||
if (decoderConfig.withUTF8Validator() && cp.get(Utf8FrameValidator.class) == null) {
|
||||
// Add the UFT8 checking before this one.
|
||||
cp.addBefore(ctx.name(), Utf8FrameValidator.class.getName(),
|
||||
new Utf8FrameValidator());
|
||||
|
@ -120,6 +120,46 @@ public class WebSocketServerProtocolHandlerTest {
|
||||
assertFalse(ch.finish());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateUTF8Validator() {
|
||||
WebSocketDecoderConfig config = WebSocketDecoderConfig.newBuilder()
|
||||
.withUTF8Validator(true)
|
||||
.build();
|
||||
|
||||
EmbeddedChannel ch = new EmbeddedChannel(
|
||||
new WebSocketServerProtocolHandler("/test", null, false, false, 1000L, config),
|
||||
new HttpRequestDecoder(),
|
||||
new HttpResponseEncoder(),
|
||||
new MockOutboundHandler());
|
||||
writeUpgradeRequest(ch);
|
||||
|
||||
FullHttpResponse response = responses.remove();
|
||||
assertEquals(SWITCHING_PROTOCOLS, response.status());
|
||||
response.release();
|
||||
|
||||
assertNotNull(ch.pipeline().get(Utf8FrameValidator.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotCreateUTF8Validator() {
|
||||
WebSocketDecoderConfig config = WebSocketDecoderConfig.newBuilder()
|
||||
.withUTF8Validator(false)
|
||||
.build();
|
||||
|
||||
EmbeddedChannel ch = new EmbeddedChannel(
|
||||
new WebSocketServerProtocolHandler("/test", null, false, false, 1000L, config),
|
||||
new HttpRequestDecoder(),
|
||||
new HttpResponseEncoder(),
|
||||
new MockOutboundHandler());
|
||||
writeUpgradeRequest(ch);
|
||||
|
||||
FullHttpResponse response = responses.remove();
|
||||
assertEquals(SWITCHING_PROTOCOLS, response.status());
|
||||
response.release();
|
||||
|
||||
assertNull(ch.pipeline().get(Utf8FrameValidator.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleTextFrame() {
|
||||
CustomTextFrameHandler customTextFrameHandler = new CustomTextFrameHandler();
|
||||
|
Loading…
Reference in New Issue
Block a user