@@ -432,6 +432,12 @@ public class Options {
432432 * Property used to set the path to a credentials file to be used in a FileAuthHandler
433433 */
434434 public static final String PROP_CREDENTIAL_PATH = PFX + "credential.path" ;
435+ /**
436+ * Property used to configure tls first behavior
437+ * This property is a boolean flag, telling connections whether
438+ * to do TLS upgrade first, before INFO
439+ */
440+ public static final String PROP_TLS_FIRST = PFX + "tls.first" ;
435441 /**
436442 * This property is used to enable support for UTF8 subjects. See {@link Builder#supportUTF8Subjects() supportUTF8Subjects()}
437443 * @deprecated only plain ascii subjects are supported
@@ -564,6 +570,7 @@ public class Options {
564570 private final int maxMessagesInOutgoingQueue ;
565571 private final boolean discardMessagesWhenOutgoingQueueFull ;
566572 private final boolean ignoreDiscoveredServers ;
573+ private final boolean tlsFirst ;
567574
568575 private final AuthHandler authHandler ;
569576 private final ReconnectDelayHandler reconnectDelayHandler ;
@@ -671,6 +678,7 @@ public static class Builder {
671678 private int maxMessagesInOutgoingQueue = DEFAULT_MAX_MESSAGES_IN_OUTGOING_QUEUE ;
672679 private boolean discardMessagesWhenOutgoingQueueFull = DEFAULT_DISCARD_MESSAGES_WHEN_OUTGOING_QUEUE_FULL ;
673680 private boolean ignoreDiscoveredServers = false ;
681+ private boolean tlsFirst = false ;
674682 private ServerPool serverPool = null ;
675683 private DispatcherFactory dispatcherFactory = null ;
676684
@@ -795,6 +803,8 @@ public Builder properties(Properties props) {
795803 booleanProperty (props , PROP_DISCARD_MESSAGES_WHEN_OUTGOING_QUEUE_FULL , b -> this .discardMessagesWhenOutgoingQueueFull = b );
796804
797805 booleanProperty (props , PROP_IGNORE_DISCOVERED_SERVERS , b -> this .ignoreDiscoveredServers = b );
806+ booleanProperty (props , PROP_TLS_FIRST , b -> this .tlsFirst = b );
807+
798808 classnameProperty (props , PROP_SERVERS_POOL_IMPLEMENTATION_CLASS , o -> this .serverPool = (ServerPool ) o );
799809 classnameProperty (props , PROP_DISPATCHER_FACTORY_CLASS , o -> this .dispatcherFactory = (DispatcherFactory ) o );
800810
@@ -1465,6 +1475,20 @@ public Builder ignoreDiscoveredServers() {
14651475 return this ;
14661476 }
14671477
1478+ /**
1479+ * Set TLS Handshake First behavior on. Default is off.
1480+ * TLS Handshake First is used to instruct the library perform
1481+ * the TLS handshake right after the connect and before receiving
1482+ * the INFO protocol from the server. If this option is enabled
1483+ * but the server is not configured to perform the TLS handshake
1484+ * first, the connection will fail.
1485+ * @return the Builder for chaining
1486+ */
1487+ public Builder tlsFirst () {
1488+ this .tlsFirst = true ;
1489+ return this ;
1490+ }
1491+
14681492 /**
14691493 * Set the ServerPool implementation for connections to use instead of the default implementation
14701494 * @param serverPool the implementation
@@ -1642,6 +1666,7 @@ public Builder(Options o) {
16421666 this .proxy = o .proxy ;
16431667
16441668 this .ignoreDiscoveredServers = o .ignoreDiscoveredServers ;
1669+ this .tlsFirst = o .tlsFirst ;
16451670
16461671 this .serverPool = o .serverPool ;
16471672 this .dispatcherFactory = o .dispatcherFactory ;
@@ -1703,6 +1728,7 @@ private Options(Builder b) {
17031728 this .proxy = b .proxy ;
17041729
17051730 this .ignoreDiscoveredServers = b .ignoreDiscoveredServers ;
1731+ this .tlsFirst = b .tlsFirst ;
17061732
17071733 this .serverPool = b .serverPool ;
17081734 this .dispatcherFactory = b .dispatcherFactory ;
@@ -1913,7 +1939,7 @@ public int getMaxControlLine() {
19131939 * @return true if there is an sslContext for this Options, otherwise false, see {@link Builder#secure() secure()} in the builder doc
19141940 */
19151941 public boolean isTLSRequired () {
1916- return ( this .sslContext != null ) ;
1942+ return tlsFirst || this .sslContext != null ;
19171943 }
19181944
19191945 /**
@@ -2080,6 +2106,14 @@ public boolean isIgnoreDiscoveredServers() {
20802106 return ignoreDiscoveredServers ;
20812107 }
20822108
2109+ /**
2110+ * Get whether to do tls first
2111+ * @return the flag
2112+ */
2113+ public boolean isTlsFirst () {
2114+ return tlsFirst ;
2115+ }
2116+
20832117 /**
20842118 * Get the ServerPool implementation. If null, a default implementation is used.
20852119 * @return the ServerPool implementation
0 commit comments