Skip to content

Commit 783077f

Browse files
committed
Merge branch 'release/1.2.0'
2 parents 134fb82 + 5c1f545 commit 783077f

File tree

25 files changed

+2130
-225
lines changed

25 files changed

+2130
-225
lines changed

Diff for: .github/workflows/ci-build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515

1616
strategy:
1717
matrix:
18-
os: [ ubuntu-20.04, macos-11, windows-2019 ]
18+
os: [ ubuntu-20.04, macos-12, windows-2019 ]
1919
jdk: [ 8, 11, 17, 21 ]
2020
fail-fast: false
2121

Diff for: README.md

+21-13
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,33 @@
55

66
Alternative Netty implementation of [RFC6455](https://tools.ietf.org/html/rfc6455) - the WebSocket protocol.
77

8-
Its advantage is significant per-core throughput improvement (1.8 - 2x) for small frames in comparison to netty's out-of-the-box
9-
websocket codecs, and minimal heap allocations on frame path. Library is compatible with
8+
Its advantages are significant per-core throughput improvement (1.8 - 2x) for small frames compared to netty's out-of-the-box
9+
websocket codecs, minimal heap allocations on frame path, and compatibility with
1010
[netty-websocket-http2](https://github.com/jauntsdn/netty-websocket-http2).
1111

1212
### use case & scope
1313

14-
* Intended for efficiently encoded, dense binary data: no extensions (compression) support / outbound text frames / inbound
15-
utf8 validation.
14+
* Intended for dense binary data & small text messages: no extensions (compression) support.
15+
16+
* No per-frame heap allocations in websocket frameFactory / decoder.
1617

1718
* Library assumes small frames - many have payload <= 125 bytes, most are < 1500, maximum supported is 65k (65535 bytes).
1819

19-
* Just codec - fragments, pings, close frames are decoded & validated only. It is responsibility of user code
20+
* Just codec - fragments, pings, close frames are decoded & protocol validated only. It is responsibility of user code
2021
to handle frames according to protocol (reassemble frame fragments, perform graceful close,
21-
respond to pings).
22-
23-
* Dedicated decoder for case of exchanging tiny messages over TLS connection:
24-
only non-masked frames with <= 125 bytes of payload for minimal per-webSocket state (memory) overhead.
25-
26-
* No per-frame heap allocations in websocket frameFactory / decoder.
22+
respond to pings) and do utf8 validation of inbound text frames ([utility](https://github.com/jauntsdn/netty-websocket-http1/blob/fb7bbb12d4fc0e62a72845dee89fe8f1d86f9a0a/netty-websocket-http1/src/main/java/com/jauntsdn/netty/handler/codec/http/websocketx/WebSocketFrameListener.java#L81) is provided).
2723

2824
* Single-threaded (transport IO event-loop) callbacks / frame factory API -
29-
in practice user code has its own message types to carry data, external means (e.g. mpsc / spsc queues) may be used to
25+
in practice user code has its own message types to carry data, and external means (e.g. mpsc / spsc queues) may be used to
3026
properly publish messages on eventloop thread.
3127

28+
* On encoder side 3 use cases are supported: frame factory [[1]](https://github.com/jauntsdn/netty-websocket-http1/blob/fb7bbb12d4fc0e62a72845dee89fe8f1d86f9a0a/netty-websocket-http1-test/src/test/java/com/jauntsdn/netty/handler/codec/http/websocketx/WebSocketCodecTest.java#L1475) (create bytebuffer and encode frame prefix),
29+
frame encoder [[2]](https://github.com/jauntsdn/netty-websocket-http1/blob/fb7bbb12d4fc0e62a72845dee89fe8f1d86f9a0a/netty-websocket-http1-test/src/test/java/com/jauntsdn/netty/handler/codec/http/websocketx/WebSocketCodecTest.java#L1019) (encode frame prefix into provided bytebuffer),
30+
frame bulk-encoder [[3]](https://github.com/jauntsdn/netty-websocket-http1/blob/fb7bbb12d4fc0e62a72845dee89fe8f1d86f9a0a/netty-websocket-http1-test/src/test/java/com/jauntsdn/netty/handler/codec/http/websocketx/WebSocketCodecTest.java#L707) (much more performant - encode multiple frames into provided bytebuffer).
31+
32+
* Dedicated decoder for case of exchanging tiny messages over TLS connection:
33+
only non-masked frames with <= 125 bytes of payload for minimal per-webSocket state (memory) overhead.
34+
3235
### performance
3336

3437
Per-core throughput [this codec perf-test](https://github.com/jauntsdn/netty-websocket-http1/tree/develop/netty-websocket-http1-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http/websocketx/perftest),
@@ -77,6 +80,11 @@ to create outbound frames. It is library user responsibility to mask outbound fr
7780
public interface WebSocketFrameFactory {
7881

7982
ByteBuf createBinaryFrame(ByteBufAllocator allocator, int binaryDataSize);
83+
84+
// ByteBuf createTextFrame(ByteBufAllocator allocator, int binaryDataSize);
85+
86+
// ByteBuf create*Fragment*(ByteBufAllocator allocator, int textDataSize);
87+
8088
// create*Frame are omitted for control frames, created in similar fashion
8189

8290
ByteBuf mask(ByteBuf frame);
@@ -159,7 +167,7 @@ repositories {
159167
}
160168
161169
dependencies {
162-
implementation "com.jauntsdn.netty:netty-websocket-http1:1.1.3"
170+
implementation "com.jauntsdn.netty:netty-websocket-http1:1.1.4"
163171
}
164172
```
165173

Diff for: gradle.properties

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
group=com.jauntsdn.netty
2-
version=1.1.4
2+
version=1.2.0
33

44
googleJavaFormatPluginVersion=0.9
55
dependencyManagementPluginVersion=1.1.0
66
gitPluginVersion=0.13.0
77
osDetectorPluginVersion=1.7.3
88
versionsPluginVersion=0.45.0
99

10-
nettyVersion=4.1.109.Final
10+
nettyVersion=4.1.112.Final
1111
nettyTcnativeVersion=2.0.65.Final
1212
hdrHistogramVersion=2.1.12
1313
slf4jVersion=1.7.36

Diff for: netty-websocket-http1-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http/websocketx/perftest/bulkencoder/server/Main.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public static void main(String[] args) throws Exception {
5252
boolean isNativeTransport =
5353
Boolean.parseBoolean(System.getProperty("NATIVE_TRANSPORT", "true"));
5454
boolean isEncrypted = Boolean.parseBoolean(System.getProperty("ENCRYPT", "true"));
55+
String keyStoreFile = System.getProperty("KEYSTORE", "localhost.p12");
56+
String keyStorePassword = System.getProperty("KEYSTORE_PASS", "localhost");
5557

5658
boolean isOpensslAvailable = OpenSsl.isAvailable();
5759
boolean isEpollAvailable = Transport.isEpollAvailable();
@@ -67,7 +69,8 @@ public static void main(String[] args) throws Exception {
6769

6870
Transport transport = Transport.get(isNativeTransport);
6971
logger.info("\n==> io transport: {}", transport.type());
70-
SslContext sslContext = isEncrypted ? Security.serverSslContext() : null;
72+
SslContext sslContext =
73+
isEncrypted ? Security.serverSslContext(keyStoreFile, keyStorePassword) : null;
7174

7275
ServerBootstrap bootstrap = new ServerBootstrap();
7376
Channel server =

Diff for: netty-websocket-http1-perftest/src/main/java/com/jauntsdn/netty/handler/codec/http/websocketx/perftest/encoder/server/Main.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public static void main(String[] args) throws Exception {
5252
boolean isNativeTransport =
5353
Boolean.parseBoolean(System.getProperty("NATIVE_TRANSPORT", "true"));
5454
boolean isEncrypted = Boolean.parseBoolean(System.getProperty("ENCRYPT", "true"));
55+
String keyStoreFile = System.getProperty("KEYSTORE", "localhost.p12");
56+
String keyStorePassword = System.getProperty("KEYSTORE_PASS", "localhost");
5557

5658
boolean isOpensslAvailable = OpenSsl.isAvailable();
5759
boolean isEpollAvailable = Transport.isEpollAvailable();
@@ -67,7 +69,8 @@ public static void main(String[] args) throws Exception {
6769

6870
Transport transport = Transport.get(isNativeTransport);
6971
logger.info("\n==> io transport: {}", transport.type());
70-
SslContext sslContext = isEncrypted ? Security.serverSslContext() : null;
72+
SslContext sslContext =
73+
isEncrypted ? Security.serverSslContext(keyStoreFile, keyStorePassword) : null;
7174

7275
ServerBootstrap bootstrap = new ServerBootstrap();
7376
Channel server =
3.98 KB
Binary file not shown.

Diff for: netty-websocket-http1-soaktest/build.gradle

-10
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,6 @@ dependencies {
3333
runtimeOnly "ch.qos.logback:logback-classic"
3434
}
3535

36-
task runServer(type: JavaExec) {
37-
classpath = sourceSets.main.runtimeClasspath
38-
mainClass = "com.jauntsdn.netty.handler.codec.http.websocketx.soaktest.server.Main"
39-
}
40-
41-
task runClient(type: JavaExec) {
42-
classpath = sourceSets.main.runtimeClasspath
43-
mainClass = "com.jauntsdn.netty.handler.codec.http.websocketx.soaktest.client.Main"
44-
}
45-
4636
task serverScripts(type: CreateStartScripts) {
4737
mainClass = "com.jauntsdn.netty.handler.codec.http.websocketx.soaktest.server.Main"
4838
applicationName = "${project.name}-server"

Diff for: netty-websocket-http1-soaktest/src/main/java/com/jauntsdn/netty/handler/codec/http/websocketx/soaktest/server/Main.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public static void main(String[] args) throws Exception {
5454
int frameSizeLimit = Integer.parseInt(System.getProperty("SIZE", "65535"));
5555
boolean expectMasked = Boolean.parseBoolean(System.getProperty("MASKED", "false"));
5656
boolean maskMismatch = !Boolean.parseBoolean(System.getProperty("STRICT", "false"));
57+
String keyStoreFile = System.getProperty("KEYSTORE", "localhost.p12");
58+
String keyStorePassword = System.getProperty("KEYSTORE_PASS", "localhost");
5759

5860
boolean isOpensslAvailable = OpenSsl.isAvailable();
5961
boolean isEpollAvailable = Transport.isEpollAvailable();
@@ -67,7 +69,7 @@ public static void main(String[] args) throws Exception {
6769

6870
Transport transport = Transport.get(/*native IO*/ true);
6971
logger.info("\n==> io transport: {}", transport.type());
70-
SslContext sslContext = Security.serverSslContext();
72+
SslContext sslContext = Security.serverSslContext(keyStoreFile, keyStorePassword);
7173

7274
ServerBootstrap bootstrap = new ServerBootstrap();
7375
Channel server =
3.98 KB
Binary file not shown.

Diff for: netty-websocket-http1-test/gradle.lockfile

+10-10
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ com.google.errorprone:javac-shaded:9+181-r4173-1=googleJavaFormat1.6
99
com.google.googlejavaformat:google-java-format:1.6=googleJavaFormat1.6
1010
com.google.guava:guava:22.0=googleJavaFormat1.6
1111
com.google.j2objc:j2objc-annotations:1.1=googleJavaFormat1.6
12-
io.netty:netty-buffer:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
13-
io.netty:netty-codec-http:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
14-
io.netty:netty-codec:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
15-
io.netty:netty-common:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
16-
io.netty:netty-handler:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
17-
io.netty:netty-resolver:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
18-
io.netty:netty-transport-classes-epoll:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
19-
io.netty:netty-transport-classes-kqueue:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
20-
io.netty:netty-transport-native-unix-common:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
21-
io.netty:netty-transport:4.1.109.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
12+
io.netty:netty-buffer:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
13+
io.netty:netty-codec-http:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
14+
io.netty:netty-codec:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
15+
io.netty:netty-common:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
16+
io.netty:netty-handler:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
17+
io.netty:netty-resolver:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
18+
io.netty:netty-transport-classes-epoll:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
19+
io.netty:netty-transport-classes-kqueue:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
20+
io.netty:netty-transport-native-unix-common:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
21+
io.netty:netty-transport:4.1.112.Final=compileClasspath,testCompileClasspath,testRuntimeClasspath
2222
net.bytebuddy:byte-buddy:1.14.11=testCompileClasspath,testRuntimeClasspath
2323
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
2424
org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath

Diff for: netty-websocket-http1-test/src/main/java/com/jauntsdn/netty/handler/codec/http/websocketx/test/Security.java

+12-6
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,28 @@
2222
import io.netty.handler.ssl.SslProvider;
2323
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
2424
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
25-
import io.netty.handler.ssl.util.SelfSignedCertificate;
26-
import java.security.SecureRandom;
25+
import java.io.InputStream;
26+
import java.security.KeyStore;
2727
import java.util.Arrays;
2828
import java.util.List;
29+
import javax.net.ssl.KeyManagerFactory;
2930
import javax.net.ssl.SSLException;
3031
import org.slf4j.Logger;
3132
import org.slf4j.LoggerFactory;
3233

3334
public final class Security {
3435
private static final Logger logger = LoggerFactory.getLogger(Security.class);
3536

36-
public static SslContext serverSslContext() throws Exception {
37-
SecureRandom random = new SecureRandom();
38-
SelfSignedCertificate ssc = new SelfSignedCertificate("com.jauntsdn", random, 1024);
37+
public static SslContext serverSslContext(String keystoreFile, String keystorePassword)
38+
throws Exception {
39+
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
40+
KeyStore keyStore = KeyStore.getInstance("PKCS12");
41+
InputStream keystoreStream = Security.class.getClassLoader().getResourceAsStream(keystoreFile);
42+
char[] keystorePasswordArray = keystorePassword.toCharArray();
43+
keyStore.load(keystoreStream, keystorePasswordArray);
44+
keyManagerFactory.init(keyStore, keystorePasswordArray);
3945

40-
return SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
46+
return SslContextBuilder.forServer(keyManagerFactory)
4147
.protocols("TLSv1.3")
4248
.sslProvider(sslProvider())
4349
.ciphers(supportedCypherSuites(), SupportedCipherSuiteFilter.INSTANCE)

0 commit comments

Comments
 (0)