@@ -25,8 +25,9 @@ import (
2525
2626// Registry for custom tls.Configs 
2727var  (
28- 	tlsConfigLock      sync.RWMutex 
29- 	tlsConfigRegistry  map [string ]* tls.Config 
28+ 	tlsConfigLock       sync.RWMutex 
29+ 	tlsConfigRegistry   map [string ]* tls.Config 
30+ 	tlsConfigPreferred  map [string ]struct {}
3031)
3132
3233// RegisterTLSConfig registers a custom tls.Config to be used with sql.Open. 
5556//	}) 
5657//	db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom") 
5758func  RegisterTLSConfig (key  string , config  * tls.Config ) error  {
59+ 	return  registerTLSConfig (key , config , false )
60+ }
61+ 
62+ // RegisterPreferredTLSConfig is like a RegisterTLSConfig, but when the MySQL 
63+ // server does not support TLS the driver will try to connect without TLS. 
64+ // It can be used as a customized "preferred" TLS configuration in the DSN. 
65+ func  RegisterPreferredTLSConfig (key  string , config  * tls.Config ) error  {
66+ 	return  registerTLSConfig (key , config , true )
67+ }
68+ 
69+ func  registerTLSConfig (key  string , config  * tls.Config , preferred  bool ) error  {
5870	if  _ , isBool  :=  readBool (key ); isBool  ||  strings .ToLower (key ) ==  "skip-verify"  ||  strings .ToLower (key ) ==  "preferred"  {
5971		return  fmt .Errorf ("key '%s' is reserved" , key )
6072	}
@@ -63,8 +75,16 @@ func RegisterTLSConfig(key string, config *tls.Config) error {
6375	if  tlsConfigRegistry  ==  nil  {
6476		tlsConfigRegistry  =  make (map [string ]* tls.Config )
6577	}
66- 
6778	tlsConfigRegistry [key ] =  config 
79+ 
80+ 	if  preferred  {
81+ 		if  tlsConfigPreferred  ==  nil  {
82+ 			tlsConfigPreferred  =  make (map [string ]struct {})
83+ 		}
84+ 		tlsConfigPreferred [key ] =  struct {}{}
85+ 	} else  {
86+ 		delete (tlsConfigPreferred , key )
87+ 	}
6888	tlsConfigLock .Unlock ()
6989	return  nil 
7090}
@@ -75,14 +95,18 @@ func DeregisterTLSConfig(key string) {
7595	if  tlsConfigRegistry  !=  nil  {
7696		delete (tlsConfigRegistry , key )
7797	}
98+ 	if  tlsConfigPreferred  !=  nil  {
99+ 		delete (tlsConfigPreferred , key )
100+ 	}
78101	tlsConfigLock .Unlock ()
79102}
80103
81- func  getTLSConfigClone (key  string ) (config  * tls.Config ) {
104+ func  getTLSConfigCloneAndPreferred (key  string ) (config  * tls.Config ,  preferred   bool ) {
82105	tlsConfigLock .RLock ()
83106	if  v , ok  :=  tlsConfigRegistry [key ]; ok  {
84107		config  =  v .Clone ()
85108	}
109+ 	_ , preferred  =  tlsConfigPreferred [key ]
86110	tlsConfigLock .RUnlock ()
87111	return 
88112}
0 commit comments