@@ -45,6 +45,11 @@ def parse(cls, sslmode):
4545        return  getattr (cls , sslmode .replace ('-' , '_' ))
4646
4747
48+ class  SSLNegotiation (compat .StrEnum ):
49+     postgres  =  "postgres" 
50+     direct  =  "direct" 
51+ 
52+ 
4853_ConnectionParameters  =  collections .namedtuple (
4954    'ConnectionParameters' ,
5055    [
@@ -53,7 +58,7 @@ def parse(cls, sslmode):
5358        'database' ,
5459        'ssl' ,
5560        'sslmode' ,
56-         'direct_tls ' ,
61+         'ssl_negotiation ' ,
5762        'server_settings' ,
5863        'target_session_attrs' ,
5964        'krbsrvname' ,
@@ -269,6 +274,7 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
269274    auth_hosts  =  None 
270275    sslcert  =  sslkey  =  sslrootcert  =  sslcrl  =  sslpassword  =  None 
271276    ssl_min_protocol_version  =  ssl_max_protocol_version  =  None 
277+     sslnegotiation  =  None 
272278
273279    if  dsn :
274280        parsed  =  urllib .parse .urlparse (dsn )
@@ -362,6 +368,9 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
362368            if  'sslrootcert'  in  query :
363369                sslrootcert  =  query .pop ('sslrootcert' )
364370
371+             if  'sslnegotiation'  in  query :
372+                 sslnegotiation  =  query .pop ('sslnegotiation' )
373+ 
365374            if  'sslcrl'  in  query :
366375                sslcrl  =  query .pop ('sslcrl' )
367376
@@ -503,13 +512,36 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
503512    if  ssl  is  None  and  have_tcp_addrs :
504513        ssl  =  'prefer' 
505514
515+     if  direct_tls  is  not   None :
516+         sslneg  =  (
517+             SSLNegotiation .direct  if  direct_tls  else  SSLNegotiation .postgres 
518+         )
519+     else :
520+         if  sslnegotiation  is  None :
521+             sslnegotiation  =  os .environ .get ("PGSSLNEGOTIATION" )
522+ 
523+         if  sslnegotiation  is  not   None :
524+             try :
525+                 sslneg  =  SSLNegotiation (sslnegotiation )
526+             except  ValueError :
527+                 modes  =  ', ' .join (
528+                     m .name .replace ('_' , '-' )
529+                     for  m  in  SSLNegotiation 
530+                 )
531+                 raise  exceptions .ClientConfigurationError (
532+                     f'`sslnegotiation` parameter must be one of: { modes }  ' 
533+                 ) from  None 
534+         else :
535+             sslneg  =  SSLNegotiation .postgres 
536+ 
506537    if  isinstance (ssl , (str , SSLMode )):
507538        try :
508539            sslmode  =  SSLMode .parse (ssl )
509540        except  AttributeError :
510541            modes  =  ', ' .join (m .name .replace ('_' , '-' ) for  m  in  SSLMode )
511542            raise  exceptions .ClientConfigurationError (
512-                 '`sslmode` parameter must be one of: {}' .format (modes ))
543+                 '`sslmode` parameter must be one of: {}' .format (modes )
544+             ) from  None 
513545
514546        # docs at https://www.postgresql.org/docs/10/static/libpq-connect.html 
515547        if  sslmode  <  SSLMode .allow :
@@ -676,7 +708,7 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
676708
677709    params  =  _ConnectionParameters (
678710        user = user , password = password , database = database , ssl = ssl ,
679-         sslmode = sslmode , direct_tls = direct_tls ,
711+         sslmode = sslmode , ssl_negotiation = sslneg ,
680712        server_settings = server_settings ,
681713        target_session_attrs = target_session_attrs ,
682714        krbsrvname = krbsrvname , gsslib = gsslib )
@@ -882,9 +914,9 @@ async def __connect_addr(
882914        # UNIX socket 
883915        connector  =  loop .create_unix_connection (proto_factory , addr )
884916
885-     elif  params .ssl  and  params .direct_tls :
886-         # if ssl and direct_tls are given , skip STARTTLS and perform direct  
887-         # SSL connection 
917+     elif  params .ssl  and  params .ssl_negotiation   is   SSLNegotiation . direct :
918+         # if ssl and ssl_negotiation is `direct` , skip STARTTLS and perform 
919+         # direct  SSL connection 
888920        connector  =  loop .create_connection (
889921            proto_factory , * addr , ssl = params .ssl 
890922        )
0 commit comments