This is an automated email from the ASF dual-hosted git repository.
xiazcy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/master by this push:
new 8906c4e147 TINKERPOP-2814 Remove default SSL handshake timeout.
new e9556a50f3 Merge pull request #1902 from
Bit-Quill/ken/TINKERPOP-2814-master
8906c4e147 is described below
commit 8906c4e147c963a2a5020ba1256ced850941b842
Author: Ken Hu <[email protected]>
AuthorDate: Mon Oct 17 12:21:36 2022 -0700
TINKERPOP-2814 Remove default SSL handshake timeout.
Netty's default SSL handshake timeout is removed and the handshake time
will be capped by connectionSetupTimeoutMillis instead. This allows the
SSL handshake to take up more of the overall WebSocket handshake
timeout and prevents cases where the handshake fails because the SSL
handshake time was exceeded but total handshake time would have been
less than connectionSetupTimeoutMillis.
---
CHANGELOG.asciidoc | 1 +
.../tinkerpop/gremlin/driver/Channelizer.java | 11 +++-
.../apache/tinkerpop/gremlin/driver/Cluster.java | 3 -
.../apache/tinkerpop/gremlin/driver/Settings.java | 3 -
.../driver/handler/WebSocketClientHandler.java | 29 ++++++++--
.../gremlin/driver/simple/WebSocketClient.java | 2 +-
.../WebSocketClientBehaviorIntegrateTest.java | 66 +++++++++++++++++++++-
.../gremlin/driver/NoOpWebSocketServerHandler.java | 42 ++++++++++++++
...ializer.java => TestHttpServerInitializer.java} | 15 ++---
.../gremlin/driver/TestWSNoOpInitializer.java | 33 +++++++++++
.../driver/TestWebSocketServerInitializer.java | 10 +---
11 files changed, 182 insertions(+), 33 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index fa2891a46b..3928ddac9d 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -275,6 +275,7 @@
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
* Bumped to Groovy 2.5.19.
* Bumped to Netty 4.1.85.
* Bumped `ivy` to 2.5.1 to fix security vulnerability
+* Removed default SSL handshake timeout. The SSL handshake timeout will
instead be capped by setting `connectionSetupTimeoutMillis`.
==== Bugs
diff --git
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
index 67386f6151..efe47c5977 100644
---
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
+++
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
@@ -35,6 +35,7 @@ import
io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import
io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler;
import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
@@ -86,6 +87,7 @@ public interface Channelizer extends ChannelHandler {
protected static final String PIPELINE_GREMLIN_SASL_HANDLER =
"gremlin-sasl-handler";
protected static final String PIPELINE_GREMLIN_HANDLER =
"gremlin-handler";
+ public static final String PIPELINE_SSL_HANDLER =
"gremlin-ssl-handler";
public boolean supportsSsl() {
return cluster.connectionPoolSettings().enableSsl;
@@ -124,7 +126,12 @@ public interface Channelizer extends ChannelHandler {
}
if (sslCtx.isPresent()) {
-
pipeline.addLast(sslCtx.get().newHandler(socketChannel.alloc(),
connection.getUri().getHost(), connection.getUri().getPort()));
+ SslHandler sslHandler =
sslCtx.get().newHandler(socketChannel.alloc(), connection.getUri().getHost(),
connection.getUri().getPort());
+ // TINKERPOP-2814. Remove the SSL handshake timeout so that
handshakes that take longer than 10000ms
+ // (Netty default) but less than connectionSetupTimeoutMillis
can succeed. This means the SSL handshake
+ // will instead be capped by connectionSetupTimeoutMillis.
+ sslHandler.setHandshakeTimeoutMillis(0);
+ pipeline.addLast(PIPELINE_SSL_HANDLER, sslHandler);
}
configure(pipeline);
@@ -187,7 +194,7 @@ public interface Channelizer extends ChannelHandler {
new
WebSocketClientHandler.InterceptedWebSocketClientHandshaker13(
connection.getUri(), WebSocketVersion.V13, null,
true,
httpHeaders, maxContentLength, true, false, -1,
- cluster.getHandshakeInterceptor()),
cluster.getConnectionSetupTimeout());
+ cluster.getHandshakeInterceptor()),
cluster.getConnectionSetupTimeout(), supportsSsl());
final int keepAliveInterval = toIntExact(TimeUnit.SECONDS.convert(
cluster.connectionPoolSettings().keepAliveInterval,
TimeUnit.MILLISECONDS));
diff --git
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
index 89f81905b3..18e0876df0 100644
---
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
+++
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
@@ -993,9 +993,6 @@ public final class Cluster {
/**
* Sets the duration of time in milliseconds provided for connection
setup to complete which includes WebSocket
* handshake and SSL handshake. Beyond this duration an exception
would be thrown.
- *
- * Note that this value should be greater that SSL handshake timeout
defined in
- * {@link io.netty.handler.ssl.SslHandler} since WebSocket handshake
include SSL handshake.
*/
public Builder connectionSetupTimeoutMillis(final long
connectionSetupTimeoutMillis) {
this.connectionSetupTimeoutMillis = connectionSetupTimeoutMillis;
diff --git
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
index f0164333c5..c6550d050a 100644
---
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
+++
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
@@ -407,9 +407,6 @@ final class Settings {
* Duration of time in milliseconds provided for connection setup to
complete which includes WebSocket
* handshake and SSL handshake. Beyond this duration an exception
would be thrown if the handshake is not
* complete by then.
- *
- * Note that this value should be greater that SSL handshake timeout
defined in
- * {@link io.netty.handler.ssl.SslHandler} since WebSocket handshake
include SSL handshake.
*/
public long connectionSetupTimeoutMillis =
Connection.CONNECTION_SETUP_TIMEOUT_MILLIS;
}
diff --git
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketClientHandler.java
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketClientHandler.java
index 21aba24777..82ae2fedd2 100644
---
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketClientHandler.java
+++
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketClientHandler.java
@@ -18,6 +18,7 @@
*/
package org.apache.tinkerpop.gremlin.driver.handler;
+import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
@@ -28,12 +29,18 @@ import
io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker13;
import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.util.concurrent.Promise;
import java.net.URI;
import java.util.concurrent.TimeoutException;
+import javax.net.ssl.SSLHandshakeException;
+
+import org.apache.tinkerpop.gremlin.driver.Channelizer;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.HandshakeInterceptor;
import org.slf4j.Logger;
@@ -48,10 +55,13 @@ public final class WebSocketClientHandler extends
WebSocketClientProtocolHandler
private final long connectionSetupTimeoutMillis;
private ChannelPromise handshakeFuture;
+ private boolean sslHandshakeCompleted;
+ private boolean useSsl;
- public WebSocketClientHandler(final WebSocketClientHandshaker handshaker,
final long timeoutMillis) {
+ public WebSocketClientHandler(final WebSocketClientHandshaker handshaker,
final long timeoutMillis, final boolean useSsl) {
super(handshaker, /*handleCloseFrames*/true, /*dropPongFrames*/true,
timeoutMillis);
this.connectionSetupTimeoutMillis = timeoutMillis;
+ this.useSsl = useSsl;
}
public ChannelFuture handshakeFuture() {
@@ -104,10 +114,21 @@ public final class WebSocketClientHandler extends
WebSocketClientProtocolHandler
}
} else if (ClientHandshakeStateEvent.HANDSHAKE_TIMEOUT.equals(event)) {
if (!handshakeFuture.isDone()) {
- handshakeFuture.setFailure(
- new TimeoutException(String.format("handshake not
completed in stipulated time=[%s]ms",
- connectionSetupTimeoutMillis)));
+ TimeoutException te = new TimeoutException(
+ String.format((useSsl && !sslHandshakeCompleted) ?
+ "SSL handshake not completed in
stipulated time=[%s]ms" :
+ "WebSocket handshake not completed in
stipulated time=[%s]ms",
+ connectionSetupTimeoutMillis));
+ handshakeFuture.setFailure(te);
+ logger.error(te.getMessage());
+ }
+
+ if (useSsl && !sslHandshakeCompleted) {
+ SslHandler handler = ((SslHandler)
ctx.pipeline().get(Channelizer.AbstractChannelizer.PIPELINE_SSL_HANDLER));
+ ((Promise<Channel>) handler.handshakeFuture()).tryFailure(new
SSLHandshakeException("SSL handshake timed out."));
}
+ } else if (event instanceof SslHandshakeCompletionEvent) {
+ sslHandshakeCompleted = true;
} else {
super.userEventTriggered(ctx, event);
}
diff --git
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/simple/WebSocketClient.java
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/simple/WebSocketClient.java
index 767f5a86a5..78f42686fa 100644
---
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/simple/WebSocketClient.java
+++
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/simple/WebSocketClient.java
@@ -69,7 +69,7 @@ public class WebSocketClient extends AbstractClient {
try {
final WebSocketClientHandler wsHandler = new
WebSocketClientHandler(WebSocketClientHandshakerFactory.newHandshaker(
- uri, WebSocketVersion.V13, null, true,
EmptyHttpHeaders.INSTANCE, 65536), 10000);
+ uri, WebSocketVersion.V13, null, true,
EmptyHttpHeaders.INSTANCE, 65536), 10000, false);
final MessageSerializer<GraphBinaryMapper> serializer = new
GraphBinaryMessageSerializerV1();
b.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
diff --git
a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/WebSocketClientBehaviorIntegrateTest.java
b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/WebSocketClientBehaviorIntegrateTest.java
index 4037641b68..6fbc3f6940 100644
---
a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/WebSocketClientBehaviorIntegrateTest.java
+++
b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/WebSocketClientBehaviorIntegrateTest.java
@@ -29,6 +29,7 @@ import org.junit.Test;
import org.junit.rules.TestName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.tinkerpop.gremlin.driver.exception.NoHostAvailableException;
import org.apache.tinkerpop.gremlin.driver.ser.Serializers;
import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -45,6 +46,7 @@ import static org.hamcrest.core.Is.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
public class WebSocketClientBehaviorIntegrateTest {
private static final Logger logger =
LoggerFactory.getLogger(WebSocketClientBehaviorIntegrateTest.class);
@@ -77,7 +79,12 @@ public class WebSocketClientBehaviorIntegrateTest {
logCaptor.clearLogs();
server = new SimpleSocketServer(settings);
- server.start(new TestWSGremlinInitializer(settings));
+ if
(name.getMethodName().equals("shouldAttemptHandshakeForLongerThanDefaultNettySslHandshakeTimeout")
||
+
name.getMethodName().equals("shouldPrintCorrectErrorForRegularWebSocketHandshakeTimeout"))
{
+ server.start(new TestWSNoOpInitializer());
+ } else {
+ server.start(new TestWSGremlinInitializer(settings));
+ }
}
@After
@@ -302,4 +309,59 @@ public class WebSocketClientBehaviorIntegrateTest {
assertEquals("No new connection creation should be started", 0,
logCaptor.getLogs().stream().filter(str ->
str.contains("Considering new connection on")).count());
}
-}
\ No newline at end of file
+
+ /**
+ * (TINKERPOP-2814) Tests to make sure that the SSL handshake is now
capped by connectionSetupTimeoutMillis and not
+ * the default Netty SSL handshake timeout of 10,000ms.
+ */
+ @Test
+ public void
shouldAttemptHandshakeForLongerThanDefaultNettySslHandshakeTimeout() {
+ final Cluster cluster = Cluster.build("localhost").port(settings.PORT)
+ .minConnectionPoolSize(1)
+ .maxConnectionPoolSize(1)
+ .connectionSetupTimeoutMillis(20000) // needs to be larger
than 10000ms.
+ .enableSsl(true)
+ .create();
+
+ final Client.ClusteredClient client = cluster.connect();
+ final long start = System.currentTimeMillis();
+
+ Exception caught = null;
+ try {
+ client.submit("1");
+ } catch (Exception e) {
+ caught = e;
+ } finally {
+ // Test against 15000ms which should give a big enough buffer to
avoid timing issues.
+ assertTrue(System.currentTimeMillis() - start > 15000);
+ assertTrue(caught != null);
+ assertTrue(caught instanceof NoHostAvailableException);
+ assertTrue(logCaptor.getLogs().stream().anyMatch(str ->
str.contains("SSL handshake not completed")));
+ }
+ }
+
+ /**
+ * Tests to make sure that the correct error message is logged when a
non-SSL connection attempt times out.
+ */
+ @Test
+ public void shouldPrintCorrectErrorForRegularWebSocketHandshakeTimeout() {
+ final Cluster cluster = Cluster.build("localhost").port(settings.PORT)
+ .minConnectionPoolSize(1)
+ .maxConnectionPoolSize(1)
+ .connectionSetupTimeoutMillis(100)
+ .create();
+
+ final Client.ClusteredClient client = cluster.connect();
+
+ Exception caught = null;
+ try {
+ client.submit("1");
+ } catch (Exception e) {
+ caught = e;
+ } finally {
+ assertTrue(caught != null);
+ assertTrue(caught instanceof NoHostAvailableException);
+ assertTrue(logCaptor.getLogs().stream().anyMatch(str ->
str.contains("WebSocket handshake not completed")));
+ }
+ }
+}
diff --git
a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/NoOpWebSocketServerHandler.java
b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/NoOpWebSocketServerHandler.java
new file mode 100644
index 0000000000..8c22c723fa
--- /dev/null
+++
b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/NoOpWebSocketServerHandler.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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 org.apache.tinkerpop.gremlin.driver;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.handler.codec.http.HttpRequest;
+import io.netty.util.ReferenceCountUtil;
+
+/**
+* Handler that will drop requests to the WebSocket path.
+*/
+public class NoOpWebSocketServerHandler extends ChannelInboundHandlerAdapter {
+ private String websocketPath;
+
+ public NoOpWebSocketServerHandler(String websocketPath) {
+ this.websocketPath = websocketPath;
+ }
+
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) {
+ if ((msg instanceof HttpRequest) && ((HttpRequest)
msg).uri().endsWith(websocketPath)) {
+ ReferenceCountUtil.release(msg);
+ }
+ }
+}
diff --git
a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWebSocketServerInitializer.java
b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestHttpServerInitializer.java
similarity index 63%
copy from
gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWebSocketServerInitializer.java
copy to
gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestHttpServerInitializer.java
index 7857ae9ac1..9985b70353 100644
---
a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWebSocketServerInitializer.java
+++
b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestHttpServerInitializer.java
@@ -23,25 +23,18 @@ import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
-import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
-import
io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
/**
- * A vanilla WebSocket server Initializer implementation using Netty. This
initializer would configure the server for
- * WebSocket handshake and decoding incoming WebSocket frames.
+ * A base ChannelInitializer that setups the pipeline for HTTP handling. This
class should be sub-classed by a handler
+ * that handles the actual data being received.
*/
-public abstract class TestWebSocketServerInitializer extends
ChannelInitializer<SocketChannel> {
- private static final String WEBSOCKET_PATH = "/gremlin";
+public class TestHttpServerInitializer extends
ChannelInitializer<SocketChannel> {
+ protected static final String WEBSOCKET_PATH = "/gremlin";
@Override
public void initChannel(SocketChannel ch) {
final ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
- pipeline.addLast(new WebSocketServerCompressionHandler());
- pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH,
null, true));
- this.postInit(ch.pipeline());
}
-
- public abstract void postInit(final ChannelPipeline ch);
}
diff --git
a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWSNoOpInitializer.java
b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWSNoOpInitializer.java
new file mode 100644
index 0000000000..268144a7af
--- /dev/null
+++
b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWSNoOpInitializer.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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 org.apache.tinkerpop.gremlin.driver;
+
+import io.netty.channel.socket.SocketChannel;
+
+/**
+ * An initializer that adds a handler that will drop WebSocket frames.
+ */
+public class TestWSNoOpInitializer extends TestHttpServerInitializer {
+
+ @Override
+ public void initChannel(SocketChannel ch) {
+ super.initChannel(ch);
+ ch.pipeline().addLast(new NoOpWebSocketServerHandler(WEBSOCKET_PATH));
+ }
+}
diff --git
a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWebSocketServerInitializer.java
b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWebSocketServerInitializer.java
index 7857ae9ac1..adfa723549 100644
---
a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWebSocketServerInitializer.java
+++
b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/driver/TestWebSocketServerInitializer.java
@@ -18,11 +18,8 @@
*/
package org.apache.tinkerpop.gremlin.driver;
-import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
-import io.netty.handler.codec.http.HttpObjectAggregator;
-import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import
io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
@@ -30,14 +27,13 @@ import
io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketSe
* A vanilla WebSocket server Initializer implementation using Netty. This
initializer would configure the server for
* WebSocket handshake and decoding incoming WebSocket frames.
*/
-public abstract class TestWebSocketServerInitializer extends
ChannelInitializer<SocketChannel> {
- private static final String WEBSOCKET_PATH = "/gremlin";
+public abstract class TestWebSocketServerInitializer extends
TestHttpServerInitializer {
@Override
public void initChannel(SocketChannel ch) {
+ super.initChannel(ch);
+
final ChannelPipeline pipeline = ch.pipeline();
- pipeline.addLast(new HttpServerCodec());
- pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH,
null, true));
this.postInit(ch.pipeline());