diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java
index 5fbcd90386..91de5c38f6 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java
@@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
/**
- * Web Socket frame containing binary data
+ * Web Socket frame containing binary data.
*/
public class BinaryWebSocketFrame extends WebSocketFrame {
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java
index 371be6e4ab..4e3e9c7e93 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java
@@ -21,7 +21,7 @@ import io.netty.util.CharsetUtil;
import io.netty.util.internal.StringUtil;
/**
- * Web Socket Frame for closing the connection
+ * Web Socket Frame for closing the connection.
*/
public class CloseWebSocketFrame extends WebSocketFrame {
@@ -51,7 +51,7 @@ public class CloseWebSocketFrame extends WebSocketFrame {
* @param finalFragment
* flag indicating if this frame is the final fragment
* @param rsv
- * reserved bits used for protocol extensions
+ * reserved bits used for protocol extensions.
*/
public CloseWebSocketFrame(boolean finalFragment, int rsv) {
this(finalFragment, rsv, Unpooled.buffer(0));
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java
index bd25ea0ea6..515fe4e7d0 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java
@@ -43,7 +43,7 @@ public class ContinuationWebSocketFrame extends WebSocketFrame {
}
/**
- * Creates a new continuation frame with the specified binary data
+ * Creates a new continuation frame with the specified binary data.
*
* @param finalFragment
* flag indicating if this frame is the final fragment
@@ -71,17 +71,17 @@ public class ContinuationWebSocketFrame extends WebSocketFrame {
}
/**
- * Returns the text data in this frame
+ * Returns the text data in this frame.
*/
public String text() {
return content().toString(CharsetUtil.UTF_8);
}
/**
- * Sets the string for this frame
+ * Sets the string for this frame.
*
* @param text
- * text to store
+ * text to store.
*/
private static ByteBuf fromText(String text) {
if (text == null || text.isEmpty()) {
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java
index 08e7025088..6c3c79cf2e 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java
@@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
/**
- * Web Socket frame containing binary data
+ * Web Socket frame containing binary data.
*/
public class PingWebSocketFrame extends WebSocketFrame {
@@ -41,7 +41,7 @@ public class PingWebSocketFrame extends WebSocketFrame {
}
/**
- * Creates a new ping frame with the specified binary data
+ * Creates a new ping frame with the specified binary data.
*
* @param finalFragment
* flag indicating if this frame is the final fragment
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java
index 29c0b0f7dd..d1b08eb741 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java
@@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
/**
- * Web Socket frame containing binary data
+ * Web Socket frame containing binary data.
*/
public class PongWebSocketFrame extends WebSocketFrame {
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java
index 9b124710bb..7d6e2aa904 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java
@@ -20,7 +20,7 @@ import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
/**
- * Web Socket text frame
+ * Web Socket text frame.
*/
public class TextWebSocketFrame extends WebSocketFrame {
@@ -35,7 +35,7 @@ public class TextWebSocketFrame extends WebSocketFrame {
* Creates a new text frame with the specified text string. The final fragment flag is set to true.
*
* @param text
- * String to put in the frame
+ * String to put in the frame.
*/
public TextWebSocketFrame(String text) {
super(fromText(text));
@@ -59,7 +59,7 @@ public class TextWebSocketFrame extends WebSocketFrame {
* @param rsv
* reserved bits used for protocol extensions
* @param text
- * String to put in the frame
+ * String to put in the frame.
*/
public TextWebSocketFrame(boolean finalFragment, int rsv, String text) {
super(finalFragment, rsv, fromText(text));
@@ -74,7 +74,7 @@ public class TextWebSocketFrame extends WebSocketFrame {
}
/**
- * Creates a new text frame with the specified binary data. The final fragment flag is set to true.
+ * Creates a new text frame with the specified binary data and the final fragment flag.
*
* @param finalFragment
* flag indicating if this frame is the final fragment
@@ -88,7 +88,7 @@ public class TextWebSocketFrame extends WebSocketFrame {
}
/**
- * Returns the text data in this frame
+ * Returns the text data in this frame.
*/
public String text() {
return content().toString(CharsetUtil.UTF_8);
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrame.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrame.java
index 677f047360..b6f9a55733 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrame.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketFrame.java
@@ -20,7 +20,7 @@ import io.netty.buffer.DefaultByteBufHolder;
import io.netty.util.internal.StringUtil;
/**
- * Base class for web socket frames
+ * Base class for web socket frames.
*/
public abstract class WebSocketFrame extends DefaultByteBufHolder {
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionFilter.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionFilter.java
new file mode 100644
index 0000000000..6485e276c6
--- /dev/null
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionFilter.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.netty.handler.codec.http.websocketx.extensions;
+
+import io.netty.handler.codec.http.websocketx.WebSocketFrame;
+
+/**
+ * Filter that is responsible to skip the evaluation of a certain extension
+ * according to standard.
+ */
+public interface WebSocketExtensionFilter {
+
+ /**
+ * A {@link WebSocketExtensionFilter} that never skip the evaluation of an
+ * any given extensions {@link WebSocketExtension}.
+ */
+ WebSocketExtensionFilter NEVER_SKIP = new WebSocketExtensionFilter() {
+ @Override
+ public boolean mustSkip(WebSocketFrame frame) {
+ return false;
+ }
+ };
+
+ /**
+ * A {@link WebSocketExtensionFilter} that always skip the evaluation of an
+ * any given extensions {@link WebSocketExtension}.
+ */
+ WebSocketExtensionFilter ALWAYS_SKIP = new WebSocketExtensionFilter() {
+ @Override
+ public boolean mustSkip(WebSocketFrame frame) {
+ return true;
+ }
+ };
+
+ /**
+ * Returns {@code true} if the evaluation of the extension must skipped
+ * for the given frame otherwise {@code false}.
+ */
+ boolean mustSkip(WebSocketFrame frame);
+
+}
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionFilterProvider.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionFilterProvider.java
new file mode 100644
index 0000000000..a5eff2beb2
--- /dev/null
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/WebSocketExtensionFilterProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2019 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.netty.handler.codec.http.websocketx.extensions;
+
+/**
+ * Extension filter provider that is responsible to provide filters for a certain {@link WebSocketExtension} extension.
+ */
+public interface WebSocketExtensionFilterProvider {
+
+ WebSocketExtensionFilterProvider DEFAULT = new WebSocketExtensionFilterProvider() {
+ @Override
+ public WebSocketExtensionFilter encoderFilter() {
+ return WebSocketExtensionFilter.NEVER_SKIP;
+ }
+
+ @Override
+ public WebSocketExtensionFilter decoderFilter() {
+ return WebSocketExtensionFilter.NEVER_SKIP;
+ }
+ };
+
+ /**
+ * Returns the extension filter for {@link WebSocketExtensionEncoder} encoder.
+ */
+ WebSocketExtensionFilter encoderFilter();
+
+ /**
+ * Returns the extension filter for {@link WebSocketExtensionDecoder} decoder.
+ */
+ WebSocketExtensionFilter decoderFilter();
+
+}
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateDecoder.java
index 0232052872..de944bb254 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateDecoder.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateDecoder.java
@@ -28,9 +28,12 @@ import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionDecoder;
+import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilter;
import java.util.List;
+import static io.netty.util.internal.ObjectUtil.*;
+
/**
* Deflate implementation of a payload decompressor for
* io.netty.handler.codec.http.websocketx.WebSocketFrame.
@@ -40,15 +43,26 @@ abstract class DeflateDecoder extends WebSocketExtensionDecoder {
static final byte[] FRAME_TAIL = new byte[] {0x00, 0x00, (byte) 0xff, (byte) 0xff};
private final boolean noContext;
+ private final WebSocketExtensionFilter extensionDecoderFilter;
private EmbeddedChannel decoder;
/**
* Constructor
+ *
* @param noContext true to disable context takeover.
+ * @param extensionDecoderFilter extension decoder filter.
*/
- DeflateDecoder(boolean noContext) {
+ DeflateDecoder(boolean noContext, WebSocketExtensionFilter extensionDecoderFilter) {
this.noContext = noContext;
+ this.extensionDecoderFilter = checkNotNull(extensionDecoderFilter, "extensionDecoderFilter");
+ }
+
+ /**
+ * Returns the extension decoder filter.
+ */
+ protected WebSocketExtensionFilter extensionDecoderFilter() {
+ return extensionDecoderFilter;
}
protected abstract boolean appendFrameTail(WebSocketFrame msg);
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateEncoder.java
index b70c06bc3c..0ac9324216 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateEncoder.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateEncoder.java
@@ -15,7 +15,6 @@
*/
package io.netty.handler.codec.http.websocketx.extensions.compression;
-import static io.netty.handler.codec.http.websocketx.extensions.compression.PerMessageDeflateDecoder.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.CompositeByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -28,9 +27,13 @@ import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionEncoder;
+import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilter;
import java.util.List;
+import static io.netty.handler.codec.http.websocketx.extensions.compression.PerMessageDeflateDecoder.*;
+import static io.netty.util.internal.ObjectUtil.*;
+
/**
* Deflate implementation of a payload compressor for
* io.netty.handler.codec.http.websocketx.WebSocketFrame.
@@ -40,6 +43,7 @@ abstract class DeflateEncoder extends WebSocketExtensionEncoder {
private final int compressionLevel;
private final int windowSize;
private final boolean noContext;
+ private final WebSocketExtensionFilter extensionEncoderFilter;
private EmbeddedChannel encoder;
@@ -48,11 +52,21 @@ abstract class DeflateEncoder extends WebSocketExtensionEncoder {
* @param compressionLevel compression level of the compressor.
* @param windowSize maximum size of the window compressor buffer.
* @param noContext true to disable context takeover.
+ * @param extensionEncoderFilter extension encoder filter.
*/
- DeflateEncoder(int compressionLevel, int windowSize, boolean noContext) {
+ DeflateEncoder(int compressionLevel, int windowSize, boolean noContext,
+ WebSocketExtensionFilter extensionEncoderFilter) {
this.compressionLevel = compressionLevel;
this.windowSize = windowSize;
this.noContext = noContext;
+ this.extensionEncoderFilter = checkNotNull(extensionEncoderFilter, "extensionEncoderFilter");
+ }
+
+ /**
+ * Returns the extension encoder filter.
+ */
+ protected WebSocketExtensionFilter extensionEncoderFilter() {
+ return extensionEncoderFilter;
}
/**
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateFrameClientExtensionHandshaker.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateFrameClientExtensionHandshaker.java
index c167b375e4..c5f8b60367 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateFrameClientExtensionHandshaker.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateFrameClientExtensionHandshaker.java
@@ -15,16 +15,18 @@
*/
package io.netty.handler.codec.http.websocketx.extensions.compression;
-import static io.netty.handler.codec.http.websocketx.extensions.compression.
- DeflateFrameServerExtensionHandshaker.*;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtension;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtensionHandshaker;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionData;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionDecoder;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionEncoder;
+import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilterProvider;
import java.util.Collections;
+import static io.netty.handler.codec.http.websocketx.extensions.compression.DeflateFrameServerExtensionHandshaker.*;
+import static io.netty.util.internal.ObjectUtil.*;
+
/**
* perframe-deflate
* handshake implementation.
@@ -33,6 +35,7 @@ public final class DeflateFrameClientExtensionHandshaker implements WebSocketCli
private final int compressionLevel;
private final boolean useWebkitExtensionName;
+ private final WebSocketExtensionFilterProvider extensionFilterProvider;
/**
* Constructor with default configuration.
@@ -48,12 +51,26 @@ public final class DeflateFrameClientExtensionHandshaker implements WebSocketCli
* Compression level between 0 and 9 (default is 6).
*/
public DeflateFrameClientExtensionHandshaker(int compressionLevel, boolean useWebkitExtensionName) {
+ this(compressionLevel, useWebkitExtensionName, WebSocketExtensionFilterProvider.DEFAULT);
+ }
+
+ /**
+ * Constructor with custom configuration.
+ *
+ * @param compressionLevel
+ * Compression level between 0 and 9 (default is 6).
+ * @param extensionFilterProvider
+ * provides client extension filters for per frame deflate encoder and decoder.
+ */
+ public DeflateFrameClientExtensionHandshaker(int compressionLevel, boolean useWebkitExtensionName,
+ WebSocketExtensionFilterProvider extensionFilterProvider) {
if (compressionLevel < 0 || compressionLevel > 9) {
throw new IllegalArgumentException(
"compressionLevel: " + compressionLevel + " (expected: 0-9)");
}
this.compressionLevel = compressionLevel;
this.useWebkitExtensionName = useWebkitExtensionName;
+ this.extensionFilterProvider = checkNotNull(extensionFilterProvider, "extensionFilterProvider");
}
@Override
@@ -71,7 +88,7 @@ public final class DeflateFrameClientExtensionHandshaker implements WebSocketCli
}
if (extensionData.parameters().isEmpty()) {
- return new DeflateFrameClientExtension(compressionLevel);
+ return new DeflateFrameClientExtension(compressionLevel, extensionFilterProvider);
} else {
return null;
}
@@ -80,9 +97,11 @@ public final class DeflateFrameClientExtensionHandshaker implements WebSocketCli
private static class DeflateFrameClientExtension implements WebSocketClientExtension {
private final int compressionLevel;
+ private final WebSocketExtensionFilterProvider extensionFilterProvider;
- DeflateFrameClientExtension(int compressionLevel) {
+ DeflateFrameClientExtension(int compressionLevel, WebSocketExtensionFilterProvider extensionFilterProvider) {
this.compressionLevel = compressionLevel;
+ this.extensionFilterProvider = extensionFilterProvider;
}
@Override
@@ -92,12 +111,13 @@ public final class DeflateFrameClientExtensionHandshaker implements WebSocketCli
@Override
public WebSocketExtensionEncoder newExtensionEncoder() {
- return new PerFrameDeflateEncoder(compressionLevel, 15, false);
+ return new PerFrameDeflateEncoder(compressionLevel, 15, false,
+ extensionFilterProvider.encoderFilter());
}
@Override
public WebSocketExtensionDecoder newExtensionDecoder() {
- return new PerFrameDeflateDecoder(false);
+ return new PerFrameDeflateDecoder(false, extensionFilterProvider.decoderFilter());
}
}
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateFrameServerExtensionHandshaker.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateFrameServerExtensionHandshaker.java
index a463fbb755..7a06a22a65 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateFrameServerExtensionHandshaker.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/DeflateFrameServerExtensionHandshaker.java
@@ -18,11 +18,14 @@ package io.netty.handler.codec.http.websocketx.extensions.compression;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionData;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionDecoder;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionEncoder;
+import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilterProvider;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtension;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandshaker;
import java.util.Collections;
+import static io.netty.util.internal.ObjectUtil.*;
+
/**
* perframe-deflate
* handshake implementation.
@@ -33,6 +36,7 @@ public final class DeflateFrameServerExtensionHandshaker implements WebSocketSer
static final String DEFLATE_FRAME_EXTENSION = "deflate-frame";
private final int compressionLevel;
+ private final WebSocketExtensionFilterProvider extensionFilterProvider;
/**
* Constructor with default configuration.
@@ -48,11 +52,25 @@ public final class DeflateFrameServerExtensionHandshaker implements WebSocketSer
* Compression level between 0 and 9 (default is 6).
*/
public DeflateFrameServerExtensionHandshaker(int compressionLevel) {
+ this(compressionLevel, WebSocketExtensionFilterProvider.DEFAULT);
+ }
+
+ /**
+ * Constructor with custom configuration.
+ *
+ * @param compressionLevel
+ * Compression level between 0 and 9 (default is 6).
+ * @param extensionFilterProvider
+ * provides server extension filters for per frame deflate encoder and decoder.
+ */
+ public DeflateFrameServerExtensionHandshaker(int compressionLevel,
+ WebSocketExtensionFilterProvider extensionFilterProvider) {
if (compressionLevel < 0 || compressionLevel > 9) {
throw new IllegalArgumentException(
"compressionLevel: " + compressionLevel + " (expected: 0-9)");
}
this.compressionLevel = compressionLevel;
+ this.extensionFilterProvider = checkNotNull(extensionFilterProvider, "extensionFilterProvider");
}
@Override
@@ -63,7 +81,7 @@ public final class DeflateFrameServerExtensionHandshaker implements WebSocketSer
}
if (extensionData.parameters().isEmpty()) {
- return new DeflateFrameServerExtension(compressionLevel, extensionData.name());
+ return new DeflateFrameServerExtension(compressionLevel, extensionData.name(), extensionFilterProvider);
} else {
return null;
}
@@ -73,10 +91,13 @@ public final class DeflateFrameServerExtensionHandshaker implements WebSocketSer
private final String extensionName;
private final int compressionLevel;
+ private final WebSocketExtensionFilterProvider extensionFilterProvider;
- DeflateFrameServerExtension(int compressionLevel, String extensionName) {
+ DeflateFrameServerExtension(int compressionLevel, String extensionName,
+ WebSocketExtensionFilterProvider extensionFilterProvider) {
this.extensionName = extensionName;
this.compressionLevel = compressionLevel;
+ this.extensionFilterProvider = extensionFilterProvider;
}
@Override
@@ -86,12 +107,13 @@ public final class DeflateFrameServerExtensionHandshaker implements WebSocketSer
@Override
public WebSocketExtensionEncoder newExtensionEncoder() {
- return new PerFrameDeflateEncoder(compressionLevel, 15, false);
+ return new PerFrameDeflateEncoder(compressionLevel, 15, false,
+ extensionFilterProvider.encoderFilter());
}
@Override
public WebSocketExtensionDecoder newExtensionDecoder() {
- return new PerFrameDeflateDecoder(false);
+ return new PerFrameDeflateDecoder(false, extensionFilterProvider.decoderFilter());
}
@Override
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerFrameDeflateDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerFrameDeflateDecoder.java
index b80b55e730..dc15352cdf 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerFrameDeflateDecoder.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerFrameDeflateDecoder.java
@@ -20,6 +20,7 @@ import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtension;
+import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilter;
/**
* Per-frame implementation of deflate decompressor.
@@ -28,18 +29,37 @@ class PerFrameDeflateDecoder extends DeflateDecoder {
/**
* Constructor
+ *
* @param noContext true to disable context takeover.
*/
PerFrameDeflateDecoder(boolean noContext) {
- super(noContext);
+ super(noContext, WebSocketExtensionFilter.NEVER_SKIP);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param noContext true to disable context takeover.
+ * @param extensionDecoderFilter extension decoder filter for per frame deflate decoder.
+ */
+ PerFrameDeflateDecoder(boolean noContext, WebSocketExtensionFilter extensionDecoderFilter) {
+ super(noContext, extensionDecoderFilter);
}
@Override
public boolean acceptInboundMessage(Object msg) throws Exception {
- return (msg instanceof TextWebSocketFrame ||
- msg instanceof BinaryWebSocketFrame ||
+ if (!super.acceptInboundMessage(msg)) {
+ return false;
+ }
+
+ WebSocketFrame wsFrame = (WebSocketFrame) msg;
+ if (extensionDecoderFilter().mustSkip(wsFrame)) {
+ return false;
+ }
+
+ return (msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame ||
msg instanceof ContinuationWebSocketFrame) &&
- (((WebSocketFrame) msg).rsv() & WebSocketExtension.RSV1) > 0;
+ (wsFrame.rsv() & WebSocketExtension.RSV1) > 0;
}
@Override
@@ -51,4 +71,5 @@ class PerFrameDeflateDecoder extends DeflateDecoder {
protected boolean appendFrameTail(WebSocketFrame msg) {
return true;
}
+
}
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerFrameDeflateEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerFrameDeflateEncoder.java
index acee48bd3c..5da86b5d19 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerFrameDeflateEncoder.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerFrameDeflateEncoder.java
@@ -20,6 +20,7 @@ import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtension;
+import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilter;
/**
* Per-frame implementation of deflate compressor.
@@ -28,21 +29,43 @@ class PerFrameDeflateEncoder extends DeflateEncoder {
/**
* Constructor
+ *
* @param compressionLevel compression level of the compressor.
- * @param windowSize maximum size of the window compressor buffer.
- * @param noContext true to disable context takeover.
+ * @param windowSize maximum size of the window compressor buffer.
+ * @param noContext true to disable context takeover.
*/
PerFrameDeflateEncoder(int compressionLevel, int windowSize, boolean noContext) {
- super(compressionLevel, windowSize, noContext);
+ super(compressionLevel, windowSize, noContext, WebSocketExtensionFilter.NEVER_SKIP);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param compressionLevel compression level of the compressor.
+ * @param windowSize maximum size of the window compressor buffer.
+ * @param noContext true to disable context takeover.
+ * @param extensionEncoderFilter extension encoder filter for per frame deflate encoder.
+ */
+ PerFrameDeflateEncoder(int compressionLevel, int windowSize, boolean noContext,
+ WebSocketExtensionFilter extensionEncoderFilter) {
+ super(compressionLevel, windowSize, noContext, extensionEncoderFilter);
}
@Override
public boolean acceptOutboundMessage(Object msg) throws Exception {
- return (msg instanceof TextWebSocketFrame ||
- msg instanceof BinaryWebSocketFrame ||
+ if (!super.acceptOutboundMessage(msg)) {
+ return false;
+ }
+
+ WebSocketFrame wsFrame = (WebSocketFrame) msg;
+ if (extensionEncoderFilter().mustSkip(wsFrame)) {
+ return false;
+ }
+
+ return (msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame ||
msg instanceof ContinuationWebSocketFrame) &&
- ((WebSocketFrame) msg).content().readableBytes() > 0 &&
- (((WebSocketFrame) msg).rsv() & WebSocketExtension.RSV1) == 0;
+ wsFrame.content().readableBytes() > 0 &&
+ (wsFrame.rsv() & WebSocketExtension.RSV1) == 0;
}
@Override
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateClientExtensionHandshaker.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateClientExtensionHandshaker.java
index 443d6299c5..df6f5f64c5 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateClientExtensionHandshaker.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateClientExtensionHandshaker.java
@@ -15,20 +15,21 @@
*/
package io.netty.handler.codec.http.websocketx.extensions.compression;
-import static io.netty.handler.codec.http.websocketx.extensions.compression.
- PerMessageDeflateServerExtensionHandshaker.*;
-
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtension;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtensionHandshaker;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionData;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionDecoder;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionEncoder;
+import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilterProvider;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
+import static io.netty.handler.codec.http.websocketx.extensions.compression.PerMessageDeflateServerExtensionHandshaker.*;
+import static io.netty.util.internal.ObjectUtil.*;
+
/**
* permessage-deflate
* handshake implementation.
@@ -40,6 +41,7 @@ public final class PerMessageDeflateClientExtensionHandshaker implements WebSock
private final int requestedServerWindowSize;
private final boolean allowClientNoContext;
private final boolean requestedServerNoContext;
+ private final WebSocketExtensionFilterProvider extensionFilterProvider;
/**
* Constructor with default configuration.
@@ -68,6 +70,34 @@ public final class PerMessageDeflateClientExtensionHandshaker implements WebSock
public PerMessageDeflateClientExtensionHandshaker(int compressionLevel,
boolean allowClientWindowSize, int requestedServerWindowSize,
boolean allowClientNoContext, boolean requestedServerNoContext) {
+ this(compressionLevel, allowClientWindowSize, requestedServerWindowSize,
+ allowClientNoContext, requestedServerNoContext, WebSocketExtensionFilterProvider.DEFAULT);
+ }
+
+ /**
+ * Constructor with custom configuration.
+ *
+ * @param compressionLevel
+ * Compression level between 0 and 9 (default is 6).
+ * @param allowClientWindowSize
+ * allows WebSocket server to customize the client inflater window size
+ * (default is false).
+ * @param requestedServerWindowSize
+ * indicates the requested sever window size to use if server inflater is customizable.
+ * @param allowClientNoContext
+ * allows WebSocket server to activate client_no_context_takeover
+ * (default is false).
+ * @param requestedServerNoContext
+ * indicates if client needs to activate server_no_context_takeover
+ * if server is compatible with (default is false).
+ * @param extensionFilterProvider
+ * provides client extension filters for per message deflate encoder and decoder.
+ */
+ public PerMessageDeflateClientExtensionHandshaker(int compressionLevel,
+ boolean allowClientWindowSize, int requestedServerWindowSize,
+ boolean allowClientNoContext, boolean requestedServerNoContext,
+ WebSocketExtensionFilterProvider extensionFilterProvider) {
+
if (requestedServerWindowSize > MAX_WINDOW_SIZE || requestedServerWindowSize < MIN_WINDOW_SIZE) {
throw new IllegalArgumentException(
"requestedServerWindowSize: " + requestedServerWindowSize + " (expected: 8-15)");
@@ -81,6 +111,7 @@ public final class PerMessageDeflateClientExtensionHandshaker implements WebSock
this.requestedServerWindowSize = requestedServerWindowSize;
this.allowClientNoContext = allowClientNoContext;
this.requestedServerNoContext = requestedServerNoContext;
+ this.extensionFilterProvider = checkNotNull(extensionFilterProvider, "extensionFilterProvider");
}
@Override
@@ -158,7 +189,7 @@ public final class PerMessageDeflateClientExtensionHandshaker implements WebSock
if (succeed) {
return new PermessageDeflateExtension(serverNoContext, serverWindowSize,
- clientNoContext, clientWindowSize);
+ clientNoContext, clientWindowSize, extensionFilterProvider);
} else {
return null;
}
@@ -170,6 +201,7 @@ public final class PerMessageDeflateClientExtensionHandshaker implements WebSock
private final int serverWindowSize;
private final boolean clientNoContext;
private final int clientWindowSize;
+ private final WebSocketExtensionFilterProvider extensionFilterProvider;
@Override
public int rsv() {
@@ -177,21 +209,24 @@ public final class PerMessageDeflateClientExtensionHandshaker implements WebSock
}
PermessageDeflateExtension(boolean serverNoContext, int serverWindowSize,
- boolean clientNoContext, int clientWindowSize) {
+ boolean clientNoContext, int clientWindowSize,
+ WebSocketExtensionFilterProvider extensionFilterProvider) {
this.serverNoContext = serverNoContext;
this.serverWindowSize = serverWindowSize;
this.clientNoContext = clientNoContext;
this.clientWindowSize = clientWindowSize;
+ this.extensionFilterProvider = extensionFilterProvider;
}
@Override
public WebSocketExtensionEncoder newExtensionEncoder() {
- return new PerMessageDeflateEncoder(compressionLevel, clientWindowSize, clientNoContext);
+ return new PerMessageDeflateEncoder(compressionLevel, clientWindowSize, clientNoContext,
+ extensionFilterProvider.encoderFilter());
}
@Override
public WebSocketExtensionDecoder newExtensionDecoder() {
- return new PerMessageDeflateDecoder(serverNoContext);
+ return new PerMessageDeflateDecoder(serverNoContext, extensionFilterProvider.decoderFilter());
}
}
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateDecoder.java
index bfe0deb2cc..d2512bb2b6 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateDecoder.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/extensions/compression/PerMessageDeflateDecoder.java
@@ -21,6 +21,7 @@ import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtension;
+import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilter;
import java.util.List;
@@ -33,23 +34,45 @@ class PerMessageDeflateDecoder extends DeflateDecoder {
/**
* Constructor
+ *
* @param noContext true to disable context takeover.
*/
PerMessageDeflateDecoder(boolean noContext) {
- super(noContext);
+ super(noContext, WebSocketExtensionFilter.NEVER_SKIP);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param noContext true to disable context takeover.
+ * @param extensionDecoderFilter extension decoder for per message deflate decoder.
+ */
+ PerMessageDeflateDecoder(boolean noContext, WebSocketExtensionFilter extensionDecoderFilter) {
+ super(noContext, extensionDecoderFilter);
}
@Override
public boolean acceptInboundMessage(Object msg) throws Exception {
- return ((msg instanceof TextWebSocketFrame ||
- msg instanceof BinaryWebSocketFrame) &&
- (((WebSocketFrame) msg).rsv() & WebSocketExtension.RSV1) > 0) ||
- (msg instanceof ContinuationWebSocketFrame && compressing);
+ if (!super.acceptInboundMessage(msg)) {
+ return false;
+ }
+
+ WebSocketFrame wsFrame = (WebSocketFrame) msg;
+ if (extensionDecoderFilter().mustSkip(wsFrame)) {
+ if (compressing) {
+ throw new IllegalStateException("Cannot skip per message deflate decoder, compression in progress");
+ }
+ return false;
+ }
+
+ return ((wsFrame instanceof TextWebSocketFrame || wsFrame instanceof BinaryWebSocketFrame) &&
+ (wsFrame.rsv() & WebSocketExtension.RSV1) > 0) ||
+ (wsFrame instanceof ContinuationWebSocketFrame && compressing);
}
@Override
protected int newRsv(WebSocketFrame msg) {
- return (msg.rsv() & WebSocketExtension.RSV1) > 0 ?
+ return (msg.rsv() & WebSocketExtension.RSV1) > 0?
msg.rsv() ^ WebSocketExtension.RSV1 : msg.rsv();
}
@@ -60,7 +83,7 @@ class PerMessageDeflateDecoder extends DeflateDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg,
- List