3737from decimal import Decimal
3838from uuid import UUID
3939
40+ import urllib3
4041from urllib3 import connection_from_url
4142from urllib3 .connection import HTTPConnection
4243from urllib3 .exceptions import (
4849 SSLError ,
4950)
5051from urllib3 .util .retry import Retry
52+
53+ from crate .client ._pep440 import Version
5154from crate .client .exceptions import (
5255 ConnectionError ,
5356 BlobLocationNotFoundException ,
@@ -274,6 +277,19 @@ def _remove_certs_for_non_https(server, kwargs):
274277 return kwargs
275278
276279
280+ def _update_pool_kwargs_for_ssl_minimum_version (server , kwargs ):
281+ """
282+ On urllib3 v2, re-add support for TLS 1.0 and TLS 1.1.
283+
284+ https://urllib3.readthedocs.io/en/latest/v2-migration-guide.html#https-requires-tls-1-2
285+ """
286+ if Version (urllib3 .__version__ ) >= Version ("2" ):
287+ from urllib3 .util import parse_url
288+ scheme , _ , host , port , * _ = parse_url (server )
289+ if scheme == "https" :
290+ kwargs ["ssl_minimum_version" ] = ssl .TLSVersion .MINIMUM_SUPPORTED
291+
292+
277293def _create_sql_payload (stmt , args , bulk_args ):
278294 if not isinstance (stmt , str ):
279295 raise ValueError ('stmt is not a string' )
@@ -304,7 +320,7 @@ def _get_socket_opts(keepalive=True,
304320 # always use TCP keepalive
305321 opts = [(socket .SOL_SOCKET , socket .SO_KEEPALIVE , 1 )]
306322
307- # hasattr check because some of the options depend on system capabilities
323+ # hasattr check because some options depend on system capabilities
308324 # see https://docs.python.org/3/library/socket.html#socket.SOMAXCONN
309325 if hasattr (socket , 'TCP_KEEPIDLE' ) and tcp_keepidle is not None :
310326 opts .append ((socket .IPPROTO_TCP , socket .TCP_KEEPIDLE , tcp_keepidle ))
@@ -340,6 +356,7 @@ def __init__(self,
340356 error_trace = False ,
341357 cert_file = None ,
342358 key_file = None ,
359+ ssl_relax_minimum_version = False ,
343360 username = None ,
344361 password = None ,
345362 schema = None ,
@@ -380,6 +397,7 @@ def __init__(self,
380397 'socket_tcp_keepintvl' : socket_tcp_keepintvl ,
381398 'socket_tcp_keepcnt' : socket_tcp_keepcnt ,
382399 })
400+ self .ssl_relax_minimum_version = ssl_relax_minimum_version
383401 self .backoff_factor = backoff_factor
384402 self .server_pool = {}
385403 self ._update_server_pool (servers , ** pool_kw )
@@ -400,6 +418,10 @@ def close(self):
400418
401419 def _create_server (self , server , ** pool_kw ):
402420 kwargs = _remove_certs_for_non_https (server , pool_kw )
421+ # After updating to urllib3 v2, optionally retain support for TLS 1.0 and TLS 1.1,
422+ # in order to support connectivity to older versions of CrateDB.
423+ if self .ssl_relax_minimum_version :
424+ _update_pool_kwargs_for_ssl_minimum_version (server , kwargs )
403425 self .server_pool [server ] = Server (server , ** kwargs )
404426
405427 def _update_server_pool (self , servers , ** pool_kw ):
0 commit comments