提交 48cd4b98 编写于 作者: X xiyangxixian

DSN 解析优化, 并支持密码特殊字符

上级 677b8cf4
......@@ -269,60 +269,55 @@ func parseDSN(odbc string, d *dsn) *dsn {
return &dsn{Disable: true}
}
// username:password@ip:port/database
l1 := strings.Split(odbc, "@")
if len(l1) < 2 {
if strings.HasPrefix(l1[0], ":") {
// ":port/database"
l2 := strings.Split(strings.TrimLeft(l1[0], ":"), "/")
if l2[0] == "" {
addr = strings.Split(addr, ":")[0] + ":3306"
if len(l2) > 1 {
schema = strings.Split(l2[1], "?")[0]
}
} else {
addr = strings.Split(addr, ":")[0] + ":" + l2[0]
if len(l2) > 1 {
schema = strings.Split(l2[1], "?")[0]
}
}
} else if strings.HasPrefix(l1[0], "/") {
// "/database"
l2 := strings.TrimLeft(l1[0], "/")
schema = l2
} else {
// ip:port/database
l2 := strings.Split(l1[0], "/")
if len(l2) == 2 {
addr = l2[0]
schema = strings.Split(l2[1], "?")[0]
} else {
addr = l2[0]
}
}
// userInfo@hostInfo/database
regexStr1 := `^(.*)@(.*?)/(.*?)($|\?)(.*)`
// hostInfo/database
regexStr2 := `^(.*)/(.*?)($|\?)(.*)`
// userInfo@hostInfo
regexStr3 := `^(.*)@(.*?)($|\?)(.*)`
var userInfo, hostInfo, query string
// DSN 格式匹配
if res := regexp.MustCompile(regexStr1).FindStringSubmatch(odbc); len(res) > 0 {
userInfo = res[1]
hostInfo = res[2]
schema = res[3]
query = res[5]
} else if res := regexp.MustCompile(regexStr2).FindStringSubmatch(odbc); len(res) > 0 {
hostInfo = res[1]
schema = res[2]
query = res[4]
} else if res := regexp.MustCompile(regexStr3).FindStringSubmatch(odbc); len(res) > 0 {
userInfo = res[1]
hostInfo = res[2]
query = res[4]
} else {
// user:password
l2 := strings.Split(l1[0], ":")
if len(l2) == 2 {
user = l2[0]
password = l2[1]
} else {
user = l2[0]
}
// ip:port/database
l3 := strings.Split(l1[1], "/")
if len(l3) == 2 {
addr = l3[0]
schema = strings.Split(l3[1], "?")[0]
} else {
addr = l3[0]
}
hostInfo = odbc
}
// 解析用户信息
if userInfo != "" {
user = strings.Split(userInfo, ":")[0]
// 防止密码中含有与用户名相同的字符, 所以用正则替换, 剩下的就是密码
password = strings.TrimLeft(regexp.MustCompile("^" + user).ReplaceAllString(userInfo, ""), ":")
}
// 其他flag参数,目前只支持charset :(
if len(strings.Split(odbc, "?")) > 1 {
flags := strings.Split(strings.Split(odbc, "?")[1], "&")
for _, f := range flags {
// 解析主机信息
host := strings.Split(hostInfo, ":")[0]
port := strings.TrimLeft(strings.Replace(hostInfo, host, "", 1), ":")
if host == "" {
host = "127.0.0.1"
}
if port == ""{
port = "3306"
}
addr = host + ":" + port
// 解析查询字符串
if (query != "") {
params := strings.Split(query, "&")
for _, f := range params {
attr := strings.Split(f, "=")
if len(attr) > 1 {
arg := strings.TrimSpace(attr[0])
......@@ -336,20 +331,6 @@ func parseDSN(odbc string, d *dsn) *dsn {
}
}
// 自动补端口
if !strings.Contains(addr, ":") {
addr = addr + ":3306"
} else {
if strings.HasSuffix(addr, ":") {
addr = addr + "3306"
}
}
// 默认走127.0.0.1
if strings.HasPrefix(addr, ":") {
addr = "127.0.0.1" + addr
}
// 默认用information_schema库
if schema == "" {
schema = "information_schema"
......
......@@ -48,6 +48,8 @@ func TestParseDSN(t *testing.T) {
"user:password@hostname:3307",
"user:password@hostname:/database",
"user:password@:3307/database",
"user@hostname/dbname",
"user:pwd:pwd@pwd/pwd@hostname/dbname",
"user:password@",
"hostname:3307/database",
"@hostname:3307/database",
......
......@@ -3,6 +3,8 @@
&common.dsn{Addr:"hostname:3307", Schema:"information_schema", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Version:999}
&common.dsn{Addr:"hostname:3306", Schema:"database", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Version:999}
&common.dsn{Addr:"127.0.0.1:3307", Schema:"database", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Version:999}
&common.dsn{Addr:"hostname:3306", Schema:"dbname", User:"user", Password:"", Charset:"utf8mb4", Disable:false, Version:999}
&common.dsn{Addr:"hostname:3306", Schema:"dbname", User:"user", Password:"pwd:pwd@pwd/pwd", Charset:"utf8mb4", Disable:false, Version:999}
&common.dsn{Addr:"127.0.0.1:3306", Schema:"information_schema", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Version:999}
&common.dsn{Addr:"hostname:3307", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Version:999}
&common.dsn{Addr:"hostname:3307", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Version:999}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册