diff --git a/lib/mongo/util/uri_parser.rb b/lib/mongo/util/uri_parser.rb index fdee374..8e26206 100644 --- a/lib/mongo/util/uri_parser.rb +++ b/lib/mongo/util/uri_parser.rb @@ -20,7 +20,7 @@ module Mongo class URIParser DEFAULT_PORT = 27017 - MONGODB_URI_MATCHER = /(([-_.\w\d]+):([-_\w\d]+)@)?([-.\w\d]+)(:([\w\d]+))?(\/([-\d\w]+))?/ + MONGODB_URI_MATCHER = /(([-_.\w\d]+):([^@]+)@)?([-.\w\d]+)(:([\w\d]+))?(\/([-\d\w]+))?/ MONGODB_URI_SPEC = "mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/database]" SPEC_ATTRS = [:nodes, :auths] OPT_ATTRS = [:connect, :replicaset, :slaveok, :safe, :w, :wtimeout, :fsync] @@ -57,6 +57,8 @@ module Mongo # Parse a MongoDB URI. This method is used by Connection.from_uri. # Returns an array of nodes and an array of db authorizations, if applicable. # + # Note: passwords can contain any character except for a ','. + # # @core connections def initialize(string) if string =~ /^mongodb:\/\// diff --git a/test/uri_test.rb b/test/uri_test.rb index d2d9acb..84e1b1c 100644 --- a/test/uri_test.rb +++ b/test/uri_test.rb @@ -26,6 +26,22 @@ class TestThreading < Test::Unit::TestCase assert_equal 27017, parser.nodes[1][1] end + def test_complex_passwords + parser = Mongo::URIParser.new('mongodb://bob:secret.word@a.example.com:27018/test') + assert_equal "bob", parser.auths[0]["username"] + assert_equal "secret.word", parser.auths[0]["password"] + + parser = Mongo::URIParser.new('mongodb://bob:s-_3#%R.t@a.example.com:27018/test') + assert_equal "bob", parser.auths[0]["username"] + assert_equal "s-_3#%R.t", parser.auths[0]["password"] + end + + def test_passwords_contain_no_commas + assert_raise MongoArgumentError do + Mongo::URIParser.new('mongodb://bob:a,b@a.example.com:27018/test') + end + end + def test_multiple_uris_with_auths parser = Mongo::URIParser.new('mongodb://bob:secret@a.example.com:27018/test,joe:secret2@b.example.com/test2') assert_equal 2, parser.nodes.length