Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 10 additions & 43 deletions vertx-core/src/main/asciidoc/http.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2029,64 +2029,31 @@ on the same port value will share this random port.

Vert.x http servers and clients can be configured to use HTTPS in exactly the same way as net servers.

==== HTTPS on the server
Please see <<ssl, configuring net servers to use SSL>> for more information.

HTTPS is enabled with the `HttpServerOptions` {@link io.vertx.core.http.HttpServerOptions#setSsl(boolean) ssl} setting.

By default, it is disabled.

[source,$lang]
----
{@link examples.HTTPExamples#sslServerConfiguration}
----

You can read more about <<server_ssl,SSL server configuration>>

==== HTTPS on the client

Client SSL/TLS is enabled with the `HttpClientOptions` {@link io.vertx.core.http.HttpClientOptions#setSsl(boolean) ssl} property or {@link io.vertx.core.http.RequestOptions#setSsl(java.lang.Boolean) ssl} property.

{@link io.vertx.core.http.HttpClientOptions#setSsl(boolean)} setting acts as the default client setting.
SSL can also be enabled/disabled per request with {@link io.vertx.core.http.RequestOptions} or when
specifying a scheme with {@link io.vertx.core.http.RequestOptions#setAbsoluteURI(java.lang.String)}
method.

[source,$lang]
----
{@link examples.HTTPExamples#sslClientConfiguration}
{@link examples.HTTPExamples#setSSLPerRequest(io.vertx.core.http.HttpClient)}
----

SSL can also be enabled/disabled per request with {@link io.vertx.core.http.RequestOptions} or when
specifying a scheme with {@link io.vertx.core.http.RequestOptions#setAbsoluteURI(java.lang.String)}
method.
The {@link io.vertx.core.http.HttpClientOptions#setSsl(boolean)} setting acts as the default client setting.

{@link io.vertx.core.http.RequestOptions#setSsl(Boolean)} overrides the default client setting.
The {@link io.vertx.core.http.RequestOptions#setSsl(Boolean)} overrides the default client setting

* setting the value to `false` will disable SSL/TLS even if the client is configured to use SSL/TLS
* setting the value to `true` will enable SSL/TLS even if the client is configured to not use SSL/TLS, the actual client SSL/TLS (such as trust, key/certificate, ciphers, ALPN, ...) will be reused
* setting the value to `true` will enable SSL/TLS even if the client is configured to not use SSL/TLS, the actual
client SSL/TLS (such as trust, key/certificate, ciphers, ALPN, ...) will be reused

Likewise {@link io.vertx.core.http.RequestOptions#setAbsoluteURI(java.lang.String)} scheme
also overrides the default client setting.

[source,$lang]
----
{@link examples.HTTPExamples#sslClientRequestConfiguration}
----

You can also set {@link io.vertx.core.net.ClientSSLOptions} at request time.

[source,$lang]
----
{@link examples.HTTPExamples#sslClientRequestConfiguration2}
----

You can read more about <<client_ssl,SSL client configuration>>.

==== Server Name Indication (SNI)

Vert.x http servers can be configured to use SNI.

[source,$lang]
----
{@link examples.HTTPExamples#serverSNIConfig}
----
Vert.x http servers can be configured to use SNI in exactly the same way as {@linkplain io.vertx.core.net net servers}.

Vert.x http client will present the actual hostname as _server name_ during the TLS handshake.

Expand Down
79 changes: 1 addition & 78 deletions vertx-core/src/main/java/examples/HTTPExamples.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,9 @@
import io.vertx.core.http.WebSocketConnectOptions;
import io.vertx.core.http.WebSocketFrame;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.ClientSSLOptions;
import io.vertx.core.net.ConnectOptions;
import io.vertx.core.net.JksOptions;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.NetServer;
import io.vertx.core.net.NetServerOptions;
import io.vertx.core.net.NetSocket;
import io.vertx.core.net.ProxyOptions;
import io.vertx.core.net.ProxyType;
import io.vertx.core.net.ServerSSLOptions;
import io.vertx.core.net.endpoint.LoadBalancer;
import io.vertx.core.net.endpoint.ServerEndpoint;
import io.vertx.core.streams.Pipe;
Expand Down Expand Up @@ -1301,54 +1293,7 @@ public void randomServersharing(Vertx vertx) {
}).listen(-1);
}

public void sslServerConfiguration(Vertx vertx) {
ServerSSLOptions sslOptions = new ServerSSLOptions()
.setKeyCertOptions(
new JksOptions().
setPath("/path/to/your/server-keystore.jks").
setPassword("password-of-your-keystore")
);

HttpServerOptions options = new HttpServerOptions()
.setSsl(true)
.setSslOptions(sslOptions);

HttpServer server = vertx.createHttpServer(options);
}

public void sslClientConfiguration(Vertx vertx) {
ClientSSLOptions sslOptions = new ClientSSLOptions()
.setTrustOptions(new JksOptions().
setPath("/path/to/your/truststore.jks").
setPassword("password-of-your-truststore")
);

HttpClientOptions options = new HttpClientOptions()
.setSsl(true)
.setSslOptions(sslOptions);

HttpClientAgent client = vertx.createHttpClient(options);
}

public void serverSNIConfig(Vertx vertx) {
ServerSSLOptions sslOptions = new ServerSSLOptions()
.setKeyCertOptions(new JksOptions().
setPath("/path/to/your/server-keystore.jks").
setPassword("password-of-your-keystore"))
.setSni(true);
}

public void sslClientRequestConfiguration(Vertx vertx, int port, String host) {
ClientSSLOptions sslOptions = new ClientSSLOptions()
.setTrustOptions(new JksOptions().
setPath("/path/to/your/truststore.jks").
setPassword("password-of-your-truststore")
);

HttpClientOptions options = new HttpClientOptions().setSslOptions(sslOptions);

HttpClientAgent client = vertx.createHttpClient(options);

public void setSSLPerRequest(HttpClient client) {
client
.request(new RequestOptions()
.setHost("localhost")
Expand All @@ -1361,28 +1306,6 @@ public void sslClientRequestConfiguration(Vertx vertx, int port, String host) {
});
}

public void sslClientRequestConfiguration2(Vertx vertx, int port, String host) {
HttpClientAgent client = vertx.createHttpClient();

ClientSSLOptions sslOptions = new ClientSSLOptions()
.setTrustOptions(new JksOptions().
setPath("/path/to/your/truststore.jks").
setPassword("password-of-your-truststore")
);

client
.request(new RequestOptions()
.setHost("localhost")
.setPort(8080)
.setURI("/")
.setSsl(true)
.setSslOptions(sslOptions))
.compose(request -> request.send())
.onSuccess(response -> {
System.out.println("Received response with status code " + response.statusCode());
});
}

public static void setIdentityContentEncodingHeader(HttpServerRequest request) {
// Disable compression and send an image
request.response()
Expand Down
21 changes: 0 additions & 21 deletions vertx-core/src/main/java/io/vertx/core/http/Http2ServerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@
public class Http2ServerConfig {

private Http2Settings initialSettings;
private boolean clearTextEnabled;
private int connectionWindowSize;
private boolean multiplexImplementation;
private int rstFloodMaxRstFramePerWindow;
private Duration rstFloodWindowDuration;

public Http2ServerConfig() {
initialSettings = new Http2Settings().setMaxConcurrentStreams(DEFAULT_INITIAL_SETTINGS_MAX_CONCURRENT_STREAMS);
clearTextEnabled = DEFAULT_HTTP2_CLEAR_TEXT_ENABLED;
connectionWindowSize = DEFAULT_HTTP2_CONNECTION_WINDOW_SIZE;
rstFloodMaxRstFramePerWindow = DEFAULT_HTTP2_RST_FLOOD_MAX_RST_FRAME_PER_WINDOW;
rstFloodWindowDuration = Duration.of(DEFAULT_HTTP2_RST_FLOOD_WINDOW_DURATION, DEFAULT_HTTP2_RST_FLOOD_WINDOW_DURATION_TIME_UNIT.toChronoUnit());
Expand All @@ -42,7 +40,6 @@ public Http2ServerConfig() {

public Http2ServerConfig(Http2ServerConfig other) {
this.initialSettings = other.initialSettings != null ? new Http2Settings(other.initialSettings) : null;
this.clearTextEnabled = other.clearTextEnabled;
this.connectionWindowSize = other.connectionWindowSize;
this.rstFloodMaxRstFramePerWindow = other.rstFloodMaxRstFramePerWindow;
this.rstFloodWindowDuration = other.rstFloodWindowDuration;
Expand Down Expand Up @@ -87,24 +84,6 @@ public Http2ServerConfig setRstFloodWindowDuration(Duration rstFloodWindowDurati
return this;
}

/**
* @return whether the server accepts HTTP/2 over clear text connections
*/
public boolean isClearTextEnabled() {
return clearTextEnabled;
}

/**
* Set whether HTTP/2 over clear text is enabled or disabled, default is enabled.
*
* @param clearTextEnabled whether to accept HTTP/2 over clear text
* @return a reference to this, so the API can be used fluently
*/
public Http2ServerConfig setClearTextEnabled(boolean clearTextEnabled) {
this.clearTextEnabled = clearTextEnabled;
return this;
}

/**
* @return the default HTTP/2 connection window size
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private static List<HttpVersion> toSupportedVersion(HttpVersion version) {
case HTTP_1_0:
return List.of(HttpVersion.HTTP_1_0);
case HTTP_1_1:
return List.of(HttpVersion.HTTP_1_1, HttpVersion.HTTP_2);
return List.of(HttpVersion.HTTP_1_1);
case HTTP_2:
return List.of(HttpVersion.HTTP_2, HttpVersion.HTTP_1_1);
default:
Expand Down
44 changes: 19 additions & 25 deletions vertx-core/src/main/java/io/vertx/core/http/HttpClientOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,6 @@ protected ClientSSLOptions createSSLOptions() {
return super.createSSLOptions().setApplicationLayerProtocols(HttpUtils.fromHttpAlpnVersions(DEFAULT_ALPN_VERSIONS));
}

@Override
public HttpClientOptions setSslOptions(ClientSSLOptions sslOptions) {
return (HttpClientOptions) super.setSslOptions(sslOptions);
}

@Override
public HttpClientOptions setSendBufferSize(int sendBufferSize) {
super.setSendBufferSize(sendBufferSize);
Expand Down Expand Up @@ -812,21 +807,9 @@ public HttpClientOptions setInitialSettings(Http2Settings settings) {
return this;
}

@Override
public boolean isUseAlpn() {
return protocolVersion == HttpVersion.HTTP_2;
}

/**
* Alpn supported is automatically managed by the HTTP client depending on the client supported protocols.
*
* @param useAlpn ignored
* @return this object
*/
@Deprecated(forRemoval = true)
@Override
public HttpClientOptions setUseAlpn(boolean useAlpn) {
return this;
return (HttpClientOptions) super.setUseAlpn(useAlpn);
}

@Override
Expand All @@ -835,22 +818,33 @@ public HttpClientOptions setSslEngineOptions(SSLEngineOptions sslEngineOptions)
}

/**
* @return {@code null}
* @return the list of protocol versions to provide during the Application-Layer Protocol Negotiation. When
* the list is empty, the client provides a best effort list according to {@link #setProtocolVersion}
*/
public List<HttpVersion> getAlpnVersions() {
return null;
List<String> applicationLayerProtocols = getOrCreateSSLOptions().getApplicationLayerProtocols();
return applicationLayerProtocols != null ? HttpUtils.toHttpAlpnVersions(applicationLayerProtocols ) : null;
}

/**
* Does nothing, the list of supported alpn versions is managed by the HTTP client depending on the
* client supported HTTP versions.
* Set the list of protocol versions to provide to the server during the Application-Layer Protocol Negotiation.
* When the list is empty, the client makes a best effort list according to {@link #setProtocolVersion}:
*
* <ul>
* <li>{@link HttpVersion#HTTP_2}: [ "h2", "http/1.1" ]</li>
* <li>otherwise: [{@link #getProtocolVersion()}]</li>
* </ul>
*
* @param alpnVersions ignored
* @param alpnVersions the versions
* @return a reference to this, so the API can be used fluently
* @deprecated this should not be used anymore
*/
@Deprecated(forRemoval = true)
public HttpClientOptions setAlpnVersions(List<HttpVersion> alpnVersions) {
ClientSSLOptions sslOptions = getOrCreateSSLOptions();
if (alpnVersions != null) {
sslOptions.setApplicationLayerProtocols(HttpUtils.fromHttpAlpnVersions(alpnVersions));
} else {
sslOptions.setApplicationLayerProtocols(null);
}
return this;
}

Expand Down
21 changes: 17 additions & 4 deletions vertx-core/src/main/java/io/vertx/core/http/HttpServerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,20 @@ public HttpServerConfig(HttpServerOptions options) {
compression = null;
}

this.versions = EnumSet.copyOf(DEFAULT_VERSIONS);
Set<HttpVersion> versions;
if (options.isSsl()) {
if (options.isUseAlpn()) {
versions = EnumSet.copyOf(options.getAlpnVersions());
} else {
versions = EnumSet.of(HttpVersion.HTTP_1_1);
}
} else if (options.isHttp2ClearTextEnabled()) {
versions = EnumSet.copyOf(DEFAULT_VERSIONS);
} else {
versions = EnumSet.of(HttpVersion.HTTP_1_1);
}

this.versions = versions;
this.maxFormAttributeSize = options.getMaxFormAttributeSize();
this.maxFormFields = options.getMaxFormFields();
this.maxFormBufferedBytes = options.getMaxFormBufferedBytes();
Expand Down Expand Up @@ -150,9 +163,9 @@ public HttpServerConfig(HttpServerConfig other) {
this.strictThreadMode = other.strictThreadMode;
this.metricsName = other.metricsName;
this.tracingPolicy = other.tracingPolicy;
this.http1Config = other.http1Config != null ? new Http1ServerConfig(other.http1Config) : new Http1ServerConfig();
this.http2Config = other.http2Config != null ? new Http2ServerConfig(other.http2Config) : new Http2ServerConfig();
this.http3Config = other.http3Config != null ? new Http3ServerConfig(other.http3Config) : new Http3ServerConfig();
this.http1Config = other.http1Config != null ? new Http1ServerConfig(other.http1Config) : null;
this.http2Config = other.http2Config != null ? new Http2ServerConfig(other.http2Config) : null;
this.http3Config = other.http3Config != null ? new Http3ServerConfig(other.http3Config) : null;
this.webSocketConfig = other.webSocketConfig != null ? new WebSocketServerConfig(other.webSocketConfig) : new WebSocketServerConfig();
this.compression = other.compression != null ? new HttpCompressionConfig(other.compression) : new HttpCompressionConfig();
this.tcpConfig = other.tcpConfig != null ? new TcpServerConfig(other.tcpConfig) : defaultTcpServerConfig();
Expand Down
Loading
Loading