From 5985af1f48d56b601f4f2c36fb810aad90d07718 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Wed, 16 Feb 2022 10:44:50 +0200 Subject: [PATCH 01/21] next development iteration --- README.md | 4 ++-- gradle.properties | 2 +- .../codec/http2/websocketx/example/channelclient/Main.java | 2 +- .../codec/http2/websocketx/example/lwsclient/Main.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 67965ae..7057eab 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ EchoWebSocketHandler http1WebSocketHandler = new EchoWebSocketHandler(); Http2WebSocketClientHandshaker handShaker = Http2WebSocketClientHandshaker.create(channel); Http2Headers headers = - new DefaultHttp2Headers().set("user-agent", "jauntsdn-websocket-http2-client/1.1.3"); + new DefaultHttp2Headers().set("user-agent", "jauntsdn-websocket-http2-client/1.1.4"); ChannelFuture handshakeFuture = /*http1 websocket handler*/ handShaker.handshake("/echo", headers, new EchoWebSocketHandler()); @@ -269,7 +269,7 @@ repositories { } dependencies { - implementation 'com.jauntsdn.netty:netty-websocket-http2:1.1.3' + implementation 'com.jauntsdn.netty:netty-websocket-http2:1.1.4' } ``` diff --git a/gradle.properties b/gradle.properties index ca0794e..a8648aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group=com.jauntsdn.netty -version=1.1.4 +version=1.1.5 googleJavaFormatPluginVersion=0.9 dependencyManagementPluginVersion=1.0.11.RELEASE diff --git a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/channelclient/Main.java b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/channelclient/Main.java index 1ceb462..2de566b 100644 --- a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/channelclient/Main.java +++ b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/channelclient/Main.java @@ -93,7 +93,7 @@ protected void initChannel(SocketChannel ch) { Http2WebSocketClientHandshaker handShaker = Http2WebSocketClientHandshaker.create(channel); Http2Headers headers = - new DefaultHttp2Headers().set("user-agent", "jauntsdn-websocket-http2-client/1.1.2"); + new DefaultHttp2Headers().set("user-agent", "jauntsdn-websocket-http2-client/1.1.4"); ChannelFuture handshake = handShaker.handshake("/echo", "echo.jauntsdn.com", headers, new EchoWebSocketHandler()); diff --git a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/lwsclient/Main.java b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/lwsclient/Main.java index 5b8c490..e81facd 100644 --- a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/lwsclient/Main.java +++ b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/lwsclient/Main.java @@ -90,7 +90,7 @@ protected void initChannel(SocketChannel ch) { Http2WebSocketClientHandshaker handShaker = Http2WebSocketClientHandshaker.create(channel); Http2Headers headers = - new DefaultHttp2Headers().set("user-agent", "jauntsdn-websocket-http2-client/1.1.2"); + new DefaultHttp2Headers().set("user-agent", "jauntsdn-websocket-http2-client/1.1.4"); ChannelFuture handshake = handShaker.handshake( "/", "dumb-increment-protocol", headers, new WebSocketDumbIncrementHandler()); From aacfa8d37f05dc16b50fe7c3fb89191e6f9ad52a Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Thu, 28 Apr 2022 14:28:15 +0300 Subject: [PATCH 02/21] update dependencies --- .gitignore | 2 ++ gradle.properties | 6 ++-- .../compileClasspath.lockfile | 22 +++++++-------- .../compileClasspath.lockfile | 28 +++++++++---------- .../compileClasspath.lockfile | 17 ++++++----- .../runtimeClasspath.lockfile | 12 ++++++++ .../testCompileClasspath.lockfile | 17 ++++++----- .../testRuntimeClasspath.lockfile | 22 +++++++-------- 8 files changed, 69 insertions(+), 57 deletions(-) create mode 100644 netty-websocket-http2/gradle/dependency-locks/runtimeClasspath.lockfile diff --git a/.gitignore b/.gitignore index 642dda5..ea1523a 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,5 @@ infer-out */.inferConfig */src/generated/* + +bin diff --git a/gradle.properties b/gradle.properties index a8648aa..b3d5019 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,15 +3,15 @@ version=1.1.5 googleJavaFormatPluginVersion=0.9 dependencyManagementPluginVersion=1.0.11.RELEASE -gitPluginVersion=0.13.0 +gitPluginVersion=0.15.0 osDetectorPluginVersion=1.7.0 versionsPluginVersion=0.42.0 -nettyVersion=4.1.74.Final +nettyVersion=4.1.76.Final nettyTcnativeVersion=2.0.48.Final hdrHistogramVersion=2.1.12 slf4jVersion=1.7.36 -logbackVersion=1.2.10 +logbackVersion=1.2.11 jsr305Version=3.0.2 junitVersion=5.8.2 diff --git a/netty-websocket-http2-example/gradle/dependency-locks/compileClasspath.lockfile b/netty-websocket-http2-example/gradle/dependency-locks/compileClasspath.lockfile index e69a2b2..f30c59d 100644 --- a/netty-websocket-http2-example/gradle/dependency-locks/compileClasspath.lockfile +++ b/netty-websocket-http2-example/gradle/dependency-locks/compileClasspath.lockfile @@ -1,16 +1,16 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.10 -ch.qos.logback:logback-core:1.2.10 -io.netty:netty-buffer:4.1.74.Final -io.netty:netty-codec-http2:4.1.74.Final -io.netty:netty-codec-http:4.1.74.Final -io.netty:netty-codec:4.1.74.Final -io.netty:netty-common:4.1.74.Final -io.netty:netty-handler:4.1.74.Final -io.netty:netty-resolver:4.1.74.Final +ch.qos.logback:logback-classic:1.2.11 +ch.qos.logback:logback-core:1.2.11 +io.netty:netty-buffer:4.1.76.Final +io.netty:netty-codec-http2:4.1.76.Final +io.netty:netty-codec-http:4.1.76.Final +io.netty:netty-codec:4.1.76.Final +io.netty:netty-common:4.1.76.Final +io.netty:netty-handler:4.1.76.Final +io.netty:netty-resolver:4.1.76.Final io.netty:netty-tcnative-boringssl-static:2.0.48.Final -io.netty:netty-tcnative-classes:2.0.48.Final -io.netty:netty-transport:4.1.74.Final +io.netty:netty-tcnative-classes:2.0.51.Final +io.netty:netty-transport:4.1.76.Final org.slf4j:slf4j-api:1.7.36 diff --git a/netty-websocket-http2-perftest/gradle/dependency-locks/compileClasspath.lockfile b/netty-websocket-http2-perftest/gradle/dependency-locks/compileClasspath.lockfile index 118db87..6b08a35 100644 --- a/netty-websocket-http2-perftest/gradle/dependency-locks/compileClasspath.lockfile +++ b/netty-websocket-http2-perftest/gradle/dependency-locks/compileClasspath.lockfile @@ -1,20 +1,20 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.10 -ch.qos.logback:logback-core:1.2.10 -io.netty:netty-buffer:4.1.74.Final -io.netty:netty-codec-http2:4.1.74.Final -io.netty:netty-codec-http:4.1.74.Final -io.netty:netty-codec:4.1.74.Final -io.netty:netty-common:4.1.74.Final -io.netty:netty-handler:4.1.74.Final -io.netty:netty-resolver:4.1.74.Final +ch.qos.logback:logback-classic:1.2.11 +ch.qos.logback:logback-core:1.2.11 +io.netty:netty-buffer:4.1.76.Final +io.netty:netty-codec-http2:4.1.76.Final +io.netty:netty-codec-http:4.1.76.Final +io.netty:netty-codec:4.1.76.Final +io.netty:netty-common:4.1.76.Final +io.netty:netty-handler:4.1.76.Final +io.netty:netty-resolver:4.1.76.Final io.netty:netty-tcnative-boringssl-static:2.0.48.Final -io.netty:netty-tcnative-classes:2.0.48.Final -io.netty:netty-transport-classes-epoll:4.1.74.Final -io.netty:netty-transport-native-epoll:4.1.74.Final -io.netty:netty-transport-native-unix-common:4.1.74.Final -io.netty:netty-transport:4.1.74.Final +io.netty:netty-tcnative-classes:2.0.51.Final +io.netty:netty-transport-classes-epoll:4.1.76.Final +io.netty:netty-transport-native-epoll:4.1.76.Final +io.netty:netty-transport-native-unix-common:4.1.76.Final +io.netty:netty-transport:4.1.76.Final org.hdrhistogram:HdrHistogram:2.1.12 org.slf4j:slf4j-api:1.7.36 diff --git a/netty-websocket-http2/gradle/dependency-locks/compileClasspath.lockfile b/netty-websocket-http2/gradle/dependency-locks/compileClasspath.lockfile index 1345f2d..4c0710d 100644 --- a/netty-websocket-http2/gradle/dependency-locks/compileClasspath.lockfile +++ b/netty-websocket-http2/gradle/dependency-locks/compileClasspath.lockfile @@ -2,13 +2,12 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. com.google.code.findbugs:jsr305:3.0.2 -io.netty:netty-buffer:4.1.74.Final -io.netty:netty-codec-http2:4.1.74.Final -io.netty:netty-codec-http:4.1.74.Final -io.netty:netty-codec:4.1.74.Final -io.netty:netty-common:4.1.74.Final -io.netty:netty-handler:4.1.74.Final -io.netty:netty-resolver:4.1.74.Final -io.netty:netty-tcnative-classes:2.0.48.Final -io.netty:netty-transport:4.1.74.Final +io.netty:netty-buffer:4.1.76.Final +io.netty:netty-codec-http2:4.1.76.Final +io.netty:netty-codec-http:4.1.76.Final +io.netty:netty-codec:4.1.76.Final +io.netty:netty-common:4.1.76.Final +io.netty:netty-handler:4.1.76.Final +io.netty:netty-resolver:4.1.76.Final +io.netty:netty-transport:4.1.76.Final org.slf4j:slf4j-api:1.7.36 diff --git a/netty-websocket-http2/gradle/dependency-locks/runtimeClasspath.lockfile b/netty-websocket-http2/gradle/dependency-locks/runtimeClasspath.lockfile new file mode 100644 index 0000000..d121a72 --- /dev/null +++ b/netty-websocket-http2/gradle/dependency-locks/runtimeClasspath.lockfile @@ -0,0 +1,12 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +io.netty:netty-buffer:4.1.76.Final +io.netty:netty-codec-http2:4.1.76.Final +io.netty:netty-codec-http:4.1.76.Final +io.netty:netty-codec:4.1.76.Final +io.netty:netty-common:4.1.76.Final +io.netty:netty-handler:4.1.76.Final +io.netty:netty-resolver:4.1.76.Final +io.netty:netty-transport:4.1.76.Final +org.slf4j:slf4j-api:1.7.36 diff --git a/netty-websocket-http2/gradle/dependency-locks/testCompileClasspath.lockfile b/netty-websocket-http2/gradle/dependency-locks/testCompileClasspath.lockfile index bbdba8a..3867a53 100644 --- a/netty-websocket-http2/gradle/dependency-locks/testCompileClasspath.lockfile +++ b/netty-websocket-http2/gradle/dependency-locks/testCompileClasspath.lockfile @@ -1,15 +1,14 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -io.netty:netty-buffer:4.1.74.Final -io.netty:netty-codec-http2:4.1.74.Final -io.netty:netty-codec-http:4.1.74.Final -io.netty:netty-codec:4.1.74.Final -io.netty:netty-common:4.1.74.Final -io.netty:netty-handler:4.1.74.Final -io.netty:netty-resolver:4.1.74.Final -io.netty:netty-tcnative-classes:2.0.48.Final -io.netty:netty-transport:4.1.74.Final +io.netty:netty-buffer:4.1.76.Final +io.netty:netty-codec-http2:4.1.76.Final +io.netty:netty-codec-http:4.1.76.Final +io.netty:netty-codec:4.1.76.Final +io.netty:netty-common:4.1.76.Final +io.netty:netty-handler:4.1.76.Final +io.netty:netty-resolver:4.1.76.Final +io.netty:netty-transport:4.1.76.Final org.apiguardian:apiguardian-api:1.1.2 org.assertj:assertj-core:3.22.0 org.junit.jupiter:junit-jupiter-api:5.8.2 diff --git a/netty-websocket-http2/gradle/dependency-locks/testRuntimeClasspath.lockfile b/netty-websocket-http2/gradle/dependency-locks/testRuntimeClasspath.lockfile index 674eb31..0aba0e9 100644 --- a/netty-websocket-http2/gradle/dependency-locks/testRuntimeClasspath.lockfile +++ b/netty-websocket-http2/gradle/dependency-locks/testRuntimeClasspath.lockfile @@ -1,18 +1,18 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.10 -ch.qos.logback:logback-core:1.2.10 -io.netty:netty-buffer:4.1.74.Final -io.netty:netty-codec-http2:4.1.74.Final -io.netty:netty-codec-http:4.1.74.Final -io.netty:netty-codec:4.1.74.Final -io.netty:netty-common:4.1.74.Final -io.netty:netty-handler:4.1.74.Final -io.netty:netty-resolver:4.1.74.Final +ch.qos.logback:logback-classic:1.2.11 +ch.qos.logback:logback-core:1.2.11 +io.netty:netty-buffer:4.1.76.Final +io.netty:netty-codec-http2:4.1.76.Final +io.netty:netty-codec-http:4.1.76.Final +io.netty:netty-codec:4.1.76.Final +io.netty:netty-common:4.1.76.Final +io.netty:netty-handler:4.1.76.Final +io.netty:netty-resolver:4.1.76.Final io.netty:netty-tcnative-boringssl-static:2.0.48.Final -io.netty:netty-tcnative-classes:2.0.48.Final -io.netty:netty-transport:4.1.74.Final +io.netty:netty-tcnative-classes:2.0.51.Final +io.netty:netty-transport:4.1.76.Final org.assertj:assertj-core:3.22.0 org.junit.jupiter:junit-jupiter-api:5.8.2 org.junit.jupiter:junit-jupiter-engine:5.8.2 From 3543ce8c48259db2230759677ecdf9ca1ac6053d Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Tue, 10 May 2022 00:15:52 +0300 Subject: [PATCH 03/21] example for http1 & http2 websockets on the same port --- README.md | 1 + multiprotocol_client.sh | 3 + multiprotocol_server.sh | 3 + netty-websocket-http2-example/build.gradle | 11 + .../http2/websocketx/example/Security.java | 25 +- .../example/channelclient/Main.java | 2 +- .../websocketx/example/lwsclient/Main.java | 2 +- .../example/multiprotocolclient/Main.java | 281 ++++++++++++++++++ .../example/multiprotocolserver/Main.java | 208 +++++++++++++ 9 files changed, 529 insertions(+), 7 deletions(-) create mode 100644 multiprotocol_client.sh create mode 100644 multiprotocol_server.sh create mode 100644 netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/multiprotocolclient/Main.java create mode 100644 netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/multiprotocolserver/Main.java diff --git a/README.md b/README.md index 7057eab..dd37a1e 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,7 @@ the results are as follows (measured over time spans of 5 seconds): * `channelserver, channelclient` packages for websocket subchannel API demos. * `handshakeserver, channelclient` packages for handshake only API demo. +* `multiprotocolserver, multiprotocolclient` packages for demo of server handling htt1/http2 websockets on the same port. * `lwsclient` package for client demo that runs against [https://libwebsockets.org/testserver/](https://libwebsockets.org/testserver/) which hosts websocket-over-http2 server implemented with [libwebsockets](https://github.com/warmcat/libwebsockets) - popular C-based networking library. diff --git a/multiprotocol_client.sh b/multiprotocol_client.sh new file mode 100644 index 0000000..283d028 --- /dev/null +++ b/multiprotocol_client.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +./gradlew netty-websocket-http2-example:runMultiProtocolClient \ No newline at end of file diff --git a/multiprotocol_server.sh b/multiprotocol_server.sh new file mode 100644 index 0000000..5a30c39 --- /dev/null +++ b/multiprotocol_server.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +./gradlew netty-websocket-http2-example:runMultiProtocolServer \ No newline at end of file diff --git a/netty-websocket-http2-example/build.gradle b/netty-websocket-http2-example/build.gradle index 857308a..3a207d9 100644 --- a/netty-websocket-http2-example/build.gradle +++ b/netty-websocket-http2-example/build.gradle @@ -36,6 +36,11 @@ task runChannelServer(type: JavaExec) { main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.channelserver.Main" } +task runMultiProtocolServer(type: JavaExec) { + classpath = sourceSets.main.runtimeClasspath + main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.multiprotocolserver.Main" +} + task runChannelClient(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.channelclient.Main" @@ -45,3 +50,9 @@ task runLwsClient(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.lwsclient.Main" } + +task runMultiProtocolClient(type: JavaExec) { + classpath = sourceSets.main.runtimeClasspath + main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.multiprotocolclient.Main" +} + diff --git a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/Security.java b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/Security.java index 2b8d41d..0fa8a20 100644 --- a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/Security.java +++ b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/Security.java @@ -41,16 +41,23 @@ public static SslContext serverSslContext(String keystoreFile, String keystorePa return SslContextBuilder.forServer(keyManagerFactory) .protocols("TLSv1.3") .sslProvider(sslProvider) - .applicationProtocolConfig(alpnConfig()) + .applicationProtocolConfig(alpnConfigHttp2()) .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE) .build(); } - public static SslContext clientLocalSslContext() throws SSLException { + public static SslContext clientLocalSslContextHttp2() throws SSLException { return clientSslContextBuilder().trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } - public static SslContext clientSslContext() throws SSLException { + public static SslContext clientLocalSslContextHttp1() throws SSLException { + return clientSslContextBuilder() + .trustManager(InsecureTrustManagerFactory.INSTANCE) + .applicationProtocolConfig(alpnConfigHttp1()) + .build(); + } + + public static SslContext clientSslContextHttp2() throws SSLException { return clientSslContextBuilder().build(); } @@ -58,11 +65,11 @@ private static SslContextBuilder clientSslContextBuilder() throws SSLException { return SslContextBuilder.forClient() .protocols("TLSv1.3") .sslProvider(sslProvider()) - .applicationProtocolConfig(alpnConfig()) + .applicationProtocolConfig(alpnConfigHttp2()) .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE); } - private static ApplicationProtocolConfig alpnConfig() { + private static ApplicationProtocolConfig alpnConfigHttp2() { return new ApplicationProtocolConfig( ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, @@ -70,6 +77,14 @@ private static ApplicationProtocolConfig alpnConfig() { ApplicationProtocolNames.HTTP_2); } + private static ApplicationProtocolConfig alpnConfigHttp1() { + return new ApplicationProtocolConfig( + ApplicationProtocolConfig.Protocol.ALPN, + ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, + ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, + ApplicationProtocolNames.HTTP_1_1); + } + private static SslProvider sslProvider() { final SslProvider sslProvider; if (OpenSsl.isAvailable()) { diff --git a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/channelclient/Main.java b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/channelclient/Main.java index 2de566b..e708019 100644 --- a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/channelclient/Main.java +++ b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/channelclient/Main.java @@ -50,7 +50,7 @@ public static void main(String[] args) throws Exception { logger.info("\n==> Channel per websocket client\n"); logger.info("\n==> Remote address: {}:{}", host, port); - final SslContext sslContext = Security.clientLocalSslContext(); + final SslContext sslContext = Security.clientLocalSslContextHttp2(); Channel channel = new Bootstrap() .group(new NioEventLoopGroup()) diff --git a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/lwsclient/Main.java b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/lwsclient/Main.java index e81facd..d5b0941 100644 --- a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/lwsclient/Main.java +++ b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/lwsclient/Main.java @@ -55,7 +55,7 @@ public static void main(String[] args) throws Exception { logger.info("\n==> Remote address: {}:{}", host, port); logger.info("\n==> Dumb increment demo of https://libwebsockets.org/testserver/"); - final SslContext sslContext = Security.clientSslContext(); + SslContext sslContext = Security.clientSslContextHttp2(); Channel channel = new Bootstrap() .group(new NioEventLoopGroup()) diff --git a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/multiprotocolclient/Main.java b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/multiprotocolclient/Main.java new file mode 100644 index 0000000..c076456 --- /dev/null +++ b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/multiprotocolclient/Main.java @@ -0,0 +1,281 @@ +/* + * Copyright 2022 - present Maksym Ostroverkhov. + * + * Licensed 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 com.jauntsdn.netty.handler.codec.http2.websocketx.example.multiprotocolclient; + +import com.jauntsdn.netty.handler.codec.http2.websocketx.Http2WebSocketClientBuilder; +import com.jauntsdn.netty.handler.codec.http2.websocketx.Http2WebSocketClientHandler; +import com.jauntsdn.netty.handler.codec.http2.websocketx.Http2WebSocketClientHandshaker; +import com.jauntsdn.netty.handler.codec.http2.websocketx.example.Security; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.http.*; +import io.netty.handler.codec.http.websocketx.*; +import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler; +import io.netty.handler.codec.http2.DefaultHttp2Headers; +import io.netty.handler.codec.http2.Http2FrameCodec; +import io.netty.handler.codec.http2.Http2FrameCodecBuilder; +import io.netty.handler.codec.http2.Http2Headers; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslHandler; +import io.netty.util.ReferenceCounted; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.channels.ClosedChannelException; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Main { + private static final Logger logger = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) throws Exception { + String host = System.getProperty("HOST", "localhost"); + int port = Integer.parseInt(System.getProperty("PORT", "8099")); + InetSocketAddress address = new InetSocketAddress(host, port); + + logger.info("\n==> Websocket-over-http1 and websocket-over-http2 clients\n"); + logger.info("\n==> Remote address: {}:{}", host, port); + + EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); + SslContext http2SslContext = Security.clientLocalSslContextHttp2(); + SslContext http1SslContext = Security.clientLocalSslContextHttp1(); + + EchoWebSocketHandler echoWebSocketHandler = new EchoWebSocketHandler(); + + WebSocketDecoderConfig decoderConfig = + WebSocketDecoderConfig.newBuilder() + .expectMaskedFrames(false) + .allowMaskMismatch(false) + .allowExtensions(true) + .build(); + + Channel http2Channel = + new Bootstrap() + .group(eventLoopGroup) + .channel(NioSocketChannel.class) + .handler( + new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) { + SslHandler sslHandler = http2SslContext.newHandler(ch.alloc()); + Http2FrameCodecBuilder frameCodecBuilder = Http2FrameCodecBuilder.forClient(); + frameCodecBuilder.initialSettings().initialWindowSize(1_000); + Http2FrameCodec http2FrameCodec = frameCodecBuilder.build(); + + Http2WebSocketClientHandler http2WebSocketClientHandler = + Http2WebSocketClientBuilder.create() + .decoderConfig(decoderConfig) + .handshakeTimeoutMillis(15_000) + .compression(true) + .build(); + + ch.pipeline().addLast(sslHandler, http2FrameCodec, http2WebSocketClientHandler); + } + }) + .connect(address) + .sync() + .channel(); + + /*wait until channel is ready (future completes)*/ + Http2WebSocketClientHandshaker http2WebSocketHandShaker = + Http2WebSocketClientHandshaker.create(http2Channel); + + Http2Headers http2Headers = + new DefaultHttp2Headers().set("user-agent", "jauntsdn-websocket-http2-client/1.1.4"); + ChannelFuture http2WebSocketHandshake = + http2WebSocketHandShaker.handshake( + "/echo", "echo.jauntsdn.com", http2Headers, echoWebSocketHandler); + + Channel http2WebSocketChannel = http2WebSocketHandshake.channel(); + + /*send websocket frames*/ + http2WebSocketChannel + .eventLoop() + .scheduleAtFixedRate( + () -> + http2WebSocketChannel.writeAndFlush( + new TextWebSocketFrame("hello http2 websocket")), + 0, + 2_000, + TimeUnit.MILLISECONDS); + + HttpHeaders http1Headers = + new DefaultHttpHeaders().set("user-agent", "jauntsdn-websocket-http1-client/1.1.4"); + + Http1WebSocketHandshaker http1WebSocketHandshaker = + new Http1WebSocketHandshaker( + "/echo", "echo.jauntsdn.com", http1Headers, decoderConfig, host, port); + + Channel http1Channel = + new Bootstrap() + .group(eventLoopGroup) + .channel(NioSocketChannel.class) + .handler( + new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) { + SslHandler sslHandler = http1SslContext.newHandler(ch.alloc()); + HttpClientCodec http1Codec = new HttpClientCodec(); + HttpObjectAggregator http1Aggregator = new HttpObjectAggregator(65536); + WebSocketClientCompressionHandler http1WebSocketCompressionHandler = + WebSocketClientCompressionHandler.INSTANCE; + + ch.pipeline() + .addLast( + sslHandler, + http1Codec, + http1Aggregator, + http1WebSocketCompressionHandler, + http1WebSocketHandshaker, + echoWebSocketHandler); + } + }) + .connect(address) + .sync() + .channel(); + + /* wait until channel is ready (future completes)*/ + http1WebSocketHandshaker.handshakeComplete().sync(); + + /*send websocket frames*/ + http1Channel + .eventLoop() + .scheduleAtFixedRate( + () -> http1Channel.writeAndFlush(new TextWebSocketFrame("hello http1 websocket")), + 1_000, + 2_000, + TimeUnit.MILLISECONDS); + + http2WebSocketChannel.closeFuture().sync(); + logger.info("==> Http2 websocket closed. Terminating client..."); + http2WebSocketChannel.eventLoop().shutdownGracefully(); + logger.info("==> Client terminated"); + } + + private static class Http1WebSocketHandshaker extends SimpleChannelInboundHandler { + private final WebSocketClientHandshaker handshaker; + private ChannelPromise handshakeComplete; + + public Http1WebSocketHandshaker( + String path, + String subprotocol, + HttpHeaders headers, + WebSocketDecoderConfig webSocketDecoderConfig, + String host, + int port) { + handshaker = + WebSocketClientHandshakerFactory.newHandshaker( + uri("wss://" + host + ":" + port + path), + WebSocketVersion.V13, + subprotocol, + webSocketDecoderConfig.allowExtensions(), + headers, + webSocketDecoderConfig.maxFramePayloadLength(), + true, + webSocketDecoderConfig.allowMaskMismatch()); + } + + public ChannelFuture handshakeComplete() { + return handshakeComplete; + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) { + handshakeComplete = ctx.newPromise(); + } + + @Override + public void channelActive(ChannelHandlerContext ctx) { + handshaker.handshake(ctx.channel()); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + ChannelPromise f = handshakeComplete; + if (!f.isDone()) { + f.setFailure(new ClosedChannelException()); + } + super.channelInactive(ctx); + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { + if (msg instanceof FullHttpResponse) { + WebSocketClientHandshaker h = handshaker; + if (h.isHandshakeComplete()) { + throw new IllegalStateException( + "Unexpected http response after http1 websocket handshake completion"); + } + ChannelPromise hc = handshakeComplete; + try { + h.finishHandshake(ctx.channel(), (FullHttpResponse) msg); + hc.setSuccess(); + } catch (WebSocketHandshakeException e) { + logger.error("Http1 websocket handshake error", e); + hc.setFailure(e); + } + return; + } + if (msg instanceof ReferenceCounted) { + ((ReferenceCounted) msg).retain(); + } + ctx.fireChannelRead(msg); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + ChannelPromise f = handshakeComplete; + if (!f.isDone()) { + f.setFailure(cause); + } + ctx.close(); + super.exceptionCaught(ctx, cause); + } + + private static URI uri(String uri) { + try { + return new URI(uri); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("uri syntax error: " + uri, e); + } + } + } + + @ChannelHandler.Sharable + private static class EchoWebSocketHandler + extends SimpleChannelInboundHandler { + + @Override + protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame webSocketFrame) { + logger.info("==> Received text websocket message: {}", webSocketFrame.text()); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + if (cause instanceof IOException) { + return; + } + logger.error("Unexpected websocket error", cause); + ctx.close(); + } + } +} diff --git a/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/multiprotocolserver/Main.java b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/multiprotocolserver/Main.java new file mode 100644 index 0000000..f6f6e20 --- /dev/null +++ b/netty-websocket-http2-example/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/example/multiprotocolserver/Main.java @@ -0,0 +1,208 @@ +/* + * Copyright 2022 - present Maksym Ostroverkhov. + * + * Licensed 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 com.jauntsdn.netty.handler.codec.http2.websocketx.example.multiprotocolserver; + +import static io.netty.channel.ChannelHandler.Sharable; + +import com.jauntsdn.netty.handler.codec.http2.websocketx.Http2WebSocketAcceptor; +import com.jauntsdn.netty.handler.codec.http2.websocketx.Http2WebSocketServerBuilder; +import com.jauntsdn.netty.handler.codec.http2.websocketx.Http2WebSocketServerHandler; +import com.jauntsdn.netty.handler.codec.http2.websocketx.example.Security; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; +import io.netty.handler.codec.http.websocketx.WebSocketHandshakeException; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; +import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler; +import io.netty.handler.codec.http2.Http2FrameCodec; +import io.netty.handler.codec.http2.Http2FrameCodecBuilder; +import io.netty.handler.codec.http2.Http2Headers; +import io.netty.handler.ssl.ApplicationProtocolNames; +import io.netty.handler.ssl.ApplicationProtocolNegotiationHandler; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslHandler; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Main { + private static final Logger logger = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) throws Exception { + String host = System.getProperty("HOST", "localhost"); + int port = Integer.parseInt(System.getProperty("PORT", "8099")); + String echoPath = System.getProperty("PING", "echo"); + String keyStoreFile = System.getProperty("KEYSTORE", "localhost.p12"); + String keyStorePassword = System.getProperty("KEYSTORE_PASS", "localhost"); + + logger.info("\n==> http1/http2 websocket server\n"); + logger.info("\n==> Bind address: {}:{}", host, port); + logger.info("\n==> Keystore file: {}", keyStoreFile); + + SslContext sslContext = Security.serverSslContext(keyStoreFile, keyStorePassword); + + ServerBootstrap bootstrap = new ServerBootstrap(); + Channel server = + bootstrap + .group(new NioEventLoopGroup()) + .channel(NioServerSocketChannel.class) + .childHandler(new ConnectionAcceptor(sslContext)) + .bind(host, port) + .sync() + .channel(); + logger.info("\n==> Server is listening on {}:{}", host, port); + + logger.info("\n==> Echo path: {}", echoPath); + server.closeFuture().sync(); + } + + private static class ConnectionAcceptor extends ChannelInitializer { + private static final List SUPPORTED_USER_AGENTS = + Collections.singletonList("jauntsdn-websocket-http2-client/"); + private final SslContext sslContext; + + ConnectionAcceptor(SslContext sslContext) { + this.sslContext = sslContext; + } + + @Override + protected void initChannel(SocketChannel ch) { + SslHandler sslHandler = sslContext.newHandler(ch.alloc()); + ChannelHandler http1webSocketHandler = new EchoWebSocketHandler(); + ApplicationProtocolNegotiationHandler webSocketProtocolVersionHandler = + new ApplicationProtocolNegotiationHandler(ApplicationProtocolNames.HTTP_1_1) { + @Override + protected void configurePipeline(ChannelHandlerContext c, String protocol) { + + switch (protocol) { + case ApplicationProtocolNames.HTTP_2: + logger.info("Server accepted TLS connection for websockets-over-http2"); + + Http2FrameCodecBuilder http2Builder = + Http2WebSocketServerBuilder.configureHttp2Server( + Http2FrameCodecBuilder.forServer()); + http2Builder.initialSettings().initialWindowSize(1_000); + Http2FrameCodec http2frameCodec = http2Builder.build(); + + Http2WebSocketServerHandler http2webSocketHandler = + Http2WebSocketServerBuilder.create() + .compression(true) + .acceptor( + (ctx, path, subprotocols, request, response) -> { + if ("/echo".equals(path)) { + if (subprotocols.contains("echo.jauntsdn.com") + && acceptUserAgent(request, response)) { + Http2WebSocketAcceptor.Subprotocol.accept( + "echo.jauntsdn.com", response); + return ctx.executor().newSucceededFuture(http1webSocketHandler); + } + } + return ctx.executor() + .newFailedFuture( + new WebSocketHandshakeException( + String.format( + "websocket rejected, path: %s, subprotocols: %s, user-agent: %s", + path, subprotocols, request.get("user-agent")))); + }) + .build(); + + ch.pipeline().addLast(http2frameCodec, http2webSocketHandler); + break; + + case ApplicationProtocolNames.HTTP_1_1: + logger.info("Server accepted TLS connection for websockets-over-http1"); + + HttpServerCodec http1Codec = new HttpServerCodec(); + HttpObjectAggregator http1Aggregator = new HttpObjectAggregator(65536); + WebSocketServerCompressionHandler http1WebSocketCompressor = + new WebSocketServerCompressionHandler(); + WebSocketServerProtocolHandler http1WebSocketProtocolHandler = + new WebSocketServerProtocolHandler("/echo", "echo.jauntsdn.com", true); + + ch.pipeline() + .addLast(http1Codec) + .addLast(http1Aggregator) + .addLast(http1WebSocketCompressor) + .addLast(http1WebSocketProtocolHandler) + .addLast(http1webSocketHandler); + break; + + default: + logger.info("Unsupported protocol for TLS connection: {}", protocol); + c.close(); + } + } + }; + + ch.pipeline().addLast(sslHandler, webSocketProtocolVersionHandler); + } + + private boolean acceptUserAgent(Http2Headers request, Http2Headers response) { + CharSequence userAgentSeq = request.get("user-agent"); + if (userAgentSeq == null || userAgentSeq.length() == 0) { + return false; + } + String userAgent = userAgentSeq.toString(); + for (String supportedUserAgent : SUPPORTED_USER_AGENTS) { + int index = userAgent.indexOf(supportedUserAgent); + if (index >= 0) { + int length = supportedUserAgent.length(); + String version = userAgent.substring(index + length); + String clientId = supportedUserAgent.substring(0, length - 1); + request.set("x-client-id", clientId); + request.set("x-client-version", version); + response.set("x-request-id", UUID.randomUUID().toString()); + return true; + } + } + return false; + } + } + + @Sharable + private static class EchoWebSocketHandler + extends SimpleChannelInboundHandler { + + @Override + protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame webSocketFrame) { + ctx.write(webSocketFrame.retain()); + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + ctx.flush(); + super.channelReadComplete(ctx); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + if (cause instanceof IOException) { + return; + } + logger.error("Unexpected websocket error", cause); + ctx.close(); + } + } +} From e220e9902f03accc61231910af2bc518ea49bbf8 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Thu, 9 Jun 2022 19:18:26 +0300 Subject: [PATCH 04/21] gitPlugin: downgrade 0.15.0 to 0.13.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index b3d5019..ba44911 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ version=1.1.5 googleJavaFormatPluginVersion=0.9 dependencyManagementPluginVersion=1.0.11.RELEASE -gitPluginVersion=0.15.0 +gitPluginVersion=0.13.0 osDetectorPluginVersion=1.7.0 versionsPluginVersion=0.42.0 From c23027354fafa607afbef33ff7616409957bb222 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Thu, 9 Jun 2022 19:02:13 +0300 Subject: [PATCH 05/21] update gradle wrapper --- gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- netty-websocket-http2-example/gradle.lockfile | 24 +++++++++++++ .../annotationProcessor.lockfile | 3 -- .../compileClasspath.lockfile | 16 --------- .../googleJavaFormat1.6.lockfile | 10 ------ .../gradle.lockfile | 28 +++++++++++++++ .../annotationProcessor.lockfile | 3 -- .../compileClasspath.lockfile | 20 ----------- .../googleJavaFormat1.6.lockfile | 10 ------ netty-websocket-http2/gradle.lockfile | 33 ++++++++++++++++++ .../annotationProcessor.lockfile | 3 -- .../compileClasspath.lockfile | 13 ------- .../googleJavaFormat1.6.lockfile | 10 ------ .../testAnnotationProcessor.lockfile | 3 -- .../testCompileClasspath.lockfile | 19 ---------- .../testRuntimeClasspath.lockfile | 24 ------------- 17 files changed, 86 insertions(+), 135 deletions(-) create mode 100644 netty-websocket-http2-example/gradle.lockfile delete mode 100644 netty-websocket-http2-example/gradle/dependency-locks/annotationProcessor.lockfile delete mode 100644 netty-websocket-http2-example/gradle/dependency-locks/compileClasspath.lockfile delete mode 100644 netty-websocket-http2-example/gradle/dependency-locks/googleJavaFormat1.6.lockfile create mode 100644 netty-websocket-http2-perftest/gradle.lockfile delete mode 100644 netty-websocket-http2-perftest/gradle/dependency-locks/annotationProcessor.lockfile delete mode 100644 netty-websocket-http2-perftest/gradle/dependency-locks/compileClasspath.lockfile delete mode 100644 netty-websocket-http2-perftest/gradle/dependency-locks/googleJavaFormat1.6.lockfile create mode 100644 netty-websocket-http2/gradle.lockfile delete mode 100644 netty-websocket-http2/gradle/dependency-locks/annotationProcessor.lockfile delete mode 100644 netty-websocket-http2/gradle/dependency-locks/compileClasspath.lockfile delete mode 100644 netty-websocket-http2/gradle/dependency-locks/googleJavaFormat1.6.lockfile delete mode 100644 netty-websocket-http2/gradle/dependency-locks/testAnnotationProcessor.lockfile delete mode 100644 netty-websocket-http2/gradle/dependency-locks/testCompileClasspath.lockfile delete mode 100644 netty-websocket-http2/gradle/dependency-locks/testRuntimeClasspath.lockfile diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 8958 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2a56324..aa991fc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/netty-websocket-http2-example/gradle.lockfile b/netty-websocket-http2-example/gradle.lockfile new file mode 100644 index 0000000..eb21a84 --- /dev/null +++ b/netty-websocket-http2-example/gradle.lockfile @@ -0,0 +1,24 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +ch.qos.logback:logback-classic:1.2.11=compileClasspath +ch.qos.logback:logback-core:1.2.11=compileClasspath +com.google.code.findbugs:jsr305:3.0.2=googleJavaFormat1.6 +com.google.errorprone:error_prone_annotations:2.0.18=googleJavaFormat1.6 +com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6 +com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6 +com.google.guava:guava:22.0=googleJavaFormat1.6 +com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6 +io.netty:netty-buffer:4.1.76.Final=compileClasspath +io.netty:netty-codec-http2:4.1.76.Final=compileClasspath +io.netty:netty-codec-http:4.1.76.Final=compileClasspath +io.netty:netty-codec:4.1.76.Final=compileClasspath +io.netty:netty-common:4.1.76.Final=compileClasspath +io.netty:netty-handler:4.1.76.Final=compileClasspath +io.netty:netty-resolver:4.1.76.Final=compileClasspath +io.netty:netty-tcnative-boringssl-static:2.0.48.Final=compileClasspath +io.netty:netty-tcnative-classes:2.0.51.Final=compileClasspath +io.netty:netty-transport:4.1.76.Final=compileClasspath +org.codehaus.mojo:animal-sniffer-annotations:1.14=googleJavaFormat1.6 +org.slf4j:slf4j-api:1.7.36=compileClasspath +empty=annotationProcessor diff --git a/netty-websocket-http2-example/gradle/dependency-locks/annotationProcessor.lockfile b/netty-websocket-http2-example/gradle/dependency-locks/annotationProcessor.lockfile deleted file mode 100644 index 656c5db..0000000 --- a/netty-websocket-http2-example/gradle/dependency-locks/annotationProcessor.lockfile +++ /dev/null @@ -1,3 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. diff --git a/netty-websocket-http2-example/gradle/dependency-locks/compileClasspath.lockfile b/netty-websocket-http2-example/gradle/dependency-locks/compileClasspath.lockfile deleted file mode 100644 index f30c59d..0000000 --- a/netty-websocket-http2-example/gradle/dependency-locks/compileClasspath.lockfile +++ /dev/null @@ -1,16 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.11 -ch.qos.logback:logback-core:1.2.11 -io.netty:netty-buffer:4.1.76.Final -io.netty:netty-codec-http2:4.1.76.Final -io.netty:netty-codec-http:4.1.76.Final -io.netty:netty-codec:4.1.76.Final -io.netty:netty-common:4.1.76.Final -io.netty:netty-handler:4.1.76.Final -io.netty:netty-resolver:4.1.76.Final -io.netty:netty-tcnative-boringssl-static:2.0.48.Final -io.netty:netty-tcnative-classes:2.0.51.Final -io.netty:netty-transport:4.1.76.Final -org.slf4j:slf4j-api:1.7.36 diff --git a/netty-websocket-http2-example/gradle/dependency-locks/googleJavaFormat1.6.lockfile b/netty-websocket-http2-example/gradle/dependency-locks/googleJavaFormat1.6.lockfile deleted file mode 100644 index fcefb57..0000000 --- a/netty-websocket-http2-example/gradle/dependency-locks/googleJavaFormat1.6.lockfile +++ /dev/null @@ -1,10 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -com.google.code.findbugs:jsr305:3.0.2 -com.google.errorprone:error_prone_annotations:2.0.18 -com.google.errorprone:javac-shaded:9+181-r4173-1 -com.google.googlejavaformat:google-java-format:1.6 -com.google.guava:guava:22.0 -com.google.j2objc:j2objc-annotations:1.1 -org.codehaus.mojo:animal-sniffer-annotations:1.14 diff --git a/netty-websocket-http2-perftest/gradle.lockfile b/netty-websocket-http2-perftest/gradle.lockfile new file mode 100644 index 0000000..9c8e11d --- /dev/null +++ b/netty-websocket-http2-perftest/gradle.lockfile @@ -0,0 +1,28 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +ch.qos.logback:logback-classic:1.2.11=compileClasspath +ch.qos.logback:logback-core:1.2.11=compileClasspath +com.google.code.findbugs:jsr305:3.0.2=googleJavaFormat1.6 +com.google.errorprone:error_prone_annotations:2.0.18=googleJavaFormat1.6 +com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6 +com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6 +com.google.guava:guava:22.0=googleJavaFormat1.6 +com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6 +io.netty:netty-buffer:4.1.76.Final=compileClasspath +io.netty:netty-codec-http2:4.1.76.Final=compileClasspath +io.netty:netty-codec-http:4.1.76.Final=compileClasspath +io.netty:netty-codec:4.1.76.Final=compileClasspath +io.netty:netty-common:4.1.76.Final=compileClasspath +io.netty:netty-handler:4.1.76.Final=compileClasspath +io.netty:netty-resolver:4.1.76.Final=compileClasspath +io.netty:netty-tcnative-boringssl-static:2.0.48.Final=compileClasspath +io.netty:netty-tcnative-classes:2.0.51.Final=compileClasspath +io.netty:netty-transport-classes-epoll:4.1.76.Final=compileClasspath +io.netty:netty-transport-native-epoll:4.1.76.Final=compileClasspath +io.netty:netty-transport-native-unix-common:4.1.76.Final=compileClasspath +io.netty:netty-transport:4.1.76.Final=compileClasspath +org.codehaus.mojo:animal-sniffer-annotations:1.14=googleJavaFormat1.6 +org.hdrhistogram:HdrHistogram:2.1.12=compileClasspath +org.slf4j:slf4j-api:1.7.36=compileClasspath +empty=annotationProcessor diff --git a/netty-websocket-http2-perftest/gradle/dependency-locks/annotationProcessor.lockfile b/netty-websocket-http2-perftest/gradle/dependency-locks/annotationProcessor.lockfile deleted file mode 100644 index 656c5db..0000000 --- a/netty-websocket-http2-perftest/gradle/dependency-locks/annotationProcessor.lockfile +++ /dev/null @@ -1,3 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. diff --git a/netty-websocket-http2-perftest/gradle/dependency-locks/compileClasspath.lockfile b/netty-websocket-http2-perftest/gradle/dependency-locks/compileClasspath.lockfile deleted file mode 100644 index 6b08a35..0000000 --- a/netty-websocket-http2-perftest/gradle/dependency-locks/compileClasspath.lockfile +++ /dev/null @@ -1,20 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.11 -ch.qos.logback:logback-core:1.2.11 -io.netty:netty-buffer:4.1.76.Final -io.netty:netty-codec-http2:4.1.76.Final -io.netty:netty-codec-http:4.1.76.Final -io.netty:netty-codec:4.1.76.Final -io.netty:netty-common:4.1.76.Final -io.netty:netty-handler:4.1.76.Final -io.netty:netty-resolver:4.1.76.Final -io.netty:netty-tcnative-boringssl-static:2.0.48.Final -io.netty:netty-tcnative-classes:2.0.51.Final -io.netty:netty-transport-classes-epoll:4.1.76.Final -io.netty:netty-transport-native-epoll:4.1.76.Final -io.netty:netty-transport-native-unix-common:4.1.76.Final -io.netty:netty-transport:4.1.76.Final -org.hdrhistogram:HdrHistogram:2.1.12 -org.slf4j:slf4j-api:1.7.36 diff --git a/netty-websocket-http2-perftest/gradle/dependency-locks/googleJavaFormat1.6.lockfile b/netty-websocket-http2-perftest/gradle/dependency-locks/googleJavaFormat1.6.lockfile deleted file mode 100644 index fcefb57..0000000 --- a/netty-websocket-http2-perftest/gradle/dependency-locks/googleJavaFormat1.6.lockfile +++ /dev/null @@ -1,10 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -com.google.code.findbugs:jsr305:3.0.2 -com.google.errorprone:error_prone_annotations:2.0.18 -com.google.errorprone:javac-shaded:9+181-r4173-1 -com.google.googlejavaformat:google-java-format:1.6 -com.google.guava:guava:22.0 -com.google.j2objc:j2objc-annotations:1.1 -org.codehaus.mojo:animal-sniffer-annotations:1.14 diff --git a/netty-websocket-http2/gradle.lockfile b/netty-websocket-http2/gradle.lockfile new file mode 100644 index 0000000..a958020 --- /dev/null +++ b/netty-websocket-http2/gradle.lockfile @@ -0,0 +1,33 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +ch.qos.logback:logback-classic:1.2.11=testRuntimeClasspath +ch.qos.logback:logback-core:1.2.11=testRuntimeClasspath +com.google.code.findbugs:jsr305:3.0.2=compileClasspath,googleJavaFormat1.6 +com.google.errorprone:error_prone_annotations:2.0.18=googleJavaFormat1.6 +com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6 +com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6 +com.google.guava:guava:22.0=googleJavaFormat1.6 +com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6 +io.netty:netty-buffer:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-http2:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-http:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-common:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-handler:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-tcnative-boringssl-static:2.0.48.Final=testRuntimeClasspath +io.netty:netty-tcnative-classes:2.0.51.Final=testRuntimeClasspath +io.netty:netty-transport:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath +org.assertj:assertj-core:3.22.0=testCompileClasspath,testRuntimeClasspath +org.codehaus.mojo:animal-sniffer-annotations:1.14=googleJavaFormat1.6 +org.junit.jupiter:junit-jupiter-api:5.8.2=testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-engine:5.8.2=testRuntimeClasspath +org.junit.jupiter:junit-jupiter-params:5.8.2=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-commons:1.8.2=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-engine:1.8.2=testRuntimeClasspath +org.junit:junit-bom:5.8.2=testCompileClasspath,testRuntimeClasspath +org.opentest4j:opentest4j:1.2.0=testCompileClasspath,testRuntimeClasspath +org.slf4j:slf4j-api:1.7.36=compileClasspath,testCompileClasspath,testRuntimeClasspath +empty=annotationProcessor,testAnnotationProcessor diff --git a/netty-websocket-http2/gradle/dependency-locks/annotationProcessor.lockfile b/netty-websocket-http2/gradle/dependency-locks/annotationProcessor.lockfile deleted file mode 100644 index 656c5db..0000000 --- a/netty-websocket-http2/gradle/dependency-locks/annotationProcessor.lockfile +++ /dev/null @@ -1,3 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. diff --git a/netty-websocket-http2/gradle/dependency-locks/compileClasspath.lockfile b/netty-websocket-http2/gradle/dependency-locks/compileClasspath.lockfile deleted file mode 100644 index 4c0710d..0000000 --- a/netty-websocket-http2/gradle/dependency-locks/compileClasspath.lockfile +++ /dev/null @@ -1,13 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -com.google.code.findbugs:jsr305:3.0.2 -io.netty:netty-buffer:4.1.76.Final -io.netty:netty-codec-http2:4.1.76.Final -io.netty:netty-codec-http:4.1.76.Final -io.netty:netty-codec:4.1.76.Final -io.netty:netty-common:4.1.76.Final -io.netty:netty-handler:4.1.76.Final -io.netty:netty-resolver:4.1.76.Final -io.netty:netty-transport:4.1.76.Final -org.slf4j:slf4j-api:1.7.36 diff --git a/netty-websocket-http2/gradle/dependency-locks/googleJavaFormat1.6.lockfile b/netty-websocket-http2/gradle/dependency-locks/googleJavaFormat1.6.lockfile deleted file mode 100644 index fcefb57..0000000 --- a/netty-websocket-http2/gradle/dependency-locks/googleJavaFormat1.6.lockfile +++ /dev/null @@ -1,10 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -com.google.code.findbugs:jsr305:3.0.2 -com.google.errorprone:error_prone_annotations:2.0.18 -com.google.errorprone:javac-shaded:9+181-r4173-1 -com.google.googlejavaformat:google-java-format:1.6 -com.google.guava:guava:22.0 -com.google.j2objc:j2objc-annotations:1.1 -org.codehaus.mojo:animal-sniffer-annotations:1.14 diff --git a/netty-websocket-http2/gradle/dependency-locks/testAnnotationProcessor.lockfile b/netty-websocket-http2/gradle/dependency-locks/testAnnotationProcessor.lockfile deleted file mode 100644 index 656c5db..0000000 --- a/netty-websocket-http2/gradle/dependency-locks/testAnnotationProcessor.lockfile +++ /dev/null @@ -1,3 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. diff --git a/netty-websocket-http2/gradle/dependency-locks/testCompileClasspath.lockfile b/netty-websocket-http2/gradle/dependency-locks/testCompileClasspath.lockfile deleted file mode 100644 index 3867a53..0000000 --- a/netty-websocket-http2/gradle/dependency-locks/testCompileClasspath.lockfile +++ /dev/null @@ -1,19 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -io.netty:netty-buffer:4.1.76.Final -io.netty:netty-codec-http2:4.1.76.Final -io.netty:netty-codec-http:4.1.76.Final -io.netty:netty-codec:4.1.76.Final -io.netty:netty-common:4.1.76.Final -io.netty:netty-handler:4.1.76.Final -io.netty:netty-resolver:4.1.76.Final -io.netty:netty-transport:4.1.76.Final -org.apiguardian:apiguardian-api:1.1.2 -org.assertj:assertj-core:3.22.0 -org.junit.jupiter:junit-jupiter-api:5.8.2 -org.junit.jupiter:junit-jupiter-params:5.8.2 -org.junit.platform:junit-platform-commons:1.8.2 -org.junit:junit-bom:5.8.2 -org.opentest4j:opentest4j:1.2.0 -org.slf4j:slf4j-api:1.7.36 diff --git a/netty-websocket-http2/gradle/dependency-locks/testRuntimeClasspath.lockfile b/netty-websocket-http2/gradle/dependency-locks/testRuntimeClasspath.lockfile deleted file mode 100644 index 0aba0e9..0000000 --- a/netty-websocket-http2/gradle/dependency-locks/testRuntimeClasspath.lockfile +++ /dev/null @@ -1,24 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.11 -ch.qos.logback:logback-core:1.2.11 -io.netty:netty-buffer:4.1.76.Final -io.netty:netty-codec-http2:4.1.76.Final -io.netty:netty-codec-http:4.1.76.Final -io.netty:netty-codec:4.1.76.Final -io.netty:netty-common:4.1.76.Final -io.netty:netty-handler:4.1.76.Final -io.netty:netty-resolver:4.1.76.Final -io.netty:netty-tcnative-boringssl-static:2.0.48.Final -io.netty:netty-tcnative-classes:2.0.51.Final -io.netty:netty-transport:4.1.76.Final -org.assertj:assertj-core:3.22.0 -org.junit.jupiter:junit-jupiter-api:5.8.2 -org.junit.jupiter:junit-jupiter-engine:5.8.2 -org.junit.jupiter:junit-jupiter-params:5.8.2 -org.junit.platform:junit-platform-commons:1.8.2 -org.junit.platform:junit-platform-engine:1.8.2 -org.junit:junit-bom:5.8.2 -org.opentest4j:opentest4j:1.2.0 -org.slf4j:slf4j-api:1.7.36 From 7a0b7db7dae054b3b42de57b36a11e3c6f97b3a2 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Thu, 9 Jun 2022 18:49:18 +0300 Subject: [PATCH 06/21] gh actions: build --- .github/workflows/ci-build.yml | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/ci-build.yml diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml new file mode 100644 index 0000000..54c8662 --- /dev/null +++ b/.github/workflows/ci-build.yml @@ -0,0 +1,38 @@ +name: Build + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop" ] + +permissions: + contents: read + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ ubuntu-20.04, macos-11, windows-2019 ] + jdk: [ 8, 11 ] + fail-fast: false + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK ${{ matrix.jdk }} + uses: actions/setup-java@v3 + with: + java-version: ${{ matrix.jdk }} + distribution: 'temurin' + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Build with Gradle + run: ./gradlew clean build --no-daemon + + From 805fc1ba80810af3e3c49d6e5a686fa947253ec6 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Thu, 9 Jun 2022 20:01:32 +0300 Subject: [PATCH 07/21] readme: add gh build status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dd37a1e..af306f1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ![Maven Central](https://img.shields.io/maven-central/v/com.jauntsdn.netty/netty-websocket-http2) - +[![Build](https://github.com/jauntsdn/netty-websocket-http2/actions/workflows/ci-build.yml/badge.svg)](https://github.com/jauntsdn/netty-websocket-http2/actions/workflows/ci-build.yml) # netty-websocket-http2 Netty based implementation of [rfc8441](https://tools.ietf.org/html/rfc8441) - bootstrapping websockets with http/2 From 72ccfa6a712f3eb1e0b67f827adc21b3e8b74cea Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Sat, 11 Jun 2022 08:32:03 +0300 Subject: [PATCH 08/21] java 17 build support --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index 79caa8f..81e9fd4 100644 --- a/build.gradle +++ b/build.gradle @@ -56,10 +56,15 @@ subprojects { options.with { links jdkJavaDoc() links "https://netty.io/4.1/api/" + addBooleanOption("Xdoclint:all,-missing", true) } } test { + if (JavaVersion.current() >= JavaVersion.VERSION_1_9) { + jvmArgs "--add-exports=java.base/sun.security.x509=ALL-UNNAMED" + } + useJUnitPlatform() testLogging { events "failed" From 88552745b0f7942f8882702f40c17863dbcd80c7 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Sat, 11 Jun 2022 08:33:54 +0300 Subject: [PATCH 09/21] gh actions: add java17 to build matrix --- .github/workflows/ci-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 54c8662..bbaee90 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: [ ubuntu-20.04, macos-11, windows-2019 ] - jdk: [ 8, 11 ] + jdk: [ 8, 11, 17 ] fail-fast: false steps: From 6db7f3e2706246577db5356d261b8830db461a72 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Sat, 11 Jun 2022 10:24:34 +0300 Subject: [PATCH 10/21] lib: set Automatic-Module-Name --- netty-websocket-http2/build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/netty-websocket-http2/build.gradle b/netty-websocket-http2/build.gradle index 8a34a71..a5c1002 100644 --- a/netty-websocket-http2/build.gradle +++ b/netty-websocket-http2/build.gradle @@ -35,3 +35,9 @@ dependencies { testRuntimeOnly "ch.qos.logback:logback-classic" testRuntimeOnly "io.netty:netty-tcnative-boringssl-static" } + +tasks.named("jar") { + manifest { + attributes("Automatic-Module-Name": "com.jauntsdn.netty.websocket.http2") + } +} From 5c27bdfa2ef9763511047df997a9c30faac2b852 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Sat, 11 Jun 2022 10:26:33 +0300 Subject: [PATCH 11/21] lib: remove lockfile leftovers for previous version of gradle --- .../dependency-locks/runtimeClasspath.lockfile | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 netty-websocket-http2/gradle/dependency-locks/runtimeClasspath.lockfile diff --git a/netty-websocket-http2/gradle/dependency-locks/runtimeClasspath.lockfile b/netty-websocket-http2/gradle/dependency-locks/runtimeClasspath.lockfile deleted file mode 100644 index d121a72..0000000 --- a/netty-websocket-http2/gradle/dependency-locks/runtimeClasspath.lockfile +++ /dev/null @@ -1,12 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -io.netty:netty-buffer:4.1.76.Final -io.netty:netty-codec-http2:4.1.76.Final -io.netty:netty-codec-http:4.1.76.Final -io.netty:netty-codec:4.1.76.Final -io.netty:netty-common:4.1.76.Final -io.netty:netty-handler:4.1.76.Final -io.netty:netty-resolver:4.1.76.Final -io.netty:netty-transport:4.1.76.Final -org.slf4j:slf4j-api:1.7.36 From 0aacf0c15e3cfd12a3433854ad11f1bf2b4cdf37 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Sat, 30 Jul 2022 08:13:46 +0300 Subject: [PATCH 12/21] update dependencies --- gradle.properties | 6 +++--- netty-websocket-http2/gradle.lockfile | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/gradle.properties b/gradle.properties index ba44911..1c5b484 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ group=com.jauntsdn.netty version=1.1.5 googleJavaFormatPluginVersion=0.9 -dependencyManagementPluginVersion=1.0.11.RELEASE +dependencyManagementPluginVersion=1.0.12.RELEASE gitPluginVersion=0.13.0 osDetectorPluginVersion=1.7.0 versionsPluginVersion=0.42.0 @@ -14,8 +14,8 @@ slf4jVersion=1.7.36 logbackVersion=1.2.11 jsr305Version=3.0.2 -junitVersion=5.8.2 -assertjVersion=3.22.0 +junitVersion=5.9.0 +assertjVersion=3.23.1 org.gradle.parallel=true org.gradle.configureondemand=true \ No newline at end of file diff --git a/netty-websocket-http2/gradle.lockfile b/netty-websocket-http2/gradle.lockfile index a958020..e9036f2 100644 --- a/netty-websocket-http2/gradle.lockfile +++ b/netty-websocket-http2/gradle.lockfile @@ -19,15 +19,16 @@ io.netty:netty-resolver:4.1.76.Final=compileClasspath,testCompileClasspath,testR io.netty:netty-tcnative-boringssl-static:2.0.48.Final=testRuntimeClasspath io.netty:netty-tcnative-classes:2.0.51.Final=testRuntimeClasspath io.netty:netty-transport:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +net.bytebuddy:byte-buddy:1.12.10=testCompileClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath -org.assertj:assertj-core:3.22.0=testCompileClasspath,testRuntimeClasspath +org.assertj:assertj-core:3.23.1=testCompileClasspath,testRuntimeClasspath org.codehaus.mojo:animal-sniffer-annotations:1.14=googleJavaFormat1.6 -org.junit.jupiter:junit-jupiter-api:5.8.2=testCompileClasspath,testRuntimeClasspath -org.junit.jupiter:junit-jupiter-engine:5.8.2=testRuntimeClasspath -org.junit.jupiter:junit-jupiter-params:5.8.2=testCompileClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-commons:1.8.2=testCompileClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-engine:1.8.2=testRuntimeClasspath -org.junit:junit-bom:5.8.2=testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-api:5.9.0=testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-engine:5.9.0=testRuntimeClasspath +org.junit.jupiter:junit-jupiter-params:5.9.0=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-commons:1.9.0=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-engine:1.9.0=testRuntimeClasspath +org.junit:junit-bom:5.9.0=testCompileClasspath,testRuntimeClasspath org.opentest4j:opentest4j:1.2.0=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:1.7.36=compileClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,testAnnotationProcessor From 2732b20df5d818606ad64295c0e624a0b1bef02a Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Mon, 15 Aug 2022 18:13:54 +0300 Subject: [PATCH 13/21] update dependencies --- build.gradle | 2 ++ gradle.properties | 6 ++-- gradle/dependency-management.gradle | 1 + netty-websocket-http2-example/build.gradle | 7 ++-- netty-websocket-http2-example/gradle.lockfile | 27 ++++++++------- netty-websocket-http2-perftest/build.gradle | 14 +++++--- .../gradle.lockfile | 34 +++++++++---------- netty-websocket-http2/build.gradle | 3 +- netty-websocket-http2/gradle.lockfile | 21 ++++++------ 9 files changed, 64 insertions(+), 51 deletions(-) diff --git a/build.gradle b/build.gradle index 81e9fd4..9b14769 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ plugins { id "com.github.ben-manes.versions" id "com.github.sherter.google-java-format" apply false + id "com.google.osdetector" apply false id "io.spring.dependency-management" apply false } @@ -34,6 +35,7 @@ allprojects { } subprojects { + apply plugin: "com.google.osdetector" apply plugin: "com.github.sherter.google-java-format" version = projectVersion(project) diff --git a/gradle.properties b/gradle.properties index 1c5b484..9644871 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,13 +2,13 @@ group=com.jauntsdn.netty version=1.1.5 googleJavaFormatPluginVersion=0.9 -dependencyManagementPluginVersion=1.0.12.RELEASE +dependencyManagementPluginVersion=1.0.13.RELEASE gitPluginVersion=0.13.0 osDetectorPluginVersion=1.7.0 versionsPluginVersion=0.42.0 -nettyVersion=4.1.76.Final -nettyTcnativeVersion=2.0.48.Final +nettyVersion=4.1.79.Final +nettyTcnativeVersion=2.0.54.Final hdrHistogramVersion=2.1.12 slf4jVersion=1.7.36 logbackVersion=1.2.11 diff --git a/gradle/dependency-management.gradle b/gradle/dependency-management.gradle index e1e3626..fe2b51d 100644 --- a/gradle/dependency-management.gradle +++ b/gradle/dependency-management.gradle @@ -8,6 +8,7 @@ subprojects { } dependencies { dependency "org.hdrhistogram:HdrHistogram:${hdrHistogramVersion}" + dependency "io.netty:netty-tcnative-classes:${nettyTcnativeVersion}" dependency "io.netty:netty-tcnative-boringssl-static:${nettyTcnativeVersion}" dependency "org.slf4j:slf4j-api:${slf4jVersion}" dependency "ch.qos.logback:logback-classic:${logbackVersion}" diff --git a/netty-websocket-http2-example/build.gradle b/netty-websocket-http2-example/build.gradle index 3a207d9..4523a43 100644 --- a/netty-websocket-http2-example/build.gradle +++ b/netty-websocket-http2-example/build.gradle @@ -15,15 +15,16 @@ */ plugins { - id "java" + id "application" } description = "Netty based implementation of rfc8441 - bootstrapping websockets with http/2. Example project" dependencies { implementation project(":netty-websocket-http2") - implementation "io.netty:netty-tcnative-boringssl-static" - implementation "ch.qos.logback:logback-classic" + implementation "org.slf4j:slf4j-api" + runtimeOnly "io.netty:netty-tcnative-boringssl-static::${osdetector.classifier}" + runtimeOnly "ch.qos.logback:logback-classic" } task runHandshakeServer(type: JavaExec) { diff --git a/netty-websocket-http2-example/gradle.lockfile b/netty-websocket-http2-example/gradle.lockfile index eb21a84..f54071d 100644 --- a/netty-websocket-http2-example/gradle.lockfile +++ b/netty-websocket-http2-example/gradle.lockfile @@ -1,24 +1,25 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.11=compileClasspath -ch.qos.logback:logback-core:1.2.11=compileClasspath +ch.qos.logback:logback-classic:1.2.11=runtimeClasspath +ch.qos.logback:logback-core:1.2.11=runtimeClasspath com.google.code.findbugs:jsr305:3.0.2=googleJavaFormat1.6 com.google.errorprone:error_prone_annotations:2.0.18=googleJavaFormat1.6 com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6 com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6 com.google.guava:guava:22.0=googleJavaFormat1.6 com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6 -io.netty:netty-buffer:4.1.76.Final=compileClasspath -io.netty:netty-codec-http2:4.1.76.Final=compileClasspath -io.netty:netty-codec-http:4.1.76.Final=compileClasspath -io.netty:netty-codec:4.1.76.Final=compileClasspath -io.netty:netty-common:4.1.76.Final=compileClasspath -io.netty:netty-handler:4.1.76.Final=compileClasspath -io.netty:netty-resolver:4.1.76.Final=compileClasspath -io.netty:netty-tcnative-boringssl-static:2.0.48.Final=compileClasspath -io.netty:netty-tcnative-classes:2.0.51.Final=compileClasspath -io.netty:netty-transport:4.1.76.Final=compileClasspath +io.netty:netty-buffer:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec-http2:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec-http:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-common:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-handler:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-resolver:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-tcnative-boringssl-static:2.0.54.Final=runtimeClasspath +io.netty:netty-tcnative-classes:2.0.54.Final=runtimeClasspath +io.netty:netty-transport-native-unix-common:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-transport:4.1.79.Final=compileClasspath,runtimeClasspath org.codehaus.mojo:animal-sniffer-annotations:1.14=googleJavaFormat1.6 -org.slf4j:slf4j-api:1.7.36=compileClasspath +org.slf4j:slf4j-api:1.7.36=compileClasspath,runtimeClasspath empty=annotationProcessor diff --git a/netty-websocket-http2-perftest/build.gradle b/netty-websocket-http2-perftest/build.gradle index 883dce4..c1fa406 100644 --- a/netty-websocket-http2-perftest/build.gradle +++ b/netty-websocket-http2-perftest/build.gradle @@ -15,17 +15,23 @@ */ plugins { - id "java" + id "application" } description = "Netty based implementation of rfc8441 - bootstrapping websockets with http/2. Performance test project" +if (osdetector.os != "linux") { + throw new GradleException("Perf estimation is for linux based hosts only") +} + dependencies { implementation project(":netty-websocket-http2") implementation "org.hdrhistogram:HdrHistogram" - implementation "ch.qos.logback:logback-classic" - implementation "io.netty:netty-tcnative-boringssl-static" - implementation "io.netty:netty-transport-native-epoll::linux-x86_64" + implementation "io.netty:netty-transport-classes-epoll" + implementation "org.slf4j:slf4j-api" + runtimeOnly "io.netty:netty-transport-native-epoll::linux-x86_64" + runtimeOnly "io.netty:netty-tcnative-boringssl-static::linux-x86_64" + runtimeOnly "ch.qos.logback:logback-classic" } task runServer(type: JavaExec) { diff --git a/netty-websocket-http2-perftest/gradle.lockfile b/netty-websocket-http2-perftest/gradle.lockfile index 9c8e11d..0b813f0 100644 --- a/netty-websocket-http2-perftest/gradle.lockfile +++ b/netty-websocket-http2-perftest/gradle.lockfile @@ -1,28 +1,28 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.11=compileClasspath -ch.qos.logback:logback-core:1.2.11=compileClasspath +ch.qos.logback:logback-classic:1.2.11=runtimeClasspath +ch.qos.logback:logback-core:1.2.11=runtimeClasspath com.google.code.findbugs:jsr305:3.0.2=googleJavaFormat1.6 com.google.errorprone:error_prone_annotations:2.0.18=googleJavaFormat1.6 com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6 com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6 com.google.guava:guava:22.0=googleJavaFormat1.6 com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6 -io.netty:netty-buffer:4.1.76.Final=compileClasspath -io.netty:netty-codec-http2:4.1.76.Final=compileClasspath -io.netty:netty-codec-http:4.1.76.Final=compileClasspath -io.netty:netty-codec:4.1.76.Final=compileClasspath -io.netty:netty-common:4.1.76.Final=compileClasspath -io.netty:netty-handler:4.1.76.Final=compileClasspath -io.netty:netty-resolver:4.1.76.Final=compileClasspath -io.netty:netty-tcnative-boringssl-static:2.0.48.Final=compileClasspath -io.netty:netty-tcnative-classes:2.0.51.Final=compileClasspath -io.netty:netty-transport-classes-epoll:4.1.76.Final=compileClasspath -io.netty:netty-transport-native-epoll:4.1.76.Final=compileClasspath -io.netty:netty-transport-native-unix-common:4.1.76.Final=compileClasspath -io.netty:netty-transport:4.1.76.Final=compileClasspath +io.netty:netty-buffer:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec-http2:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec-http:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-common:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-handler:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-resolver:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-tcnative-boringssl-static:2.0.54.Final=runtimeClasspath +io.netty:netty-tcnative-classes:2.0.54.Final=runtimeClasspath +io.netty:netty-transport-classes-epoll:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-transport-native-epoll:4.1.79.Final=runtimeClasspath +io.netty:netty-transport-native-unix-common:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-transport:4.1.79.Final=compileClasspath,runtimeClasspath org.codehaus.mojo:animal-sniffer-annotations:1.14=googleJavaFormat1.6 -org.hdrhistogram:HdrHistogram:2.1.12=compileClasspath -org.slf4j:slf4j-api:1.7.36=compileClasspath +org.hdrhistogram:HdrHistogram:2.1.12=compileClasspath,runtimeClasspath +org.slf4j:slf4j-api:1.7.36=compileClasspath,runtimeClasspath empty=annotationProcessor diff --git a/netty-websocket-http2/build.gradle b/netty-websocket-http2/build.gradle index a5c1002..963a387 100644 --- a/netty-websocket-http2/build.gradle +++ b/netty-websocket-http2/build.gradle @@ -33,7 +33,8 @@ dependencies { testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine" testRuntimeOnly "ch.qos.logback:logback-classic" - testRuntimeOnly "io.netty:netty-tcnative-boringssl-static" + testRuntimeOnly "io.netty:netty-tcnative-classes" + testRuntimeOnly "io.netty:netty-tcnative-boringssl-static::${osdetector.classifier}" } tasks.named("jar") { diff --git a/netty-websocket-http2/gradle.lockfile b/netty-websocket-http2/gradle.lockfile index e9036f2..d812c22 100644 --- a/netty-websocket-http2/gradle.lockfile +++ b/netty-websocket-http2/gradle.lockfile @@ -9,16 +9,17 @@ com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6 com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6 com.google.guava:guava:22.0=googleJavaFormat1.6 com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6 -io.netty:netty-buffer:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-http2:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-http:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-common:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-handler:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-tcnative-boringssl-static:2.0.48.Final=testRuntimeClasspath -io.netty:netty-tcnative-classes:2.0.51.Final=testRuntimeClasspath -io.netty:netty-transport:4.1.76.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-buffer:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-http2:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-http:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-common:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-handler:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-tcnative-boringssl-static:2.0.54.Final=testRuntimeClasspath +io.netty:netty-tcnative-classes:2.0.54.Final=testRuntimeClasspath +io.netty:netty-transport-native-unix-common:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport:4.1.79.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath net.bytebuddy:byte-buddy:1.12.10=testCompileClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath org.assertj:assertj-core:3.23.1=testCompileClasspath,testRuntimeClasspath From 5b40eaa7cee6502474889e6deada910dfd9e93f6 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Mon, 15 Aug 2022 18:16:47 +0300 Subject: [PATCH 14/21] fix gradle warnings --- netty-websocket-http2-example/build.gradle | 12 ++++++------ netty-websocket-http2-perftest/build.gradle | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/netty-websocket-http2-example/build.gradle b/netty-websocket-http2-example/build.gradle index 4523a43..21afaca 100644 --- a/netty-websocket-http2-example/build.gradle +++ b/netty-websocket-http2-example/build.gradle @@ -29,31 +29,31 @@ dependencies { task runHandshakeServer(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.handshakeserver.Main" + mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.handshakeserver.Main" } task runChannelServer(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.channelserver.Main" + mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.channelserver.Main" } task runMultiProtocolServer(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.multiprotocolserver.Main" + mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.multiprotocolserver.Main" } task runChannelClient(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.channelclient.Main" + mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.channelclient.Main" } task runLwsClient(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.lwsclient.Main" + mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.lwsclient.Main" } task runMultiProtocolClient(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.multiprotocolclient.Main" + mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.multiprotocolclient.Main" } diff --git a/netty-websocket-http2-perftest/build.gradle b/netty-websocket-http2-perftest/build.gradle index c1fa406..d13bd46 100644 --- a/netty-websocket-http2-perftest/build.gradle +++ b/netty-websocket-http2-perftest/build.gradle @@ -36,10 +36,10 @@ dependencies { task runServer(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = "com.jauntsdn.netty.handler.codec.http2.websocketx.perftest.server.Main" + mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.perftest.server.Main" } task runClient(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = "com.jauntsdn.netty.handler.codec.http2.websocketx.perftest.client.Main" + mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.perftest.client.Main" } From ac9ac736782fb292ae089a482d198dfae47425cb Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Mon, 15 Aug 2022 18:40:17 +0300 Subject: [PATCH 15/21] update gradle --- gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 60756 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 6 ++++++ gradlew.bat | 14 ++++++++------ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..249e5832f090a2944b7473328c07c9755baa3196 100644 GIT binary patch delta 10197 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa991fc..ae04661 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c787..a69d9cb 100755 --- a/gradlew +++ b/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..f127cfd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From a5bfebd6fa5b6588ac92bdf0e1ead6631995a144 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Mon, 15 Aug 2022 19:05:04 +0300 Subject: [PATCH 16/21] only sign published artifacts when -Prelease=true --- gradle/publishing.gradle | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle index c9a0098..be8b5f0 100644 --- a/gradle/publishing.gradle +++ b/gradle/publishing.gradle @@ -1,4 +1,6 @@ subprojects { + def isRelease = isRelease(project) + def releasedModules = isRelease ? releaseModules() : [] tasks.withType(GenerateModuleMetadata) { enabled = false @@ -88,12 +90,20 @@ subprojects { plugins.withType(SigningPlugin) { signing { - sign publishing.publications.maven - required { - gradle.taskGraph.allTasks - .any { it.name.contains("publishMavenPublicationToSonatypeRepository") } + def isSigned = isRelease && releasedModules.contains(project.name) + println("Publication signed: ${isSigned}") + if (isSigned) { + sign publishing.publications.maven } } } } +} + +def isRelease(Project project) { + return project.hasProperty("release") && project.property("release") == "true" +} + +def releaseModules() { + return "netty-websocket-http2" } \ No newline at end of file From 9fd8157ae1511da7c78312c02849261d9586124b Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Mon, 15 Aug 2022 19:55:36 +0300 Subject: [PATCH 17/21] examples: remove redundant code --- .../http2/websocketx/perftest/Transport.java | 30 +++---------------- .../websocketx/perftest/client/Main.java | 3 +- .../websocketx/perftest/server/Main.java | 3 +- 3 files changed, 8 insertions(+), 28 deletions(-) diff --git a/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/Transport.java b/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/Transport.java index a503b0a..3000763 100644 --- a/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/Transport.java +++ b/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/Transport.java @@ -19,7 +19,6 @@ import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; import io.netty.channel.ServerChannel; -import io.netty.channel.epoll.Epoll; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollServerSocketChannel; import io.netty.channel.epoll.EpollSocketChannel; @@ -28,38 +27,17 @@ import io.netty.channel.socket.nio.NioSocketChannel; public class Transport { - static final boolean isEpollAvailable; - - static { - boolean available; - try { - Class.forName("io.netty.channel.epoll.Epoll"); - available = Epoll.isAvailable(); - } catch (ClassNotFoundException e) { - available = false; - } - isEpollAvailable = available; - } - private final Class clientChannel; private final Class serverChannel; private final EventLoopGroup eventLoopGroup; - public static boolean isEpollAvailable() { - return isEpollAvailable; - } - public static Transport get(boolean isNative) { int threadCount = Runtime.getRuntime().availableProcessors() * 2; if (isNative) { - if (isEpollAvailable()) { - return new Transport( - EpollSocketChannel.class, - EpollServerSocketChannel.class, - new EpollEventLoopGroup(threadCount)); - } else { - throw new IllegalArgumentException("native transport not available"); - } + return new Transport( + EpollSocketChannel.class, + EpollServerSocketChannel.class, + new EpollEventLoopGroup(threadCount)); } return new Transport( NioSocketChannel.class, NioServerSocketChannel.class, new NioEventLoopGroup(threadCount)); diff --git a/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/client/Main.java b/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/client/Main.java index c880e09..1c65fcd 100644 --- a/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/client/Main.java +++ b/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/client/Main.java @@ -28,6 +28,7 @@ import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.Unpooled; import io.netty.channel.*; +import io.netty.channel.epoll.Epoll; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http2.Http2FrameCodec; @@ -61,7 +62,7 @@ public static void main(String[] args) throws Exception { int websocketsCount = Integer.parseInt(System.getProperty("WEBSOCKETS", "1")); boolean isOpensslAvailable = OpenSsl.isAvailable(); - boolean isEpollAvailable = Transport.isEpollAvailable(); + boolean isEpollAvailable = Epoll.isAvailable(); logger.info("\n==> http2 websocket load test client\n"); logger.info("\n==> remote address: {}:{}", host, port); diff --git a/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/server/Main.java b/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/server/Main.java index 14e7e71..b117e85 100644 --- a/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/server/Main.java +++ b/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/server/Main.java @@ -24,6 +24,7 @@ import com.jauntsdn.netty.handler.codec.http2.websocketx.perftest.Transport; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; +import io.netty.channel.epoll.Epoll; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketHandshakeException; @@ -48,7 +49,7 @@ public static void main(String[] args) throws Exception { int flowControlWindowSize = Integer.parseInt(System.getProperty("FLOW_CONTROL_WINDOW", "100000")); boolean isOpensslAvailable = OpenSsl.isAvailable(); - boolean isEpollAvailable = Transport.isEpollAvailable(); + boolean isEpollAvailable = Epoll.isAvailable(); logger.info("\n==> http2 websocket load test server\n"); logger.info("\n==> bind address: {}:{}", host, port); From c6fe06d59d59e3f6899fc2a101e8b178329a5adb Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Mon, 15 Aug 2022 21:34:14 +0300 Subject: [PATCH 18/21] perftest: re-enable building & running on non-linux hosts --- netty-websocket-http2-perftest/build.gradle | 10 ++++------ .../codec/http2/websocketx/perftest/Transport.java | 14 ++++++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/netty-websocket-http2-perftest/build.gradle b/netty-websocket-http2-perftest/build.gradle index d13bd46..8a8d616 100644 --- a/netty-websocket-http2-perftest/build.gradle +++ b/netty-websocket-http2-perftest/build.gradle @@ -20,17 +20,15 @@ plugins { description = "Netty based implementation of rfc8441 - bootstrapping websockets with http/2. Performance test project" -if (osdetector.os != "linux") { - throw new GradleException("Perf estimation is for linux based hosts only") -} - dependencies { implementation project(":netty-websocket-http2") implementation "org.hdrhistogram:HdrHistogram" implementation "io.netty:netty-transport-classes-epoll" implementation "org.slf4j:slf4j-api" - runtimeOnly "io.netty:netty-transport-native-epoll::linux-x86_64" - runtimeOnly "io.netty:netty-tcnative-boringssl-static::linux-x86_64" + if (osdetector.os == "linux") { + runtimeOnly "io.netty:netty-transport-native-epoll::${osdetector.classifier}" + } + runtimeOnly "io.netty:netty-tcnative-boringssl-static::${osdetector.classifier}" runtimeOnly "ch.qos.logback:logback-classic" } diff --git a/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/Transport.java b/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/Transport.java index 3000763..4807909 100644 --- a/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/Transport.java +++ b/netty-websocket-http2-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http2/websocketx/perftest/Transport.java @@ -19,6 +19,7 @@ import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; import io.netty.channel.ServerChannel; +import io.netty.channel.epoll.Epoll; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollServerSocketChannel; import io.netty.channel.epoll.EpollSocketChannel; @@ -34,10 +35,15 @@ public class Transport { public static Transport get(boolean isNative) { int threadCount = Runtime.getRuntime().availableProcessors() * 2; if (isNative) { - return new Transport( - EpollSocketChannel.class, - EpollServerSocketChannel.class, - new EpollEventLoopGroup(threadCount)); + if (Epoll.isAvailable()) { + return new Transport( + EpollSocketChannel.class, + EpollServerSocketChannel.class, + new EpollEventLoopGroup(threadCount)); + } else { + throw new IllegalArgumentException( + "Epoll IO not available: " + Epoll.unavailabilityCause()); + } } return new Transport( NioSocketChannel.class, NioServerSocketChannel.class, new NioEventLoopGroup(threadCount)); From 2bc47f17aeb58b1ef3fa1d85ea1bc032bc6779f9 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Mon, 15 Aug 2022 23:18:04 +0300 Subject: [PATCH 19/21] perftest: disable lockfiles --- build.gradle | 6 ---- netty-websocket-http2-example/build.gradle | 4 +++ .../gradle.lockfile | 28 ------------------- netty-websocket-http2/build.gradle | 4 +++ 4 files changed, 8 insertions(+), 34 deletions(-) delete mode 100644 netty-websocket-http2-perftest/gradle.lockfile diff --git a/build.gradle b/build.gradle index 9b14769..619641b 100644 --- a/build.gradle +++ b/build.gradle @@ -28,12 +28,6 @@ description = "Netty based implementation of rfc8441 - bootstrapping websockets apply from: "gradle/dependency-management.gradle" apply from: "gradle/publishing.gradle" -allprojects { - dependencyLocking { - lockAllConfigurations() - } -} - subprojects { apply plugin: "com.google.osdetector" apply plugin: "com.github.sherter.google-java-format" diff --git a/netty-websocket-http2-example/build.gradle b/netty-websocket-http2-example/build.gradle index 21afaca..66ac4a8 100644 --- a/netty-websocket-http2-example/build.gradle +++ b/netty-websocket-http2-example/build.gradle @@ -27,6 +27,10 @@ dependencies { runtimeOnly "ch.qos.logback:logback-classic" } +dependencyLocking { + lockAllConfigurations() +} + task runHandshakeServer(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.handshakeserver.Main" diff --git a/netty-websocket-http2-perftest/gradle.lockfile b/netty-websocket-http2-perftest/gradle.lockfile deleted file mode 100644 index 0b813f0..0000000 --- a/netty-websocket-http2-perftest/gradle.lockfile +++ /dev/null @@ -1,28 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.2.11=runtimeClasspath -ch.qos.logback:logback-core:1.2.11=runtimeClasspath -com.google.code.findbugs:jsr305:3.0.2=googleJavaFormat1.6 -com.google.errorprone:error_prone_annotations:2.0.18=googleJavaFormat1.6 -com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6 -com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6 -com.google.guava:guava:22.0=googleJavaFormat1.6 -com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6 -io.netty:netty-buffer:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-codec-http2:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-codec-http:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-codec:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-common:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-handler:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-resolver:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-tcnative-boringssl-static:2.0.54.Final=runtimeClasspath -io.netty:netty-tcnative-classes:2.0.54.Final=runtimeClasspath -io.netty:netty-transport-classes-epoll:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-transport-native-epoll:4.1.79.Final=runtimeClasspath -io.netty:netty-transport-native-unix-common:4.1.79.Final=compileClasspath,runtimeClasspath -io.netty:netty-transport:4.1.79.Final=compileClasspath,runtimeClasspath -org.codehaus.mojo:animal-sniffer-annotations:1.14=googleJavaFormat1.6 -org.hdrhistogram:HdrHistogram:2.1.12=compileClasspath,runtimeClasspath -org.slf4j:slf4j-api:1.7.36=compileClasspath,runtimeClasspath -empty=annotationProcessor diff --git a/netty-websocket-http2/build.gradle b/netty-websocket-http2/build.gradle index 963a387..19011e4 100644 --- a/netty-websocket-http2/build.gradle +++ b/netty-websocket-http2/build.gradle @@ -37,6 +37,10 @@ dependencies { testRuntimeOnly "io.netty:netty-tcnative-boringssl-static::${osdetector.classifier}" } +dependencyLocking { + lockAllConfigurations() +} + tasks.named("jar") { manifest { attributes("Automatic-Module-Name": "com.jauntsdn.netty.websocket.http2") From 28ad0e1aefdae79c61497d057105e54cff5e06a5 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Tue, 16 Aug 2022 12:48:10 +0300 Subject: [PATCH 20/21] build: use epoll classifiers compatible with dependency locking on non-linux hosts --- build.gradle | 4 +++ netty-websocket-http2-example/build.gradle | 4 --- netty-websocket-http2-perftest/build.gradle | 9 ++++-- .../gradle.lockfile | 28 +++++++++++++++++++ netty-websocket-http2/build.gradle | 4 --- 5 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 netty-websocket-http2-perftest/gradle.lockfile diff --git a/build.gradle b/build.gradle index 619641b..5643723 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,10 @@ subprojects { mavenCentral() } + dependencyLocking { + lockAllConfigurations() + } + plugins.withType(JavaPlugin) { compileJava { diff --git a/netty-websocket-http2-example/build.gradle b/netty-websocket-http2-example/build.gradle index 66ac4a8..21afaca 100644 --- a/netty-websocket-http2-example/build.gradle +++ b/netty-websocket-http2-example/build.gradle @@ -27,10 +27,6 @@ dependencies { runtimeOnly "ch.qos.logback:logback-classic" } -dependencyLocking { - lockAllConfigurations() -} - task runHandshakeServer(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath mainClass = "com.jauntsdn.netty.handler.codec.http2.websocketx.example.handshakeserver.Main" diff --git a/netty-websocket-http2-perftest/build.gradle b/netty-websocket-http2-perftest/build.gradle index 8a8d616..5f37825 100644 --- a/netty-websocket-http2-perftest/build.gradle +++ b/netty-websocket-http2-perftest/build.gradle @@ -20,14 +20,17 @@ plugins { description = "Netty based implementation of rfc8441 - bootstrapping websockets with http/2. Performance test project" +def epollClassifier = + osdetector.os == "linux" + ? "::${osdetector.classifier}" + : "" + dependencies { implementation project(":netty-websocket-http2") implementation "org.hdrhistogram:HdrHistogram" implementation "io.netty:netty-transport-classes-epoll" implementation "org.slf4j:slf4j-api" - if (osdetector.os == "linux") { - runtimeOnly "io.netty:netty-transport-native-epoll::${osdetector.classifier}" - } + runtimeOnly "io.netty:netty-transport-native-epoll${epollClassifier}" runtimeOnly "io.netty:netty-tcnative-boringssl-static::${osdetector.classifier}" runtimeOnly "ch.qos.logback:logback-classic" } diff --git a/netty-websocket-http2-perftest/gradle.lockfile b/netty-websocket-http2-perftest/gradle.lockfile new file mode 100644 index 0000000..0b813f0 --- /dev/null +++ b/netty-websocket-http2-perftest/gradle.lockfile @@ -0,0 +1,28 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +ch.qos.logback:logback-classic:1.2.11=runtimeClasspath +ch.qos.logback:logback-core:1.2.11=runtimeClasspath +com.google.code.findbugs:jsr305:3.0.2=googleJavaFormat1.6 +com.google.errorprone:error_prone_annotations:2.0.18=googleJavaFormat1.6 +com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6 +com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6 +com.google.guava:guava:22.0=googleJavaFormat1.6 +com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6 +io.netty:netty-buffer:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec-http2:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec-http:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-codec:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-common:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-handler:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-resolver:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-tcnative-boringssl-static:2.0.54.Final=runtimeClasspath +io.netty:netty-tcnative-classes:2.0.54.Final=runtimeClasspath +io.netty:netty-transport-classes-epoll:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-transport-native-epoll:4.1.79.Final=runtimeClasspath +io.netty:netty-transport-native-unix-common:4.1.79.Final=compileClasspath,runtimeClasspath +io.netty:netty-transport:4.1.79.Final=compileClasspath,runtimeClasspath +org.codehaus.mojo:animal-sniffer-annotations:1.14=googleJavaFormat1.6 +org.hdrhistogram:HdrHistogram:2.1.12=compileClasspath,runtimeClasspath +org.slf4j:slf4j-api:1.7.36=compileClasspath,runtimeClasspath +empty=annotationProcessor diff --git a/netty-websocket-http2/build.gradle b/netty-websocket-http2/build.gradle index 19011e4..963a387 100644 --- a/netty-websocket-http2/build.gradle +++ b/netty-websocket-http2/build.gradle @@ -37,10 +37,6 @@ dependencies { testRuntimeOnly "io.netty:netty-tcnative-boringssl-static::${osdetector.classifier}" } -dependencyLocking { - lockAllConfigurations() -} - tasks.named("jar") { manifest { attributes("Automatic-Module-Name": "com.jauntsdn.netty.websocket.http2") From efb99c5cc5506d542cf8195e07d2725b51cc4d53 Mon Sep 17 00:00:00 2001 From: Maksym Ostroverkhov Date: Sat, 20 Aug 2022 10:07:39 +0300 Subject: [PATCH 21/21] multiprotocol_client/server.sh: chmod +x --- multiprotocol_client.sh | 0 multiprotocol_server.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 multiprotocol_client.sh mode change 100644 => 100755 multiprotocol_server.sh diff --git a/multiprotocol_client.sh b/multiprotocol_client.sh old mode 100644 new mode 100755 diff --git a/multiprotocol_server.sh b/multiprotocol_server.sh old mode 100644 new mode 100755