我来自Ruby,目前正在看Go。我开始编写一些代码来检查给定主机的TLS支持。
var tls_versions = map[uint16]string{ tls.VersionSSL30: "SSLv3", tls.VersionTLS10: "TLSv1.0", tls.VersionTLS11: "TLSv1.1", tls.VersionTLS12: "TLSv1.2", } var refused_re = regexp.MustCompile(": connection refused") var nodns_re = regexp.MustCompile(": no such host") var versionnotsupported_re = regexp.MustCompile(": protocol version not supported") func checkversion(host string) (map[string]bool, error) { // {{ ret := map[string]bool{} for version := tls.VersionSSL30; version <= tls.VersionTLS12; version++ { conn, err := tls.Dial("tcp", host+":443", &tls.Config{ MinVersion: uint16(version), }) if err != nil && (refused_re.MatchString(err.Error()) == true || nodns_re.MatchString(err.Error()) == true) { log.Println(err) return ret, err } if err != nil && versionnotsupported_re.MatchString(err.Error()) == true { ret[tls_versions[uint16(version)]] = false log.Println("Not supported: "+host+" "+tls_versions[uint16(version)]) } ret[tls_versions[uint16(version)]] = true if conn != nil { conn.Close() } } return ret, nil }
来自Ruby我发现这个代码中的错误管理非常难看,因为我是一个错误/改变远没有得到正确的错误原因。我试着玩反射,但无法让它做我想要的。我想知道我是否遗漏了一些显而易见的东西,或者它是不是这样?或者它是否特定于crypto / tls库以避免从任何问题中恢复?
感谢您的帮助。
答案 0 :(得分:3)
Go中有可能进行良好的错误管理。
请参阅Dave C的this answer以获得一个很好的总结和很好的例子。
不幸的是,在tls
套餐的情况下,您运气不好。您尝试检测的错误是由fmt.Errorf()
次调用(委托给errors.New()
)生成的,因此它们在任何情况下都不是特殊的,并且它们没有预先声明,因此您无法做得更好比你目前的解决方案来区分它们。可能开发人员懒得提供更复杂或更容易追溯的错误,或者只是他们认为它不重要而且为了简单而被遗漏;所以他们目前更像是开发人员的信息。
进一步阅读(引自Dave C&#39的回答):