1616import json
1717import time
1818import ssl
19+ import ipaddress
1920import base64
2021from random import shuffle
2122from urllib .parse import urlparse
@@ -111,6 +112,7 @@ def __init__(self, uri):
111112 self .last_attempt = None
112113 self .did_connect = False
113114 self .discovered = False
115+ self .tls_name = None
114116
115117
116118class Client (object ):
@@ -1346,10 +1348,21 @@ def _process_info(self, info):
13461348 if info ['connect_urls' ]:
13471349 connect_urls = []
13481350 for connect_url in info ['connect_urls' ]:
1349- uri = urlparse ("nats://%s" % connect_url )
1351+ scheme = ''
1352+ if self ._current_server .uri .scheme == 'tls' :
1353+ scheme = 'tls'
1354+ else :
1355+ scheme = 'nats'
1356+
1357+ uri = urlparse ("{}://{}" .format (scheme , connect_url ))
13501358 srv = Srv (uri )
13511359 srv .discovered = True
13521360
1361+ # Check whether we should reuse the original hostname.
1362+ if 'tls_required' in self ._server_info and self ._server_info ['tls_required' ] \
1363+ and self ._host_is_ip (uri .hostname ):
1364+ srv .tls_name = self ._current_server .uri .hostname
1365+
13531366 # Filter for any similar server in the server pool already.
13541367 should_add = True
13551368 for s in self ._server_pool :
@@ -1363,6 +1376,13 @@ def _process_info(self, info):
13631376 for srv in connect_urls :
13641377 self ._server_pool .append (srv )
13651378
1379+ def _host_is_ip (self , connect_url ):
1380+ try :
1381+ ipaddress .ip_address (connect_url )
1382+ return True
1383+ except :
1384+ return False
1385+
13661386 @asyncio .coroutine
13671387 def _process_connect_init (self ):
13681388 """
@@ -1407,13 +1427,19 @@ def _process_connect_init(self):
14071427
14081428 yield from self ._io_writer .drain () # just in case something is left
14091429
1410- self ._io_reader , self ._io_writer = \
1411- yield from asyncio .open_connection (
1412- loop = self ._loop ,
1413- limit = DEFAULT_BUFFER_SIZE ,
1414- sock = sock ,
1415- ssl = ssl_context ,
1416- server_hostname = self ._current_server .uri .hostname ,
1430+ # Check whether to reuse the original hostname for an implicit route.
1431+ hostname = None
1432+ if self ._current_server .tls_name is not None :
1433+ hostname = self ._current_server .tls_name
1434+ else :
1435+ hostname = self ._current_server .uri .hostname
1436+
1437+ self ._io_reader , self ._io_writer = yield from asyncio .open_connection (
1438+ loop = self ._loop ,
1439+ limit = DEFAULT_BUFFER_SIZE ,
1440+ sock = sock ,
1441+ ssl = ssl_context ,
1442+ server_hostname = hostname ,
14171443 )
14181444
14191445 # Refresh state of parser upon reconnect.
0 commit comments