File tree Expand file tree Collapse file tree 4 files changed +41
-5
lines changed Expand file tree Collapse file tree 4 files changed +41
-5
lines changed Original file line number Diff line number Diff line change @@ -650,7 +650,10 @@ def __init__(
650
650
opts = common ._CaseInsensitiveDictionary ()
651
651
fqdn = None
652
652
for entity in host :
653
- if "://" in entity :
653
+ # A hostname can only include a-z, 0-9, '-' and '.'. If we find a '/'
654
+ # it must be a URI,
655
+ # https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
656
+ if "/" in entity :
654
657
# Determine connection timeout from kwargs.
655
658
timeout = keyword_opts .get ("connecttimeoutms" )
656
659
if timeout is not None :
Original file line number Diff line number Diff line change 14
14
15
15
"""Support for resolving hosts and options from mongodb+srv:// URIs."""
16
16
17
+ import ipaddress
18
+
17
19
try :
18
20
from dns import resolver
19
21
_HAVE_DNSPYTHON = True
@@ -40,20 +42,29 @@ def _resolve(*args, **kwargs):
40
42
# dnspython 1.X
41
43
return resolver .query (* args , ** kwargs )
42
44
45
+ _INVALID_HOST_MSG = (
46
+ "Invalid URI host: %s is not a valid hostname for 'mongodb+srv://'. "
47
+ "Did you mean to use 'mongodb://'?" )
43
48
44
49
class _SrvResolver (object ):
45
50
def __init__ (self , fqdn , connect_timeout = None ):
46
51
self .__fqdn = fqdn
47
52
self .__connect_timeout = connect_timeout or CONNECT_TIMEOUT
48
53
49
54
# Validate the fully qualified domain name.
55
+ try :
56
+ ipaddress .ip_address (fqdn )
57
+ raise ConfigurationError (_INVALID_HOST_MSG % ("an IP address" ,))
58
+ except ValueError :
59
+ pass
60
+
50
61
try :
51
62
self .__plist = self .__fqdn .split ("." )[1 :]
52
63
except Exception :
53
- raise ConfigurationError ("Invalid URI host: %s" % (fqdn ,))
64
+ raise ConfigurationError (_INVALID_HOST_MSG % (fqdn ,))
54
65
self .__slen = len (self .__plist )
55
66
if self .__slen < 2 :
56
- raise ConfigurationError ("Invalid URI host: %s" % (fqdn ,))
67
+ raise ConfigurationError (_INVALID_HOST_MSG % (fqdn ,))
57
68
58
69
def get_options (self ):
59
70
try :
Original file line number Diff line number Diff line change @@ -166,6 +166,20 @@ def test_max_pool_size_zero(self):
166
166
with self .assertRaises (ValueError ):
167
167
MongoClient (maxPoolSize = 0 )
168
168
169
+ def test_uri_detection (self ):
170
+ self .assertRaises (
171
+ ConfigurationError ,
172
+ MongoClient ,
173
+ "/foo" )
174
+ self .assertRaises (
175
+ ConfigurationError ,
176
+ MongoClient ,
177
+ "://" )
178
+ self .assertRaises (
179
+ ConfigurationError ,
180
+ MongoClient ,
181
+ "foo/" )
182
+
169
183
def test_get_db (self ):
170
184
def make_db (base , name ):
171
185
return base [name ]
Original file line number Diff line number Diff line change @@ -142,12 +142,20 @@ class TestParsingErrors(unittest.TestCase):
142
142
def test_invalid_host (self ):
143
143
self .assertRaisesRegex (
144
144
ConfigurationError ,
145
- "Invalid URI host: mongodb" ,
145
+ "Invalid URI host: mongodb is not " ,
146
146
MongoClient , "mongodb+srv://mongodb" )
147
147
self .assertRaisesRegex (
148
148
ConfigurationError ,
149
- "Invalid URI host: mongodb.com" ,
149
+ "Invalid URI host: mongodb.com is not " ,
150
150
MongoClient , "mongodb+srv://mongodb.com" )
151
+ self .assertRaisesRegex (
152
+ ConfigurationError ,
153
+ "Invalid URI host: an IP address is not" ,
154
+ MongoClient , "mongodb+srv://127.0.0.1" )
155
+ self .assertRaisesRegex (
156
+ ConfigurationError ,
157
+ "Invalid URI host: an IP address is not" ,
158
+ MongoClient , "mongodb+srv://[::1]" )
151
159
152
160
153
161
if __name__ == '__main__' :
You can’t perform that action at this time.
0 commit comments