package mongodb import ( "crypto/tls" "errors" "net" "net/url" "strconv" "strings" "time" mgo "gopkg.in/mgo.v2" ) // Unfortunately, mgo doesn't support the ssl parameter in its MongoDB URI parsing logic, so we have to handle that // ourselves. See https://github.com/go-mgo/mgo/issues/84 func parseMongoURI(rawUri string) (*mgo.DialInfo, error) { uri, err := url.Parse(rawUri) if err != nil { return nil, err } info := mgo.DialInfo{ Addrs: strings.Split(uri.Host, ","), Database: strings.TrimPrefix(uri.Path, "/"), Timeout: 10 * time.Second, } if uri.User != nil { info.Username = uri.User.Username() info.Password, _ = uri.User.Password() } query := uri.Query() for key, values := range query { var value string if len(values) > 0 { value = values[0] } switch key { case "authSource": info.Source = value case "authMechanism": info.Mechanism = value case "gssapiServiceName": info.Service = value case "replicaSet": info.ReplicaSetName = value case "maxPoolSize": poolLimit, err := strconv.Atoi(value) if err != nil { return nil, errors.New("bad value for maxPoolSize: " + value) } info.PoolLimit = poolLimit case "ssl": ssl, err := strconv.ParseBool(value) if err != nil { return nil, errors.New("bad value for ssl: " + value) } if ssl { info.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) { return tls.Dial("tcp", addr.String(), &tls.Config{}) } } case "connect": if value == "direct" { info.Direct = true break } if value == "replicaSet" { break } fallthrough default: return nil, errors.New("unsupported connection URL option: " + key + "=" + value) } } return &info, nil }