|
36 | 36 | import java.util.List;
|
37 | 37 | import java.util.Map;
|
38 | 38 | import java.util.ServiceLoader;
|
| 39 | +import java.util.function.Function; |
| 40 | +import java.util.function.Supplier; |
39 | 41 |
|
40 | 42 | import static reactor.netty.tcp.SslProvider.DefaultConfigurationType.TCP;
|
41 | 43 |
|
@@ -277,6 +279,8 @@ public static final class Builder {
|
277 | 279 | @Nullable
|
278 | 280 | private String sslRootCert = null;
|
279 | 281 |
|
| 282 | + private Function<SslContextBuilder, SslContextBuilder> sslContextBuilderCustomizer = Function.identity(); |
| 283 | + |
280 | 284 | @Nullable
|
281 | 285 | private String username;
|
282 | 286 |
|
@@ -473,6 +477,20 @@ public Builder socket(String socket) {
|
473 | 477 | return this;
|
474 | 478 | }
|
475 | 479 |
|
| 480 | + /** |
| 481 | + * Configure a {@link SslContextBuilder} customizer. The customizer gets applied on each SSL connection attempt to allow for just-in-time configuration updates. The {@link Function} gets |
| 482 | + * called with the prepared {@link SslContextBuilder} that has all configuration options applied. The customizer may return the same builder or return a new builder instance to be used to |
| 483 | + * build the SSL context. |
| 484 | + * |
| 485 | + * @param sslContextBuilderCustomizer customizer function |
| 486 | + * @return this {@link Builder} |
| 487 | + * @throws IllegalArgumentException if {@code sslContextBuilderCustomizer} is {@code null} |
| 488 | + */ |
| 489 | + public Builder sslContextBuilderCustomizer(Function<SslContextBuilder, SslContextBuilder> sslContextBuilderCustomizer) { |
| 490 | + this.sslContextBuilderCustomizer = Assert.requireNonNull(sslContextBuilderCustomizer, "sslContextBuilderCustomizer must not be null"); |
| 491 | + return this; |
| 492 | + } |
| 493 | + |
476 | 494 | /**
|
477 | 495 | * Configure ssl cert for client certificate authentication.
|
478 | 496 | *
|
@@ -544,6 +562,7 @@ public String toString() {
|
544 | 562 | ", schema='" + this.schema + '\'' +
|
545 | 563 | ", username='" + this.username + '\'' +
|
546 | 564 | ", socket='" + this.socket + '\'' +
|
| 565 | + ", sslContextBuilderCustomizer='" + this.sslContextBuilderCustomizer + '\'' + |
547 | 566 | ", sslMode='" + this.sslMode + '\'' +
|
548 | 567 | ", sslRootCert='" + this.sslRootCert + '\'' +
|
549 | 568 | ", sslCert='" + this.sslCert + '\'' +
|
@@ -577,14 +596,14 @@ public Builder username(String username) {
|
577 | 596 |
|
578 | 597 | private SSLConfig createSslConfig() {
|
579 | 598 | if (this.socket != null || this.sslMode == SSLMode.DISABLE) {
|
580 |
| - return new SSLConfig(SSLMode.DISABLE, null, (hostname, session) -> true); |
| 599 | + return SSLConfig.disabled(); |
581 | 600 | }
|
| 601 | + |
582 | 602 | HostnameVerifier hostnameVerifier = this.sslHostnameVerifier;
|
583 |
| - SslProvider sslProvider = createSslProvider(); |
584 |
| - return new SSLConfig(this.sslMode, sslProvider, hostnameVerifier); |
| 603 | + return new SSLConfig(this.sslMode, createSslProvider(), hostnameVerifier); |
585 | 604 | }
|
586 | 605 |
|
587 |
| - private SslProvider createSslProvider() { |
| 606 | + private Supplier<SslProvider> createSslProvider() { |
588 | 607 | SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
|
589 | 608 | if (this.sslMode.verifyCertificate()) {
|
590 | 609 | if (this.sslRootCert != null) {
|
@@ -625,8 +644,10 @@ private SslProvider createSslProvider() {
|
625 | 644 | String sslPassword = this.sslPassword == null ? null : this.sslPassword.toString();
|
626 | 645 | sslContextBuilder.keyManager(new File(sslCert), new File(sslKey), sslPassword);
|
627 | 646 | }
|
628 |
| - return SslProvider.builder() |
629 |
| - .sslContext(sslContextBuilder) |
| 647 | + |
| 648 | + |
| 649 | + return () -> SslProvider.builder() |
| 650 | + .sslContext(this.sslContextBuilderCustomizer.apply(sslContextBuilder)) |
630 | 651 | .defaultConfiguration(TCP)
|
631 | 652 | .build();
|
632 | 653 | }
|
|
0 commit comments