Skip to content

Commit 481ec58

Browse files
committed
HTTP server builder.
Motivation: The new TCP configuration still references the SSL engine options, we should externalize that and make it a separate side of the actual TCP configuration. Changes: Add a new HTTP server builder that allows to configure various aspects of an HTTP server. HTTP client builder also gets augmented with SSL engine options configurability.
1 parent 5bebe2f commit 481ec58

27 files changed

Lines changed: 354 additions & 128 deletions

vertx-core/src/main/asciidoc/net.adoc

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -515,22 +515,6 @@ NOTE: The options object is compared (using `equals`) against the existing optio
515515
are equals since loading options can be costly. When object are equals, you can use the `force` parameter to force
516516
the update.
517517

518-
==== SSL engine
519-
520-
The engine implementation can be configured to use https://www.openssl.org[OpenSSL] instead of the JDK implementation.
521-
Before JDK started to use hardware intrinsics (CPU instructions) for AES in Java 8 and for RSA in Java 9,
522-
OpenSSL provided much better performances and CPU usage than the JDK engine.
523-
524-
The engine options to use is
525-
526-
- the {@link io.vertx.core.net.TCPSSLOptions#getSslEngineOptions()} options when it is set
527-
- otherwise {@link io.vertx.core.net.JdkSSLEngineOptions}
528-
529-
[source,$lang]
530-
----
531-
{@link examples.NetExamples#exampleSSLEngine}
532-
----
533-
534518
=== Using a proxy for client connections
535519

536520
The {@link io.vertx.core.net.NetClient} supports either an HTTP/1.x _CONNECT_, _SOCKS4a_ or _SOCKS5_ proxy.

vertx-core/src/main/asciidoc/ssl.adoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,14 @@ Protocol versions can be specified on the {@link io.vertx.core.net.ServerSSLOpti
5555

5656
NOTE: TLS 1.0 (TLSv1) and TLS 1.1 (TLSv1.1) are widely deprecated and have been disabled by default since Vert.x 4.4.0.
5757

58+
=== SSL engine
59+
60+
The engine implementation can be configured to use https://www.openssl.org[OpenSSL] instead of the JDK implementation.
61+
Before JDK started to use hardware intrinsics (CPU instructions) for AES in Java 8 and for RSA in Java 9,
62+
OpenSSL provided much better performances and CPU usage than the JDK engine.
63+
64+
[source,$lang]
65+
----
66+
{@link examples.SslExamples#exampleSSLEngine}
67+
----
68+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.vertx.core.net;
2+
3+
import io.vertx.core.json.JsonObject;
4+
import io.vertx.core.json.JsonArray;
5+
6+
/**
7+
* Converter and mapper for {@link io.vertx.core.net.JdkSSLEngineOptions}.
8+
* NOTE: This class has been automatically generated from the {@link io.vertx.core.net.JdkSSLEngineOptions} original class using Vert.x codegen.
9+
*/
10+
public class JdkSSLEngineOptionsConverter {
11+
12+
static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json, JdkSSLEngineOptions obj) {
13+
for (java.util.Map.Entry<String, Object> member : json) {
14+
switch (member.getKey()) {
15+
case "useWorkerThread":
16+
if (member.getValue() instanceof Boolean) {
17+
obj.setUseWorkerThread((Boolean)member.getValue());
18+
}
19+
break;
20+
}
21+
}
22+
}
23+
24+
static void toJson(JdkSSLEngineOptions obj, JsonObject json) {
25+
toJson(obj, json.getMap());
26+
}
27+
28+
static void toJson(JdkSSLEngineOptions obj, java.util.Map<String, Object> json) {
29+
json.put("useWorkerThread", obj.getUseWorkerThread());
30+
}
31+
}

vertx-core/src/main/java/examples/NetExamples.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -362,23 +362,6 @@ public void updateSSLOptions(HttpServer server) {
362362
setPassword("password-of-your-keystore")));
363363
}
364364

365-
public void exampleSSLEngine(Vertx vertx, JksOptions keyStoreOptions) {
366-
367-
// Use JDK SSL engine
368-
TcpServerConfig options = new TcpServerConfig().
369-
setSsl(true);
370-
371-
// Use JDK SSL engine explicitly
372-
options = new TcpServerConfig().
373-
setSsl(true).
374-
setSslEngineOptions(new JdkSSLEngineOptions());
375-
376-
// Use OpenSSL engine
377-
options = new TcpServerConfig().
378-
setSsl(true).
379-
setSslEngineOptions(new OpenSSLEngineOptions());
380-
}
381-
382365
public void example46(Vertx vertx, String verificationAlgorithm, TrustOptions trustOptions) {
383366
TcpClientConfig config = new TcpClientConfig().
384367
setSsl(true);

vertx-core/src/main/java/examples/SslExamples.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@
33
import io.vertx.core.Vertx;
44
import io.vertx.core.buffer.Buffer;
55
import io.vertx.core.http.ClientAuth;
6+
import io.vertx.core.http.HttpServer;
7+
import io.vertx.core.http.HttpServerConfig;
68
import io.vertx.core.net.ClientSSLOptions;
9+
import io.vertx.core.net.JdkSSLEngineOptions;
710
import io.vertx.core.net.JksOptions;
811
import io.vertx.core.net.KeyStoreOptions;
912
import io.vertx.core.net.NetClient;
1013
import io.vertx.core.net.NetClientOptions;
1114
import io.vertx.core.net.NetServer;
1215
import io.vertx.core.net.NetServerOptions;
16+
import io.vertx.core.net.OpenSSLEngineOptions;
1317
import io.vertx.core.net.PemKeyCertOptions;
1418
import io.vertx.core.net.PemTrustOptions;
1519
import io.vertx.core.net.PfxOptions;
1620
import io.vertx.core.net.ServerSSLOptions;
21+
import io.vertx.core.net.TcpServerConfig;
1722

1823
import java.util.Arrays;
1924

@@ -304,4 +309,29 @@ public void configureSNIServerWithPems(Vertx vertx) {
304309
))
305310
.setSni(true);
306311
}
312+
313+
public void exampleSSLEngine(Vertx vertx, JksOptions keyStoreOptions) {
314+
315+
ServerSSLOptions sslOptions = new ServerSSLOptions()
316+
.setKeyCertOptions(keyStoreOptions);
317+
HttpServerConfig config = new HttpServerConfig()
318+
.setSsl(true);
319+
320+
// Use JDK SSL engine
321+
HttpServer server = vertx.createHttpServer(config);
322+
323+
// Use JDK SSL engine explicitly
324+
server = vertx.httpServerBuilder()
325+
.with(config)
326+
.with(sslOptions)
327+
.with(new JdkSSLEngineOptions())
328+
.build();
329+
330+
// Use OpenSSL engine
331+
server = vertx.httpServerBuilder()
332+
.with(config)
333+
.with(sslOptions)
334+
.with(new OpenSSLEngineOptions())
335+
.build();
336+
}
307337
}

vertx-core/src/main/java/io/vertx/core/Vertx.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.vertx.core.eventbus.EventBus;
2020
import io.vertx.core.file.FileSystem;
2121
import io.vertx.core.http.*;
22+
import io.vertx.core.http.impl.HttpServerBuilderImpl;
2223
import io.vertx.core.impl.VertxImpl;
2324
import io.vertx.core.internal.ContextInternal;
2425
import io.vertx.core.dns.impl.DnsAddressResolverProvider;
@@ -34,6 +35,7 @@
3435
import io.vertx.core.net.QuicClientConfig;
3536
import io.vertx.core.net.QuicServer;
3637
import io.vertx.core.net.QuicServerConfig;
38+
import io.vertx.core.net.SSLEngineOptions;
3739
import io.vertx.core.net.ServerSSLOptions;
3840
import io.vertx.core.net.TcpClientConfig;
3941
import io.vertx.core.net.TcpServerConfig;
@@ -324,7 +326,25 @@ default QuicClient createQuicClient(QuicClientConfig config) {
324326
* @param options the options to use
325327
* @return the server
326328
*/
327-
HttpServer createHttpServer(HttpServerOptions options);
329+
default HttpServer createHttpServer(HttpServerOptions options) {
330+
HttpServerConfig config = new HttpServerConfig(options);
331+
ServerSSLOptions sslOptions = options.getSslOptions();
332+
if (sslOptions != null) {
333+
sslOptions = sslOptions.copy();
334+
} else if (options.isSsl()) {
335+
sslOptions = new ServerSSLOptions();
336+
}
337+
SSLEngineOptions sslEngineOptions = options.getSslEngineOptions();
338+
if (sslEngineOptions != null) {
339+
sslEngineOptions = sslEngineOptions.copy();
340+
}
341+
HttpServerBuilder builder = ((HttpServerBuilderImpl)httpServerBuilder())
342+
.with(config)
343+
.with(sslOptions)
344+
.with(sslEngineOptions)
345+
.registerWebSocketWriteHandlers(options.isRegisterWebSocketWriteHandlers());
346+
return builder.build();
347+
}
328348

329349
/**
330350
* Create an HTTP server using the specified config
@@ -342,7 +362,9 @@ default HttpServer createHttpServer(HttpServerConfig config) {
342362
* @param config the config to use
343363
* @return the server
344364
*/
345-
HttpServer createHttpServer(HttpServerConfig config, ServerSSLOptions sslOptions);
365+
default HttpServer createHttpServer(HttpServerConfig config, ServerSSLOptions sslOptions) {
366+
return httpServerBuilder().with(config).with(sslOptions).build();
367+
}
346368

347369
/**
348370
* Create an HTTP/HTTPS server using default options
@@ -353,6 +375,14 @@ default HttpServer createHttpServer() {
353375
return createHttpServer(new HttpServerOptions());
354376
}
355377

378+
/**
379+
* Provide a builder for {@link HttpServer}, it can be used to configure advanced
380+
* HTTP servre settings like a connection handler.
381+
* <p>
382+
* Example usage: {@code HttpServer server = vertx.httpServerBuilder().with(options).withConnectHandler(conn -> ...).build()}
383+
*/
384+
HttpServerBuilder httpServerBuilder();
385+
356386
/**
357387
* Create a WebSocket client using default options
358388
*

vertx-core/src/main/java/io/vertx/core/eventbus/impl/clustered/ClusteredEventBus.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,7 @@ public static String defaultAddress() {
129129
}
130130

131131
private NetClient createNetClient(VertxInternal vertx, NetClientOptions clientOptions) {
132-
TcpClientConfig config = new TcpClientConfig(clientOptions);
133-
NetClientBuilder builder = new NetClientBuilder(vertx, config)
134-
.sslOptions(clientOptions.getSslOptions())
135-
.registerWriteHandler(clientOptions.isRegisterWriteHandler());
136-
return builder.build();
132+
return new NetClientBuilder(vertx, clientOptions).build();
137133
}
138134

139135
private NetServerOptions getServerOptions() {

vertx-core/src/main/java/io/vertx/core/http/HttpClientBuilder.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import io.vertx.core.Future;
1717
import io.vertx.core.Handler;
1818
import io.vertx.core.net.ClientSSLOptions;
19+
import io.vertx.core.net.SSLEngineOptions;
1920
import io.vertx.core.net.endpoint.LoadBalancer;
2021
import io.vertx.core.net.AddressResolver;
2122

@@ -61,6 +62,14 @@ public interface HttpClientBuilder {
6162
@Fluent
6263
HttpClientBuilder with(ClientSSLOptions options);
6364

65+
/**
66+
* Configure the client with the given SSL {@code engine}.
67+
* @param engine the SSL engine options
68+
* @return a reference to this, so the API can be used fluently
69+
*/
70+
@Fluent
71+
HttpClientBuilder with(SSLEngineOptions engine);
72+
6473
/**
6574
* Set a connection handler for the client. This handler is called when a new connection is established.
6675
*
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2011-2026 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
package io.vertx.core.http;
12+
13+
import io.vertx.codegen.annotations.Fluent;
14+
import io.vertx.codegen.annotations.VertxGen;
15+
import io.vertx.core.Handler;
16+
import io.vertx.core.net.SSLEngineOptions;
17+
import io.vertx.core.net.ServerSSLOptions;
18+
19+
/**
20+
* A builder for {@link HttpServer}.
21+
*
22+
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
23+
*/
24+
@VertxGen
25+
public interface HttpServerBuilder {
26+
27+
/**
28+
* Configure the server.
29+
* @param config the server config
30+
* @return a reference to this, so the API can be used fluently
31+
*/
32+
@Fluent
33+
HttpServerBuilder with(HttpServerConfig config);
34+
35+
/**
36+
* Configure the server with the given SSL {@code options}.
37+
* @param options the SSL options
38+
* @return a reference to this, so the API can be used fluently
39+
*/
40+
@Fluent
41+
HttpServerBuilder with(ServerSSLOptions options);
42+
43+
/**
44+
* Configure the server with the given SSL {@code engine}.
45+
* @param engine the SSL engine options
46+
* @return a reference to this, so the API can be used fluently
47+
*/
48+
@Fluent
49+
HttpServerBuilder with(SSLEngineOptions engine);
50+
51+
/**
52+
* Set a connection handler for the server. This handler is called when a new connection is established.
53+
*
54+
* @return a reference to this, so the API can be used fluently
55+
*/
56+
@Fluent
57+
HttpServerBuilder withConnectHandler(Handler<HttpConnection> handler);
58+
59+
/**
60+
* Build and return the server.
61+
* @return the server as configured by this builder
62+
*/
63+
HttpServer build();
64+
65+
}

vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientBuilderInternal.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.vertx.core.net.ClientSSLOptions;
2020
import io.vertx.core.net.NetworkLogging;
2121
import io.vertx.core.net.ProxyOptions;
22+
import io.vertx.core.net.SSLEngineOptions;
2223
import io.vertx.core.net.endpoint.LoadBalancer;
2324
import io.vertx.core.net.AddressResolver;
2425
import io.vertx.core.net.endpoint.impl.EndpointResolverImpl;
@@ -37,6 +38,7 @@ public final class HttpClientBuilderInternal implements HttpClientBuilder {
3738
private HttpClientConfig clientConfig;
3839
private HttpClientOptions clientOptions; // To be removed
3940
private ClientSSLOptions sslOptions;
41+
private SSLEngineOptions sslEngineOptions;
4042
private PoolOptions poolOptions;
4143
private Handler<HttpConnection> connectHandler;
4244
private Function<HttpClientResponse, Future<RequestOptions>> redirectHandler;
@@ -58,6 +60,7 @@ public HttpClientBuilder with(HttpClientConfig config) {
5860
public HttpClientBuilder with(HttpClientOptions options) {
5961
this.clientConfig = new HttpClientConfig(options);
6062
this.sslOptions = options.getSslOptions();
63+
this.sslEngineOptions = options.getSslEngineOptions();
6164
this.clientOptions = options;
6265
return this;
6366
}
@@ -74,6 +77,12 @@ public HttpClientBuilder with(ClientSSLOptions options) {
7477
return this;
7578
}
7679

80+
@Override
81+
public HttpClientBuilder with(SSLEngineOptions engine) {
82+
this.sslEngineOptions = engine;
83+
return this;
84+
}
85+
7786
@Override
7887
public HttpClientBuilder withConnectHandler(Handler<HttpConnection> handler) {
7988
this.connectHandler = handler;
@@ -255,6 +264,7 @@ public HttpClientAgent build() {
255264
NetClientInternal tcpClient = new NetClientBuilder(vertx, clientConfig)
256265
.protocol("http")
257266
.sslOptions(sslOptions)
267+
.sslEngineOptions(sslEngineOptions)
258268
.build();
259269
NetworkLogging networkLogging = co.getTcpConfig().getNetworkLogging();
260270
transport = new TcpHttpClientTransport(

0 commit comments

Comments
 (0)