1212import sys
1313import tempfile
1414
15+ from base64 import b64encode
16+
1517def hexescape (char ):
1618 """Escape char as RFC 2396 specifies"""
1719 hex_repr = hex (ord (char ))[2 :].upper ()
@@ -42,8 +44,8 @@ def fakehttp(self, fakedata):
4244 class FakeSocket (io .BytesIO ):
4345 io_refs = 1
4446
45- def sendall (self , str ):
46- pass
47+ def sendall (self , data ):
48+ FakeHTTPConnection . buf = data
4749
4850 def makefile (self , * args , ** kwds ):
4951 self .io_refs += 1
@@ -65,8 +67,13 @@ def close(self):
6567 io .BytesIO .close (self )
6668
6769 class FakeHTTPConnection (http .client .HTTPConnection ):
70+
71+ # buffer to store data for verification in urlopen tests.
72+ buf = None
73+
6874 def connect (self ):
6975 self .sock = FakeSocket (fakedata )
76+
7077 self ._connection_class = http .client .HTTPConnection
7178 http .client .HTTPConnection = FakeHTTPConnection
7279
@@ -268,6 +275,25 @@ def test_userpass_inurl(self):
268275 finally :
269276 self .unfakehttp ()
270277
278+ def test_userpass_inurl_w_spaces (self ):
279+ self .fakehttp (b"HTTP/1.0 200 OK\r \n \r \n Hello!" )
280+ try :
281+ userpass = "a b:c d"
282+ url = "http://{}@python.org/" .format (userpass )
283+ fakehttp_wrapper = http .client .HTTPConnection
284+ authorization = ("Authorization: Basic %s\r \n " %
285+ b64encode (userpass .encode ("ASCII" )).decode ("ASCII" ))
286+ fp = urlopen (url )
287+ # The authorization header must be in place
288+ self .assertIn (authorization , fakehttp_wrapper .buf .decode ("UTF-8" ))
289+ self .assertEqual (fp .readline (), b"Hello!" )
290+ self .assertEqual (fp .readline (), b"" )
291+ # the spaces are quoted in URL so no match
292+ self .assertNotEqual (fp .geturl (), url )
293+ self .assertEqual (fp .getcode (), 200 )
294+ finally :
295+ self .unfakehttp ()
296+
271297class urlretrieve_FileTests (unittest .TestCase ):
272298 """Test urllib.urlretrieve() on local files"""
273299
@@ -1111,6 +1137,9 @@ def test_splitpasswd(self):
11111137 self .assertEqual (('user' , 'a\f b' ),urllib .parse .splitpasswd ('user:a\f b' ))
11121138 self .assertEqual (('user' , 'a\v b' ),urllib .parse .splitpasswd ('user:a\v b' ))
11131139 self .assertEqual (('user' , 'a:b' ),urllib .parse .splitpasswd ('user:a:b' ))
1140+ self .assertEqual (('user' , 'a b' ),urllib .parse .splitpasswd ('user:a b' ))
1141+ self .assertEqual (('user 2' , 'ab' ),urllib .parse .splitpasswd ('user 2:ab' ))
1142+ self .assertEqual (('user+1' , 'a+b' ),urllib .parse .splitpasswd ('user+1:a+b' ))
11141143
11151144 def test_thishost (self ):
11161145 """Test the urllib.request.thishost utility function returns a tuple"""
0 commit comments