diff --git a/reactor-netty-examples/build.gradle b/reactor-netty-examples/build.gradle index 9ee4881670..837a2b4f63 100644 --- a/reactor-netty-examples/build.gradle +++ b/reactor-netty-examples/build.gradle @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2024 VMware, Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2025 VMware, Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,12 +26,12 @@ dependencies { api "io.zipkin.reporter2:zipkin-sender-urlconnection:$zipkinSenderVersion" api "io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64" + api "io.netty.incubator:netty-incubator-codec-http3:$nettyHttp3Version" runtimeOnly "ch.qos.logback:logback-classic:$logbackVersion" runtimeOnly "io.netty:netty-tcnative-boringssl-static:$boringSslVersion$os_suffix" // Needed for proxy testing runtimeOnly "io.netty:netty-handler-proxy:$nettyVersion" - runtimeOnly "io.netty.incubator:netty-incubator-codec-http3:$nettyHttp3Version" } description = "Examples for the Reactor Netty library" \ No newline at end of file diff --git a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/cors/HttpCorsServer.java b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/cors/HttpCorsServer.java index 12f946f60e..01d536e399 100644 --- a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/cors/HttpCorsServer.java +++ b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/cors/HttpCorsServer.java @@ -21,12 +21,14 @@ import io.netty.handler.codec.http.cors.CorsHandler; import io.netty.handler.ssl.util.SelfSignedCertificate; import java.security.cert.CertificateException; +import java.time.Duration; import reactor.netty.Connection; import reactor.netty.NettyOutbound; import reactor.netty.NettyPipeline; import reactor.netty.http.Http11SslContextSpec; import reactor.netty.http.Http2SslContextSpec; +import reactor.netty.http.Http3SslContextSpec; import reactor.netty.http.HttpProtocol; import reactor.netty.http.server.HttpServer; import reactor.netty.http.server.HttpServerRequest; @@ -44,6 +46,7 @@ public class HttpCorsServer { static final boolean WIRETAP = System.getProperty("wiretap") != null; static final boolean COMPRESS = System.getProperty("compress") != null; static final boolean HTTP2 = System.getProperty("http2") != null; + static final boolean HTTP3 = System.getProperty("http3") != null; public static void main(String... args) throws CertificateException { HttpServer server = @@ -59,6 +62,9 @@ public static void main(String... args) throws CertificateException { if (HTTP2) { server = server.secure(spec -> spec.sslContext(Http2SslContextSpec.forServer(ssc.certificate(), ssc.privateKey()))); } + else if (HTTP3) { + server = server.secure(spec -> spec.sslContext(Http3SslContextSpec.forServer(ssc.key(), null, ssc.cert()))); + } else { server = server.secure(spec -> spec.sslContext(Http11SslContextSpec.forServer(ssc.certificate(), ssc.privateKey()))); } @@ -68,6 +74,16 @@ public static void main(String... args) throws CertificateException { server = server.protocol(HttpProtocol.H2); } + if (HTTP3) { + server = + server.protocol(HttpProtocol.HTTP3) + .http3Settings(spec -> spec.idleTimeout(Duration.ofSeconds(5)) + .maxData(10000000) + .maxStreamDataBidirectionalLocal(1000000) + .maxStreamDataBidirectionalRemote(1000000) + .maxStreamsBidirectional(100)); + } + server.bindNow() .onDispose() .block(); @@ -81,11 +97,14 @@ private static NettyOutbound okResponse(HttpServerRequest request, HttpServerRes private static void addCorsHandler(Connection connection) { CorsConfig corsConfig = CorsConfigBuilder.forOrigin("example.com").allowNullOrigin().allowCredentials().allowedRequestHeaders("custom-request-header").build(); - if (!HTTP2) { - connection.channel().pipeline().addAfter(NettyPipeline.HttpCodec, "Cors", new CorsHandler(corsConfig)); + if (HTTP2) { + connection.channel().pipeline().addAfter(NettyPipeline.H2ToHttp11Codec, "Cors", new CorsHandler(corsConfig)); + } + else if (HTTP3) { + connection.channel().pipeline().addAfter(NettyPipeline.H3ToHttp11Codec, "Cors", new CorsHandler(corsConfig)); } else { - connection.channel().pipeline().addAfter(NettyPipeline.H2ToHttp11Codec, "Cors", new CorsHandler(corsConfig)); + connection.channel().pipeline().addAfter(NettyPipeline.HttpCodec, "Cors", new CorsHandler(corsConfig)); } } } diff --git a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/echo/EchoClient.java b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/echo/EchoClient.java index a54e3f3b5f..51d6988691 100644 --- a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/echo/EchoClient.java +++ b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/echo/EchoClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 VMware, Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2025 VMware, Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,13 @@ import reactor.core.publisher.Mono; import reactor.netty.ByteBufFlux; import reactor.netty.http.Http11SslContextSpec; +import reactor.netty.http.Http2SslContextSpec; +import reactor.netty.http.Http3SslContextSpec; +import reactor.netty.http.HttpProtocol; import reactor.netty.http.client.HttpClient; +import java.time.Duration; + /** * An HTTP client that sends POST request to the HTTP server and * receives as a response the content that was sent as a request. @@ -33,6 +38,8 @@ public final class EchoClient { static final int PORT = Integer.parseInt(System.getProperty("port", SECURE ? "8443" : "8080")); static final boolean WIRETAP = System.getProperty("wiretap") != null; static final boolean COMPRESS = System.getProperty("compress") != null; + static final boolean HTTP2 = System.getProperty("http2") != null; + static final boolean HTTP3 = System.getProperty("http3") != null; public static void main(String[] args) { HttpClient client = @@ -42,10 +49,36 @@ public static void main(String[] args) { .compress(COMPRESS); if (SECURE) { - Http11SslContextSpec http11SslContextSpec = - Http11SslContextSpec.forClient() - .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); - client = client.secure(spec -> spec.sslContext(http11SslContextSpec)); + if (HTTP2) { + Http2SslContextSpec http2SslContextSpec = + Http2SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http2SslContextSpec)); + } + else if (HTTP3) { + Http3SslContextSpec http3SslContextSpec = + Http3SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http3SslContextSpec)); + } + else { + Http11SslContextSpec http11SslContextSpec = + Http11SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http11SslContextSpec)); + } + } + + if (HTTP2) { + client = client.protocol(HttpProtocol.H2); + } + + if (HTTP3) { + client = + client.protocol(HttpProtocol.HTTP3) + .http3Settings(spec -> spec.idleTimeout(Duration.ofSeconds(5)) + .maxData(10000000) + .maxStreamDataBidirectionalLocal(1000000)); } String response = diff --git a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/echo/EchoServer.java b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/echo/EchoServer.java index f9ba260294..cf664783e2 100644 --- a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/echo/EchoServer.java +++ b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/echo/EchoServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2023 VMware, Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2025 VMware, Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,12 @@ import io.netty.handler.ssl.util.SelfSignedCertificate; import reactor.netty.http.Http11SslContextSpec; import reactor.netty.http.Http2SslContextSpec; +import reactor.netty.http.Http3SslContextSpec; import reactor.netty.http.HttpProtocol; import reactor.netty.http.server.HttpServer; +import java.time.Duration; + import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpHeaderValues.TEXT_PLAIN; @@ -36,6 +39,7 @@ public final class EchoServer { static final boolean WIRETAP = System.getProperty("wiretap") != null; static final boolean COMPRESS = System.getProperty("compress") != null; static final boolean HTTP2 = System.getProperty("http2") != null; + static final boolean HTTP3 = System.getProperty("http3") != null; public static void main(String[] args) throws Exception { HttpServer server = @@ -52,6 +56,9 @@ public static void main(String[] args) throws Exception { if (HTTP2) { server = server.secure(spec -> spec.sslContext(Http2SslContextSpec.forServer(ssc.certificate(), ssc.privateKey()))); } + else if (HTTP3) { + server = server.secure(spec -> spec.sslContext(Http3SslContextSpec.forServer(ssc.key(), null, ssc.cert()))); + } else { server = server.secure(spec -> spec.sslContext(Http11SslContextSpec.forServer(ssc.certificate(), ssc.privateKey()))); } @@ -61,6 +68,16 @@ public static void main(String[] args) throws Exception { server = server.protocol(HttpProtocol.H2); } + if (HTTP3) { + server = + server.protocol(HttpProtocol.HTTP3) + .http3Settings(spec -> spec.idleTimeout(Duration.ofSeconds(5)) + .maxData(10000000) + .maxStreamDataBidirectionalLocal(1000000) + .maxStreamDataBidirectionalRemote(1000000) + .maxStreamsBidirectional(100)); + } + server.bindNow() .onDispose() .block(); diff --git a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/helloworld/HelloWorldClient.java b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/helloworld/HelloWorldClient.java index 96fe47493e..b69fc3dcd1 100644 --- a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/helloworld/HelloWorldClient.java +++ b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/helloworld/HelloWorldClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 VMware, Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2025 VMware, Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,13 @@ import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import reactor.netty.http.Http11SslContextSpec; +import reactor.netty.http.Http2SslContextSpec; +import reactor.netty.http.Http3SslContextSpec; +import reactor.netty.http.HttpProtocol; import reactor.netty.http.client.HttpClient; +import java.time.Duration; + /** * An HTTP client that sends GET request to the HTTP server and receives as a response - "Hello World!". * @@ -30,6 +35,8 @@ public final class HelloWorldClient { static final int PORT = Integer.parseInt(System.getProperty("port", SECURE ? "8443" : "8080")); static final boolean WIRETAP = System.getProperty("wiretap") != null; static final boolean COMPRESS = System.getProperty("compress") != null; + static final boolean HTTP2 = System.getProperty("http2") != null; + static final boolean HTTP3 = System.getProperty("http3") != null; public static void main(String[] args) { HttpClient client = @@ -39,10 +46,36 @@ public static void main(String[] args) { .compress(COMPRESS); if (SECURE) { - Http11SslContextSpec http11SslContextSpec = - Http11SslContextSpec.forClient() - .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); - client = client.secure(spec -> spec.sslContext(http11SslContextSpec)); + if (HTTP2) { + Http2SslContextSpec http2SslContextSpec = + Http2SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http2SslContextSpec)); + } + else if (HTTP3) { + Http3SslContextSpec http3SslContextSpec = + Http3SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http3SslContextSpec)); + } + else { + Http11SslContextSpec http11SslContextSpec = + Http11SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http11SslContextSpec)); + } + } + + if (HTTP2) { + client = client.protocol(HttpProtocol.H2); + } + + if (HTTP3) { + client = + client.protocol(HttpProtocol.HTTP3) + .http3Settings(spec -> spec.idleTimeout(Duration.ofSeconds(5)) + .maxData(10000000) + .maxStreamDataBidirectionalLocal(1000000)); } String response = diff --git a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/helloworld/HelloWorldServer.java b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/helloworld/HelloWorldServer.java index 73de468ba5..c4e4f163f2 100644 --- a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/helloworld/HelloWorldServer.java +++ b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/helloworld/HelloWorldServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2023 VMware, Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2025 VMware, Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,12 @@ import reactor.core.publisher.Mono; import reactor.netty.http.Http11SslContextSpec; import reactor.netty.http.Http2SslContextSpec; +import reactor.netty.http.Http3SslContextSpec; import reactor.netty.http.HttpProtocol; import reactor.netty.http.server.HttpServer; +import java.time.Duration; + import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpHeaderValues.TEXT_PLAIN; @@ -37,6 +40,7 @@ public final class HelloWorldServer { static final boolean WIRETAP = System.getProperty("wiretap") != null; static final boolean COMPRESS = System.getProperty("compress") != null; static final boolean HTTP2 = System.getProperty("http2") != null; + static final boolean HTTP3 = System.getProperty("http3") != null; public static void main(String[] args) throws Exception { HttpServer server = @@ -53,6 +57,9 @@ public static void main(String[] args) throws Exception { if (HTTP2) { server = server.secure(spec -> spec.sslContext(Http2SslContextSpec.forServer(ssc.certificate(), ssc.privateKey()))); } + else if (HTTP3) { + server = server.secure(spec -> spec.sslContext(Http3SslContextSpec.forServer(ssc.key(), null, ssc.cert()))); + } else { server = server.secure(spec -> spec.sslContext(Http11SslContextSpec.forServer(ssc.certificate(), ssc.privateKey()))); } @@ -62,6 +69,16 @@ public static void main(String[] args) throws Exception { server = server.protocol(HttpProtocol.H2); } + if (HTTP3) { + server = + server.protocol(HttpProtocol.HTTP3) + .http3Settings(spec -> spec.idleTimeout(Duration.ofSeconds(5)) + .maxData(10000000) + .maxStreamDataBidirectionalLocal(1000000) + .maxStreamDataBidirectionalRemote(1000000) + .maxStreamsBidirectional(100)); + } + server.bindNow() .onDispose() .block(); diff --git a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/snoop/HttpSnoopClient.java b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/snoop/HttpSnoopClient.java index 9f3c9c65bd..61ceee32bd 100644 --- a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/snoop/HttpSnoopClient.java +++ b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/snoop/HttpSnoopClient.java @@ -21,8 +21,13 @@ import reactor.core.publisher.Mono; import reactor.netty.ByteBufMono; import reactor.netty.http.Http11SslContextSpec; +import reactor.netty.http.Http2SslContextSpec; +import reactor.netty.http.Http3SslContextSpec; +import reactor.netty.http.HttpProtocol; import reactor.netty.http.client.HttpClient; +import java.time.Duration; + /** * An HTTP client demo that sends two requests to the http snoop server and then waits for the completion of the two requests. * @@ -35,6 +40,8 @@ public class HttpSnoopClient { static final int PORT = Integer.parseInt(System.getProperty("port", SECURE ? "8443" : "8080")); static final boolean WIRETAP = System.getProperty("wiretap") != null; static final boolean COMPRESS = System.getProperty("compress") != null; + static final boolean HTTP2 = System.getProperty("http2") != null; + static final boolean HTTP3 = System.getProperty("http3") != null; public static void main(String[] args) throws Exception { HttpClient client = HttpClient.create() @@ -43,10 +50,36 @@ public static void main(String[] args) throws Exception { .compress(COMPRESS); if (SECURE) { - Http11SslContextSpec http11SslContextSpec = - Http11SslContextSpec.forClient() - .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); - client = client.secure(spec -> spec.sslContext(http11SslContextSpec)); + if (HTTP2) { + Http2SslContextSpec http2SslContextSpec = + Http2SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http2SslContextSpec)); + } + else if (HTTP3) { + Http3SslContextSpec http3SslContextSpec = + Http3SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http3SslContextSpec)); + } + else { + Http11SslContextSpec http11SslContextSpec = + Http11SslContextSpec.forClient() + .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE)); + client = client.secure(spec -> spec.sslContext(http11SslContextSpec)); + } + } + + if (HTTP2) { + client = client.protocol(HttpProtocol.H2); + } + + if (HTTP3) { + client = + client.protocol(HttpProtocol.HTTP3) + .http3Settings(spec -> spec.idleTimeout(Duration.ofSeconds(5)) + .maxData(10000000) + .maxStreamDataBidirectionalLocal(1000000)); } // we fire two requests to the server asynchronously diff --git a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/snoop/HttpSnoopServer.java b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/snoop/HttpSnoopServer.java index c98ebe1c17..4851263b11 100644 --- a/reactor-netty-examples/src/main/java/reactor/netty/examples/http/snoop/HttpSnoopServer.java +++ b/reactor-netty-examples/src/main/java/reactor/netty/examples/http/snoop/HttpSnoopServer.java @@ -24,11 +24,13 @@ import reactor.netty.NettyOutbound; import reactor.netty.http.Http11SslContextSpec; import reactor.netty.http.Http2SslContextSpec; +import reactor.netty.http.Http3SslContextSpec; import reactor.netty.http.HttpProtocol; import reactor.netty.http.server.HttpServer; import reactor.netty.http.server.HttpServerRequest; import reactor.netty.http.server.HttpServerResponse; +import java.time.Duration; import java.util.Arrays; import java.util.List; @@ -44,6 +46,7 @@ public class HttpSnoopServer { static final boolean WIRETAP = System.getProperty("wiretap") != null; static final boolean COMPRESS = System.getProperty("compress") != null; static final boolean HTTP2 = System.getProperty("http2") != null; + static final boolean HTTP3 = System.getProperty("http3") != null; public static void main(String[] args) throws Exception { // 1.create and config the server instance @@ -57,6 +60,9 @@ public static void main(String[] args) throws Exception { if (HTTP2) { server = server.secure(spec -> spec.sslContext(Http2SslContextSpec.forServer(ssc.certificate(), ssc.privateKey()))); } + else if (HTTP3) { + server = server.secure(spec -> spec.sslContext(Http3SslContextSpec.forServer(ssc.key(), null, ssc.cert()))); + } else { server = server.secure(spec -> spec.sslContext(Http11SslContextSpec.forServer(ssc.certificate(), ssc.privateKey()))); } @@ -66,6 +72,16 @@ public static void main(String[] args) throws Exception { server = server.protocol(HttpProtocol.H2); } + if (HTTP3) { + server = + server.protocol(HttpProtocol.HTTP3) + .http3Settings(spec -> spec.idleTimeout(Duration.ofSeconds(5)) + .maxData(10000000) + .maxStreamDataBidirectionalLocal(1000000) + .maxStreamDataBidirectionalRemote(1000000) + .maxStreamsBidirectional(100)); + } + // 2.config the route rule, this server will receive any request that has any path and any method, // and then send back the details of the received HTTP request server = server.route(routes -> routes.route(req -> true, HttpSnoopServer::parseRequestAndSendResponse));