@@ -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