17db96d56Sopenharmony_ci"""Regression tests for what was in Python 2's "urllib" module""" 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciimport urllib.parse 47db96d56Sopenharmony_ciimport urllib.request 57db96d56Sopenharmony_ciimport urllib.error 67db96d56Sopenharmony_ciimport http.client 77db96d56Sopenharmony_ciimport email.message 87db96d56Sopenharmony_ciimport io 97db96d56Sopenharmony_ciimport unittest 107db96d56Sopenharmony_cifrom unittest.mock import patch 117db96d56Sopenharmony_cifrom test import support 127db96d56Sopenharmony_cifrom test.support import os_helper 137db96d56Sopenharmony_cifrom test.support import socket_helper 147db96d56Sopenharmony_cifrom test.support import warnings_helper 157db96d56Sopenharmony_ciimport os 167db96d56Sopenharmony_citry: 177db96d56Sopenharmony_ci import ssl 187db96d56Sopenharmony_ciexcept ImportError: 197db96d56Sopenharmony_ci ssl = None 207db96d56Sopenharmony_ciimport sys 217db96d56Sopenharmony_ciimport tempfile 227db96d56Sopenharmony_cifrom nturl2path import url2pathname, pathname2url 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_cifrom base64 import b64encode 257db96d56Sopenharmony_ciimport collections 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ciif not socket_helper.has_gethostname: 297db96d56Sopenharmony_ci raise unittest.SkipTest("test requires gethostname()") 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_cidef hexescape(char): 337db96d56Sopenharmony_ci """Escape char as RFC 2396 specifies""" 347db96d56Sopenharmony_ci hex_repr = hex(ord(char))[2:].upper() 357db96d56Sopenharmony_ci if len(hex_repr) == 1: 367db96d56Sopenharmony_ci hex_repr = "0%s" % hex_repr 377db96d56Sopenharmony_ci return "%" + hex_repr 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci# Shortcut for testing FancyURLopener 407db96d56Sopenharmony_ci_urlopener = None 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_cidef urlopen(url, data=None, proxies=None): 447db96d56Sopenharmony_ci """urlopen(url [, data]) -> open file-like object""" 457db96d56Sopenharmony_ci global _urlopener 467db96d56Sopenharmony_ci if proxies is not None: 477db96d56Sopenharmony_ci opener = urllib.request.FancyURLopener(proxies=proxies) 487db96d56Sopenharmony_ci elif not _urlopener: 497db96d56Sopenharmony_ci opener = FancyURLopener() 507db96d56Sopenharmony_ci _urlopener = opener 517db96d56Sopenharmony_ci else: 527db96d56Sopenharmony_ci opener = _urlopener 537db96d56Sopenharmony_ci if data is None: 547db96d56Sopenharmony_ci return opener.open(url) 557db96d56Sopenharmony_ci else: 567db96d56Sopenharmony_ci return opener.open(url, data) 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_cidef FancyURLopener(): 607db96d56Sopenharmony_ci with warnings_helper.check_warnings( 617db96d56Sopenharmony_ci ('FancyURLopener style of invoking requests is deprecated.', 627db96d56Sopenharmony_ci DeprecationWarning)): 637db96d56Sopenharmony_ci return urllib.request.FancyURLopener() 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_cidef fakehttp(fakedata, mock_close=False): 677db96d56Sopenharmony_ci class FakeSocket(io.BytesIO): 687db96d56Sopenharmony_ci io_refs = 1 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci def sendall(self, data): 717db96d56Sopenharmony_ci FakeHTTPConnection.buf = data 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci def makefile(self, *args, **kwds): 747db96d56Sopenharmony_ci self.io_refs += 1 757db96d56Sopenharmony_ci return self 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci def read(self, amt=None): 787db96d56Sopenharmony_ci if self.closed: 797db96d56Sopenharmony_ci return b"" 807db96d56Sopenharmony_ci return io.BytesIO.read(self, amt) 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci def readline(self, length=None): 837db96d56Sopenharmony_ci if self.closed: 847db96d56Sopenharmony_ci return b"" 857db96d56Sopenharmony_ci return io.BytesIO.readline(self, length) 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci def close(self): 887db96d56Sopenharmony_ci self.io_refs -= 1 897db96d56Sopenharmony_ci if self.io_refs == 0: 907db96d56Sopenharmony_ci io.BytesIO.close(self) 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ci class FakeHTTPConnection(http.client.HTTPConnection): 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci # buffer to store data for verification in urlopen tests. 957db96d56Sopenharmony_ci buf = None 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci def connect(self): 987db96d56Sopenharmony_ci self.sock = FakeSocket(self.fakedata) 997db96d56Sopenharmony_ci type(self).fakesock = self.sock 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci if mock_close: 1027db96d56Sopenharmony_ci # bpo-36918: HTTPConnection destructor calls close() which calls 1037db96d56Sopenharmony_ci # flush(). Problem: flush() calls self.fp.flush() which raises 1047db96d56Sopenharmony_ci # "ValueError: I/O operation on closed file" which is logged as an 1057db96d56Sopenharmony_ci # "Exception ignored in". Override close() to silence this error. 1067db96d56Sopenharmony_ci def close(self): 1077db96d56Sopenharmony_ci pass 1087db96d56Sopenharmony_ci FakeHTTPConnection.fakedata = fakedata 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci return FakeHTTPConnection 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ciclass FakeHTTPMixin(object): 1147db96d56Sopenharmony_ci def fakehttp(self, fakedata, mock_close=False): 1157db96d56Sopenharmony_ci fake_http_class = fakehttp(fakedata, mock_close=mock_close) 1167db96d56Sopenharmony_ci self._connection_class = http.client.HTTPConnection 1177db96d56Sopenharmony_ci http.client.HTTPConnection = fake_http_class 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci def unfakehttp(self): 1207db96d56Sopenharmony_ci http.client.HTTPConnection = self._connection_class 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_ciclass FakeFTPMixin(object): 1247db96d56Sopenharmony_ci def fakeftp(self): 1257db96d56Sopenharmony_ci class FakeFtpWrapper(object): 1267db96d56Sopenharmony_ci def __init__(self, user, passwd, host, port, dirs, timeout=None, 1277db96d56Sopenharmony_ci persistent=True): 1287db96d56Sopenharmony_ci pass 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci def retrfile(self, file, type): 1317db96d56Sopenharmony_ci return io.BytesIO(), 0 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci def close(self): 1347db96d56Sopenharmony_ci pass 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci self._ftpwrapper_class = urllib.request.ftpwrapper 1377db96d56Sopenharmony_ci urllib.request.ftpwrapper = FakeFtpWrapper 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci def unfakeftp(self): 1407db96d56Sopenharmony_ci urllib.request.ftpwrapper = self._ftpwrapper_class 1417db96d56Sopenharmony_ci 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ciclass urlopen_FileTests(unittest.TestCase): 1447db96d56Sopenharmony_ci """Test urlopen() opening a temporary file. 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ci Try to test as much functionality as possible so as to cut down on reliance 1477db96d56Sopenharmony_ci on connecting to the Net for testing. 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci """ 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_ci def setUp(self): 1527db96d56Sopenharmony_ci # Create a temp file to use for testing 1537db96d56Sopenharmony_ci self.text = bytes("test_urllib: %s\n" % self.__class__.__name__, 1547db96d56Sopenharmony_ci "ascii") 1557db96d56Sopenharmony_ci f = open(os_helper.TESTFN, 'wb') 1567db96d56Sopenharmony_ci try: 1577db96d56Sopenharmony_ci f.write(self.text) 1587db96d56Sopenharmony_ci finally: 1597db96d56Sopenharmony_ci f.close() 1607db96d56Sopenharmony_ci self.pathname = os_helper.TESTFN 1617db96d56Sopenharmony_ci self.quoted_pathname = urllib.parse.quote(self.pathname) 1627db96d56Sopenharmony_ci self.returned_obj = urlopen("file:%s" % self.quoted_pathname) 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci def tearDown(self): 1657db96d56Sopenharmony_ci """Shut down the open object""" 1667db96d56Sopenharmony_ci self.returned_obj.close() 1677db96d56Sopenharmony_ci os.remove(os_helper.TESTFN) 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci def test_interface(self): 1707db96d56Sopenharmony_ci # Make sure object returned by urlopen() has the specified methods 1717db96d56Sopenharmony_ci for attr in ("read", "readline", "readlines", "fileno", 1727db96d56Sopenharmony_ci "close", "info", "geturl", "getcode", "__iter__"): 1737db96d56Sopenharmony_ci self.assertTrue(hasattr(self.returned_obj, attr), 1747db96d56Sopenharmony_ci "object returned by urlopen() lacks %s attribute" % 1757db96d56Sopenharmony_ci attr) 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci def test_read(self): 1787db96d56Sopenharmony_ci self.assertEqual(self.text, self.returned_obj.read()) 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci def test_readline(self): 1817db96d56Sopenharmony_ci self.assertEqual(self.text, self.returned_obj.readline()) 1827db96d56Sopenharmony_ci self.assertEqual(b'', self.returned_obj.readline(), 1837db96d56Sopenharmony_ci "calling readline() after exhausting the file did not" 1847db96d56Sopenharmony_ci " return an empty string") 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci def test_readlines(self): 1877db96d56Sopenharmony_ci lines_list = self.returned_obj.readlines() 1887db96d56Sopenharmony_ci self.assertEqual(len(lines_list), 1, 1897db96d56Sopenharmony_ci "readlines() returned the wrong number of lines") 1907db96d56Sopenharmony_ci self.assertEqual(lines_list[0], self.text, 1917db96d56Sopenharmony_ci "readlines() returned improper text") 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci def test_fileno(self): 1947db96d56Sopenharmony_ci file_num = self.returned_obj.fileno() 1957db96d56Sopenharmony_ci self.assertIsInstance(file_num, int, "fileno() did not return an int") 1967db96d56Sopenharmony_ci self.assertEqual(os.read(file_num, len(self.text)), self.text, 1977db96d56Sopenharmony_ci "Reading on the file descriptor returned by fileno() " 1987db96d56Sopenharmony_ci "did not return the expected text") 1997db96d56Sopenharmony_ci 2007db96d56Sopenharmony_ci def test_close(self): 2017db96d56Sopenharmony_ci # Test close() by calling it here and then having it be called again 2027db96d56Sopenharmony_ci # by the tearDown() method for the test 2037db96d56Sopenharmony_ci self.returned_obj.close() 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_ci def test_headers(self): 2067db96d56Sopenharmony_ci self.assertIsInstance(self.returned_obj.headers, email.message.Message) 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci def test_url(self): 2097db96d56Sopenharmony_ci self.assertEqual(self.returned_obj.url, self.quoted_pathname) 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci def test_status(self): 2127db96d56Sopenharmony_ci self.assertIsNone(self.returned_obj.status) 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci def test_info(self): 2157db96d56Sopenharmony_ci self.assertIsInstance(self.returned_obj.info(), email.message.Message) 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci def test_geturl(self): 2187db96d56Sopenharmony_ci self.assertEqual(self.returned_obj.geturl(), self.quoted_pathname) 2197db96d56Sopenharmony_ci 2207db96d56Sopenharmony_ci def test_getcode(self): 2217db96d56Sopenharmony_ci self.assertIsNone(self.returned_obj.getcode()) 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci def test_iter(self): 2247db96d56Sopenharmony_ci # Test iterator 2257db96d56Sopenharmony_ci # Don't need to count number of iterations since test would fail the 2267db96d56Sopenharmony_ci # instant it returned anything beyond the first line from the 2277db96d56Sopenharmony_ci # comparison. 2287db96d56Sopenharmony_ci # Use the iterator in the usual implicit way to test for ticket #4608. 2297db96d56Sopenharmony_ci for line in self.returned_obj: 2307db96d56Sopenharmony_ci self.assertEqual(line, self.text) 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci def test_relativelocalfile(self): 2337db96d56Sopenharmony_ci self.assertRaises(ValueError,urllib.request.urlopen,'./' + self.pathname) 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci 2367db96d56Sopenharmony_ciclass ProxyTests(unittest.TestCase): 2377db96d56Sopenharmony_ci 2387db96d56Sopenharmony_ci def setUp(self): 2397db96d56Sopenharmony_ci # Records changes to env vars 2407db96d56Sopenharmony_ci self.env = self.enterContext(os_helper.EnvironmentVarGuard()) 2417db96d56Sopenharmony_ci # Delete all proxy related env vars 2427db96d56Sopenharmony_ci for k in list(os.environ): 2437db96d56Sopenharmony_ci if 'proxy' in k.lower(): 2447db96d56Sopenharmony_ci self.env.unset(k) 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci def test_getproxies_environment_keep_no_proxies(self): 2477db96d56Sopenharmony_ci self.env.set('NO_PROXY', 'localhost') 2487db96d56Sopenharmony_ci proxies = urllib.request.getproxies_environment() 2497db96d56Sopenharmony_ci # getproxies_environment use lowered case truncated (no '_proxy') keys 2507db96d56Sopenharmony_ci self.assertEqual('localhost', proxies['no']) 2517db96d56Sopenharmony_ci # List of no_proxies with space. 2527db96d56Sopenharmony_ci self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com:1234') 2537db96d56Sopenharmony_ci self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com')) 2547db96d56Sopenharmony_ci self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com:8888')) 2557db96d56Sopenharmony_ci self.assertTrue(urllib.request.proxy_bypass_environment('newdomain.com:1234')) 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci def test_proxy_cgi_ignore(self): 2587db96d56Sopenharmony_ci try: 2597db96d56Sopenharmony_ci self.env.set('HTTP_PROXY', 'http://somewhere:3128') 2607db96d56Sopenharmony_ci proxies = urllib.request.getproxies_environment() 2617db96d56Sopenharmony_ci self.assertEqual('http://somewhere:3128', proxies['http']) 2627db96d56Sopenharmony_ci self.env.set('REQUEST_METHOD', 'GET') 2637db96d56Sopenharmony_ci proxies = urllib.request.getproxies_environment() 2647db96d56Sopenharmony_ci self.assertNotIn('http', proxies) 2657db96d56Sopenharmony_ci finally: 2667db96d56Sopenharmony_ci self.env.unset('REQUEST_METHOD') 2677db96d56Sopenharmony_ci self.env.unset('HTTP_PROXY') 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_ci def test_proxy_bypass_environment_host_match(self): 2707db96d56Sopenharmony_ci bypass = urllib.request.proxy_bypass_environment 2717db96d56Sopenharmony_ci self.env.set('NO_PROXY', 2727db96d56Sopenharmony_ci 'localhost, anotherdomain.com, newdomain.com:1234, .d.o.t') 2737db96d56Sopenharmony_ci self.assertTrue(bypass('localhost')) 2747db96d56Sopenharmony_ci self.assertTrue(bypass('LocalHost')) # MixedCase 2757db96d56Sopenharmony_ci self.assertTrue(bypass('LOCALHOST')) # UPPERCASE 2767db96d56Sopenharmony_ci self.assertTrue(bypass('.localhost')) 2777db96d56Sopenharmony_ci self.assertTrue(bypass('newdomain.com:1234')) 2787db96d56Sopenharmony_ci self.assertTrue(bypass('.newdomain.com:1234')) 2797db96d56Sopenharmony_ci self.assertTrue(bypass('foo.d.o.t')) # issue 29142 2807db96d56Sopenharmony_ci self.assertTrue(bypass('d.o.t')) 2817db96d56Sopenharmony_ci self.assertTrue(bypass('anotherdomain.com:8888')) 2827db96d56Sopenharmony_ci self.assertTrue(bypass('.anotherdomain.com:8888')) 2837db96d56Sopenharmony_ci self.assertTrue(bypass('www.newdomain.com:1234')) 2847db96d56Sopenharmony_ci self.assertFalse(bypass('prelocalhost')) 2857db96d56Sopenharmony_ci self.assertFalse(bypass('newdomain.com')) # no port 2867db96d56Sopenharmony_ci self.assertFalse(bypass('newdomain.com:1235')) # wrong port 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci def test_proxy_bypass_environment_always_match(self): 2897db96d56Sopenharmony_ci bypass = urllib.request.proxy_bypass_environment 2907db96d56Sopenharmony_ci self.env.set('NO_PROXY', '*') 2917db96d56Sopenharmony_ci self.assertTrue(bypass('newdomain.com')) 2927db96d56Sopenharmony_ci self.assertTrue(bypass('newdomain.com:1234')) 2937db96d56Sopenharmony_ci self.env.set('NO_PROXY', '*, anotherdomain.com') 2947db96d56Sopenharmony_ci self.assertTrue(bypass('anotherdomain.com')) 2957db96d56Sopenharmony_ci self.assertFalse(bypass('newdomain.com')) 2967db96d56Sopenharmony_ci self.assertFalse(bypass('newdomain.com:1234')) 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_ci def test_proxy_bypass_environment_newline(self): 2997db96d56Sopenharmony_ci bypass = urllib.request.proxy_bypass_environment 3007db96d56Sopenharmony_ci self.env.set('NO_PROXY', 3017db96d56Sopenharmony_ci 'localhost, anotherdomain.com, newdomain.com:1234') 3027db96d56Sopenharmony_ci self.assertFalse(bypass('localhost\n')) 3037db96d56Sopenharmony_ci self.assertFalse(bypass('anotherdomain.com:8888\n')) 3047db96d56Sopenharmony_ci self.assertFalse(bypass('newdomain.com:1234\n')) 3057db96d56Sopenharmony_ci 3067db96d56Sopenharmony_ci 3077db96d56Sopenharmony_ciclass ProxyTests_withOrderedEnv(unittest.TestCase): 3087db96d56Sopenharmony_ci 3097db96d56Sopenharmony_ci def setUp(self): 3107db96d56Sopenharmony_ci # We need to test conditions, where variable order _is_ significant 3117db96d56Sopenharmony_ci self._saved_env = os.environ 3127db96d56Sopenharmony_ci # Monkey patch os.environ, start with empty fake environment 3137db96d56Sopenharmony_ci os.environ = collections.OrderedDict() 3147db96d56Sopenharmony_ci 3157db96d56Sopenharmony_ci def tearDown(self): 3167db96d56Sopenharmony_ci os.environ = self._saved_env 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci def test_getproxies_environment_prefer_lowercase(self): 3197db96d56Sopenharmony_ci # Test lowercase preference with removal 3207db96d56Sopenharmony_ci os.environ['no_proxy'] = '' 3217db96d56Sopenharmony_ci os.environ['No_Proxy'] = 'localhost' 3227db96d56Sopenharmony_ci self.assertFalse(urllib.request.proxy_bypass_environment('localhost')) 3237db96d56Sopenharmony_ci self.assertFalse(urllib.request.proxy_bypass_environment('arbitrary')) 3247db96d56Sopenharmony_ci os.environ['http_proxy'] = '' 3257db96d56Sopenharmony_ci os.environ['HTTP_PROXY'] = 'http://somewhere:3128' 3267db96d56Sopenharmony_ci proxies = urllib.request.getproxies_environment() 3277db96d56Sopenharmony_ci self.assertEqual({}, proxies) 3287db96d56Sopenharmony_ci # Test lowercase preference of proxy bypass and correct matching including ports 3297db96d56Sopenharmony_ci os.environ['no_proxy'] = 'localhost, noproxy.com, my.proxy:1234' 3307db96d56Sopenharmony_ci os.environ['No_Proxy'] = 'xyz.com' 3317db96d56Sopenharmony_ci self.assertTrue(urllib.request.proxy_bypass_environment('localhost')) 3327db96d56Sopenharmony_ci self.assertTrue(urllib.request.proxy_bypass_environment('noproxy.com:5678')) 3337db96d56Sopenharmony_ci self.assertTrue(urllib.request.proxy_bypass_environment('my.proxy:1234')) 3347db96d56Sopenharmony_ci self.assertFalse(urllib.request.proxy_bypass_environment('my.proxy')) 3357db96d56Sopenharmony_ci self.assertFalse(urllib.request.proxy_bypass_environment('arbitrary')) 3367db96d56Sopenharmony_ci # Test lowercase preference with replacement 3377db96d56Sopenharmony_ci os.environ['http_proxy'] = 'http://somewhere:3128' 3387db96d56Sopenharmony_ci os.environ['Http_Proxy'] = 'http://somewhereelse:3128' 3397db96d56Sopenharmony_ci proxies = urllib.request.getproxies_environment() 3407db96d56Sopenharmony_ci self.assertEqual('http://somewhere:3128', proxies['http']) 3417db96d56Sopenharmony_ci 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ciclass urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin, FakeFTPMixin): 3447db96d56Sopenharmony_ci """Test urlopen() opening a fake http connection.""" 3457db96d56Sopenharmony_ci 3467db96d56Sopenharmony_ci def check_read(self, ver): 3477db96d56Sopenharmony_ci self.fakehttp(b"HTTP/" + ver + b" 200 OK\r\n\r\nHello!") 3487db96d56Sopenharmony_ci try: 3497db96d56Sopenharmony_ci fp = urlopen("http://python.org/") 3507db96d56Sopenharmony_ci self.assertEqual(fp.readline(), b"Hello!") 3517db96d56Sopenharmony_ci self.assertEqual(fp.readline(), b"") 3527db96d56Sopenharmony_ci self.assertEqual(fp.geturl(), 'http://python.org/') 3537db96d56Sopenharmony_ci self.assertEqual(fp.getcode(), 200) 3547db96d56Sopenharmony_ci finally: 3557db96d56Sopenharmony_ci self.unfakehttp() 3567db96d56Sopenharmony_ci 3577db96d56Sopenharmony_ci def test_url_fragment(self): 3587db96d56Sopenharmony_ci # Issue #11703: geturl() omits fragments in the original URL. 3597db96d56Sopenharmony_ci url = 'http://docs.python.org/library/urllib.html#OK' 3607db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!") 3617db96d56Sopenharmony_ci try: 3627db96d56Sopenharmony_ci fp = urllib.request.urlopen(url) 3637db96d56Sopenharmony_ci self.assertEqual(fp.geturl(), url) 3647db96d56Sopenharmony_ci finally: 3657db96d56Sopenharmony_ci self.unfakehttp() 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci def test_willclose(self): 3687db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!") 3697db96d56Sopenharmony_ci try: 3707db96d56Sopenharmony_ci resp = urlopen("http://www.python.org") 3717db96d56Sopenharmony_ci self.assertTrue(resp.fp.will_close) 3727db96d56Sopenharmony_ci finally: 3737db96d56Sopenharmony_ci self.unfakehttp() 3747db96d56Sopenharmony_ci 3757db96d56Sopenharmony_ci @unittest.skipUnless(ssl, "ssl module required") 3767db96d56Sopenharmony_ci def test_url_path_with_control_char_rejected(self): 3777db96d56Sopenharmony_ci for char_no in list(range(0, 0x21)) + [0x7f]: 3787db96d56Sopenharmony_ci char = chr(char_no) 3797db96d56Sopenharmony_ci schemeless_url = f"//localhost:7777/test{char}/" 3807db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") 3817db96d56Sopenharmony_ci try: 3827db96d56Sopenharmony_ci # We explicitly test urllib.request.urlopen() instead of the top 3837db96d56Sopenharmony_ci # level 'def urlopen()' function defined in this... (quite ugly) 3847db96d56Sopenharmony_ci # test suite. They use different url opening codepaths. Plain 3857db96d56Sopenharmony_ci # urlopen uses FancyURLOpener which goes via a codepath that 3867db96d56Sopenharmony_ci # calls urllib.parse.quote() on the URL which makes all of the 3877db96d56Sopenharmony_ci # above attempts at injection within the url _path_ safe. 3887db96d56Sopenharmony_ci escaped_char_repr = repr(char).replace('\\', r'\\') 3897db96d56Sopenharmony_ci InvalidURL = http.client.InvalidURL 3907db96d56Sopenharmony_ci with self.assertRaisesRegex( 3917db96d56Sopenharmony_ci InvalidURL, f"contain control.*{escaped_char_repr}"): 3927db96d56Sopenharmony_ci urllib.request.urlopen(f"http:{schemeless_url}") 3937db96d56Sopenharmony_ci with self.assertRaisesRegex( 3947db96d56Sopenharmony_ci InvalidURL, f"contain control.*{escaped_char_repr}"): 3957db96d56Sopenharmony_ci urllib.request.urlopen(f"https:{schemeless_url}") 3967db96d56Sopenharmony_ci # This code path quotes the URL so there is no injection. 3977db96d56Sopenharmony_ci resp = urlopen(f"http:{schemeless_url}") 3987db96d56Sopenharmony_ci self.assertNotIn(char, resp.geturl()) 3997db96d56Sopenharmony_ci finally: 4007db96d56Sopenharmony_ci self.unfakehttp() 4017db96d56Sopenharmony_ci 4027db96d56Sopenharmony_ci @unittest.skipUnless(ssl, "ssl module required") 4037db96d56Sopenharmony_ci def test_url_path_with_newline_header_injection_rejected(self): 4047db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") 4057db96d56Sopenharmony_ci host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123" 4067db96d56Sopenharmony_ci schemeless_url = "//" + host + ":8080/test/?test=a" 4077db96d56Sopenharmony_ci try: 4087db96d56Sopenharmony_ci # We explicitly test urllib.request.urlopen() instead of the top 4097db96d56Sopenharmony_ci # level 'def urlopen()' function defined in this... (quite ugly) 4107db96d56Sopenharmony_ci # test suite. They use different url opening codepaths. Plain 4117db96d56Sopenharmony_ci # urlopen uses FancyURLOpener which goes via a codepath that 4127db96d56Sopenharmony_ci # calls urllib.parse.quote() on the URL which makes all of the 4137db96d56Sopenharmony_ci # above attempts at injection within the url _path_ safe. 4147db96d56Sopenharmony_ci InvalidURL = http.client.InvalidURL 4157db96d56Sopenharmony_ci with self.assertRaisesRegex( 4167db96d56Sopenharmony_ci InvalidURL, r"contain control.*\\r.*(found at least . .)"): 4177db96d56Sopenharmony_ci urllib.request.urlopen(f"http:{schemeless_url}") 4187db96d56Sopenharmony_ci with self.assertRaisesRegex(InvalidURL, r"contain control.*\\n"): 4197db96d56Sopenharmony_ci urllib.request.urlopen(f"https:{schemeless_url}") 4207db96d56Sopenharmony_ci # This code path quotes the URL so there is no injection. 4217db96d56Sopenharmony_ci resp = urlopen(f"http:{schemeless_url}") 4227db96d56Sopenharmony_ci self.assertNotIn(' ', resp.geturl()) 4237db96d56Sopenharmony_ci self.assertNotIn('\r', resp.geturl()) 4247db96d56Sopenharmony_ci self.assertNotIn('\n', resp.geturl()) 4257db96d56Sopenharmony_ci finally: 4267db96d56Sopenharmony_ci self.unfakehttp() 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_ci @unittest.skipUnless(ssl, "ssl module required") 4297db96d56Sopenharmony_ci def test_url_host_with_control_char_rejected(self): 4307db96d56Sopenharmony_ci for char_no in list(range(0, 0x21)) + [0x7f]: 4317db96d56Sopenharmony_ci char = chr(char_no) 4327db96d56Sopenharmony_ci schemeless_url = f"//localhost{char}/test/" 4337db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") 4347db96d56Sopenharmony_ci try: 4357db96d56Sopenharmony_ci escaped_char_repr = repr(char).replace('\\', r'\\') 4367db96d56Sopenharmony_ci InvalidURL = http.client.InvalidURL 4377db96d56Sopenharmony_ci with self.assertRaisesRegex( 4387db96d56Sopenharmony_ci InvalidURL, f"contain control.*{escaped_char_repr}"): 4397db96d56Sopenharmony_ci urlopen(f"http:{schemeless_url}") 4407db96d56Sopenharmony_ci with self.assertRaisesRegex(InvalidURL, f"contain control.*{escaped_char_repr}"): 4417db96d56Sopenharmony_ci urlopen(f"https:{schemeless_url}") 4427db96d56Sopenharmony_ci finally: 4437db96d56Sopenharmony_ci self.unfakehttp() 4447db96d56Sopenharmony_ci 4457db96d56Sopenharmony_ci @unittest.skipUnless(ssl, "ssl module required") 4467db96d56Sopenharmony_ci def test_url_host_with_newline_header_injection_rejected(self): 4477db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") 4487db96d56Sopenharmony_ci host = "localhost\r\nX-injected: header\r\n" 4497db96d56Sopenharmony_ci schemeless_url = "//" + host + ":8080/test/?test=a" 4507db96d56Sopenharmony_ci try: 4517db96d56Sopenharmony_ci InvalidURL = http.client.InvalidURL 4527db96d56Sopenharmony_ci with self.assertRaisesRegex( 4537db96d56Sopenharmony_ci InvalidURL, r"contain control.*\\r"): 4547db96d56Sopenharmony_ci urlopen(f"http:{schemeless_url}") 4557db96d56Sopenharmony_ci with self.assertRaisesRegex(InvalidURL, r"contain control.*\\n"): 4567db96d56Sopenharmony_ci urlopen(f"https:{schemeless_url}") 4577db96d56Sopenharmony_ci finally: 4587db96d56Sopenharmony_ci self.unfakehttp() 4597db96d56Sopenharmony_ci 4607db96d56Sopenharmony_ci def test_read_0_9(self): 4617db96d56Sopenharmony_ci # "0.9" response accepted (but not "simple responses" without 4627db96d56Sopenharmony_ci # a status line) 4637db96d56Sopenharmony_ci self.check_read(b"0.9") 4647db96d56Sopenharmony_ci 4657db96d56Sopenharmony_ci def test_read_1_0(self): 4667db96d56Sopenharmony_ci self.check_read(b"1.0") 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci def test_read_1_1(self): 4697db96d56Sopenharmony_ci self.check_read(b"1.1") 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci def test_read_bogus(self): 4727db96d56Sopenharmony_ci # urlopen() should raise OSError for many error codes. 4737db96d56Sopenharmony_ci self.fakehttp(b'''HTTP/1.1 401 Authentication Required 4747db96d56Sopenharmony_ciDate: Wed, 02 Jan 2008 03:03:54 GMT 4757db96d56Sopenharmony_ciServer: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e 4767db96d56Sopenharmony_ciConnection: close 4777db96d56Sopenharmony_ciContent-Type: text/html; charset=iso-8859-1 4787db96d56Sopenharmony_ci''', mock_close=True) 4797db96d56Sopenharmony_ci try: 4807db96d56Sopenharmony_ci self.assertRaises(OSError, urlopen, "http://python.org/") 4817db96d56Sopenharmony_ci finally: 4827db96d56Sopenharmony_ci self.unfakehttp() 4837db96d56Sopenharmony_ci 4847db96d56Sopenharmony_ci def test_invalid_redirect(self): 4857db96d56Sopenharmony_ci # urlopen() should raise OSError for many error codes. 4867db96d56Sopenharmony_ci self.fakehttp(b'''HTTP/1.1 302 Found 4877db96d56Sopenharmony_ciDate: Wed, 02 Jan 2008 03:03:54 GMT 4887db96d56Sopenharmony_ciServer: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e 4897db96d56Sopenharmony_ciLocation: file://guidocomputer.athome.com:/python/license 4907db96d56Sopenharmony_ciConnection: close 4917db96d56Sopenharmony_ciContent-Type: text/html; charset=iso-8859-1 4927db96d56Sopenharmony_ci''', mock_close=True) 4937db96d56Sopenharmony_ci try: 4947db96d56Sopenharmony_ci msg = "Redirection to url 'file:" 4957db96d56Sopenharmony_ci with self.assertRaisesRegex(urllib.error.HTTPError, msg): 4967db96d56Sopenharmony_ci urlopen("http://python.org/") 4977db96d56Sopenharmony_ci finally: 4987db96d56Sopenharmony_ci self.unfakehttp() 4997db96d56Sopenharmony_ci 5007db96d56Sopenharmony_ci def test_redirect_limit_independent(self): 5017db96d56Sopenharmony_ci # Ticket #12923: make sure independent requests each use their 5027db96d56Sopenharmony_ci # own retry limit. 5037db96d56Sopenharmony_ci for i in range(FancyURLopener().maxtries): 5047db96d56Sopenharmony_ci self.fakehttp(b'''HTTP/1.1 302 Found 5057db96d56Sopenharmony_ciLocation: file://guidocomputer.athome.com:/python/license 5067db96d56Sopenharmony_ciConnection: close 5077db96d56Sopenharmony_ci''', mock_close=True) 5087db96d56Sopenharmony_ci try: 5097db96d56Sopenharmony_ci self.assertRaises(urllib.error.HTTPError, urlopen, 5107db96d56Sopenharmony_ci "http://something") 5117db96d56Sopenharmony_ci finally: 5127db96d56Sopenharmony_ci self.unfakehttp() 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ci def test_empty_socket(self): 5157db96d56Sopenharmony_ci # urlopen() raises OSError if the underlying socket does not send any 5167db96d56Sopenharmony_ci # data. (#1680230) 5177db96d56Sopenharmony_ci self.fakehttp(b'') 5187db96d56Sopenharmony_ci try: 5197db96d56Sopenharmony_ci self.assertRaises(OSError, urlopen, "http://something") 5207db96d56Sopenharmony_ci finally: 5217db96d56Sopenharmony_ci self.unfakehttp() 5227db96d56Sopenharmony_ci 5237db96d56Sopenharmony_ci def test_missing_localfile(self): 5247db96d56Sopenharmony_ci # Test for #10836 5257db96d56Sopenharmony_ci with self.assertRaises(urllib.error.URLError) as e: 5267db96d56Sopenharmony_ci urlopen('file://localhost/a/file/which/doesnot/exists.py') 5277db96d56Sopenharmony_ci self.assertTrue(e.exception.filename) 5287db96d56Sopenharmony_ci self.assertTrue(e.exception.reason) 5297db96d56Sopenharmony_ci 5307db96d56Sopenharmony_ci def test_file_notexists(self): 5317db96d56Sopenharmony_ci fd, tmp_file = tempfile.mkstemp() 5327db96d56Sopenharmony_ci tmp_fileurl = 'file://localhost/' + tmp_file.replace(os.path.sep, '/') 5337db96d56Sopenharmony_ci try: 5347db96d56Sopenharmony_ci self.assertTrue(os.path.exists(tmp_file)) 5357db96d56Sopenharmony_ci with urlopen(tmp_fileurl) as fobj: 5367db96d56Sopenharmony_ci self.assertTrue(fobj) 5377db96d56Sopenharmony_ci finally: 5387db96d56Sopenharmony_ci os.close(fd) 5397db96d56Sopenharmony_ci os.unlink(tmp_file) 5407db96d56Sopenharmony_ci self.assertFalse(os.path.exists(tmp_file)) 5417db96d56Sopenharmony_ci with self.assertRaises(urllib.error.URLError): 5427db96d56Sopenharmony_ci urlopen(tmp_fileurl) 5437db96d56Sopenharmony_ci 5447db96d56Sopenharmony_ci def test_ftp_nohost(self): 5457db96d56Sopenharmony_ci test_ftp_url = 'ftp:///path' 5467db96d56Sopenharmony_ci with self.assertRaises(urllib.error.URLError) as e: 5477db96d56Sopenharmony_ci urlopen(test_ftp_url) 5487db96d56Sopenharmony_ci self.assertFalse(e.exception.filename) 5497db96d56Sopenharmony_ci self.assertTrue(e.exception.reason) 5507db96d56Sopenharmony_ci 5517db96d56Sopenharmony_ci def test_ftp_nonexisting(self): 5527db96d56Sopenharmony_ci with self.assertRaises(urllib.error.URLError) as e: 5537db96d56Sopenharmony_ci urlopen('ftp://localhost/a/file/which/doesnot/exists.py') 5547db96d56Sopenharmony_ci self.assertFalse(e.exception.filename) 5557db96d56Sopenharmony_ci self.assertTrue(e.exception.reason) 5567db96d56Sopenharmony_ci 5577db96d56Sopenharmony_ci @patch.object(urllib.request, 'MAXFTPCACHE', 0) 5587db96d56Sopenharmony_ci def test_ftp_cache_pruning(self): 5597db96d56Sopenharmony_ci self.fakeftp() 5607db96d56Sopenharmony_ci try: 5617db96d56Sopenharmony_ci urllib.request.ftpcache['test'] = urllib.request.ftpwrapper('user', 'pass', 'localhost', 21, []) 5627db96d56Sopenharmony_ci urlopen('ftp://localhost') 5637db96d56Sopenharmony_ci finally: 5647db96d56Sopenharmony_ci self.unfakeftp() 5657db96d56Sopenharmony_ci 5667db96d56Sopenharmony_ci def test_userpass_inurl(self): 5677db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!") 5687db96d56Sopenharmony_ci try: 5697db96d56Sopenharmony_ci fp = urlopen("http://user:pass@python.org/") 5707db96d56Sopenharmony_ci self.assertEqual(fp.readline(), b"Hello!") 5717db96d56Sopenharmony_ci self.assertEqual(fp.readline(), b"") 5727db96d56Sopenharmony_ci self.assertEqual(fp.geturl(), 'http://user:pass@python.org/') 5737db96d56Sopenharmony_ci self.assertEqual(fp.getcode(), 200) 5747db96d56Sopenharmony_ci finally: 5757db96d56Sopenharmony_ci self.unfakehttp() 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci def test_userpass_inurl_w_spaces(self): 5787db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!") 5797db96d56Sopenharmony_ci try: 5807db96d56Sopenharmony_ci userpass = "a b:c d" 5817db96d56Sopenharmony_ci url = "http://{}@python.org/".format(userpass) 5827db96d56Sopenharmony_ci fakehttp_wrapper = http.client.HTTPConnection 5837db96d56Sopenharmony_ci authorization = ("Authorization: Basic %s\r\n" % 5847db96d56Sopenharmony_ci b64encode(userpass.encode("ASCII")).decode("ASCII")) 5857db96d56Sopenharmony_ci fp = urlopen(url) 5867db96d56Sopenharmony_ci # The authorization header must be in place 5877db96d56Sopenharmony_ci self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8")) 5887db96d56Sopenharmony_ci self.assertEqual(fp.readline(), b"Hello!") 5897db96d56Sopenharmony_ci self.assertEqual(fp.readline(), b"") 5907db96d56Sopenharmony_ci # the spaces are quoted in URL so no match 5917db96d56Sopenharmony_ci self.assertNotEqual(fp.geturl(), url) 5927db96d56Sopenharmony_ci self.assertEqual(fp.getcode(), 200) 5937db96d56Sopenharmony_ci finally: 5947db96d56Sopenharmony_ci self.unfakehttp() 5957db96d56Sopenharmony_ci 5967db96d56Sopenharmony_ci def test_URLopener_deprecation(self): 5977db96d56Sopenharmony_ci with warnings_helper.check_warnings(('',DeprecationWarning)): 5987db96d56Sopenharmony_ci urllib.request.URLopener() 5997db96d56Sopenharmony_ci 6007db96d56Sopenharmony_ci @unittest.skipUnless(ssl, "ssl module required") 6017db96d56Sopenharmony_ci def test_cafile_and_context(self): 6027db96d56Sopenharmony_ci context = ssl.create_default_context() 6037db96d56Sopenharmony_ci with warnings_helper.check_warnings(('', DeprecationWarning)): 6047db96d56Sopenharmony_ci with self.assertRaises(ValueError): 6057db96d56Sopenharmony_ci urllib.request.urlopen( 6067db96d56Sopenharmony_ci "https://localhost", cafile="/nonexistent/path", context=context 6077db96d56Sopenharmony_ci ) 6087db96d56Sopenharmony_ci 6097db96d56Sopenharmony_ci 6107db96d56Sopenharmony_ciclass urlopen_DataTests(unittest.TestCase): 6117db96d56Sopenharmony_ci """Test urlopen() opening a data URL.""" 6127db96d56Sopenharmony_ci 6137db96d56Sopenharmony_ci def setUp(self): 6147db96d56Sopenharmony_ci # clear _opener global variable 6157db96d56Sopenharmony_ci self.addCleanup(urllib.request.urlcleanup) 6167db96d56Sopenharmony_ci 6177db96d56Sopenharmony_ci # text containing URL special- and unicode-characters 6187db96d56Sopenharmony_ci self.text = "test data URLs :;,%=& \u00f6 \u00c4 " 6197db96d56Sopenharmony_ci # 2x1 pixel RGB PNG image with one black and one white pixel 6207db96d56Sopenharmony_ci self.image = ( 6217db96d56Sopenharmony_ci b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x02\x00\x00\x00' 6227db96d56Sopenharmony_ci b'\x01\x08\x02\x00\x00\x00{@\xe8\xdd\x00\x00\x00\x01sRGB\x00\xae' 6237db96d56Sopenharmony_ci b'\xce\x1c\xe9\x00\x00\x00\x0fIDAT\x08\xd7c```\xf8\xff\xff?\x00' 6247db96d56Sopenharmony_ci b'\x06\x01\x02\xfe\no/\x1e\x00\x00\x00\x00IEND\xaeB`\x82') 6257db96d56Sopenharmony_ci 6267db96d56Sopenharmony_ci self.text_url = ( 6277db96d56Sopenharmony_ci "data:text/plain;charset=UTF-8,test%20data%20URLs%20%3A%3B%2C%25%3" 6287db96d56Sopenharmony_ci "D%26%20%C3%B6%20%C3%84%20") 6297db96d56Sopenharmony_ci self.text_url_base64 = ( 6307db96d56Sopenharmony_ci "data:text/plain;charset=ISO-8859-1;base64,dGVzdCBkYXRhIFVSTHMgOjs" 6317db96d56Sopenharmony_ci "sJT0mIPYgxCA%3D") 6327db96d56Sopenharmony_ci # base64 encoded data URL that contains ignorable spaces, 6337db96d56Sopenharmony_ci # such as "\n", " ", "%0A", and "%20". 6347db96d56Sopenharmony_ci self.image_url = ( 6357db96d56Sopenharmony_ci "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAIAAAB7\n" 6367db96d56Sopenharmony_ci "QOjdAAAAAXNSR0IArs4c6QAAAA9JREFUCNdj%0AYGBg%2BP//PwAGAQL%2BCm8 " 6377db96d56Sopenharmony_ci "vHgAAAABJRU5ErkJggg%3D%3D%0A%20") 6387db96d56Sopenharmony_ci 6397db96d56Sopenharmony_ci self.text_url_resp = urllib.request.urlopen(self.text_url) 6407db96d56Sopenharmony_ci self.text_url_base64_resp = urllib.request.urlopen( 6417db96d56Sopenharmony_ci self.text_url_base64) 6427db96d56Sopenharmony_ci self.image_url_resp = urllib.request.urlopen(self.image_url) 6437db96d56Sopenharmony_ci 6447db96d56Sopenharmony_ci def test_interface(self): 6457db96d56Sopenharmony_ci # Make sure object returned by urlopen() has the specified methods 6467db96d56Sopenharmony_ci for attr in ("read", "readline", "readlines", 6477db96d56Sopenharmony_ci "close", "info", "geturl", "getcode", "__iter__"): 6487db96d56Sopenharmony_ci self.assertTrue(hasattr(self.text_url_resp, attr), 6497db96d56Sopenharmony_ci "object returned by urlopen() lacks %s attribute" % 6507db96d56Sopenharmony_ci attr) 6517db96d56Sopenharmony_ci 6527db96d56Sopenharmony_ci def test_info(self): 6537db96d56Sopenharmony_ci self.assertIsInstance(self.text_url_resp.info(), email.message.Message) 6547db96d56Sopenharmony_ci self.assertEqual(self.text_url_base64_resp.info().get_params(), 6557db96d56Sopenharmony_ci [('text/plain', ''), ('charset', 'ISO-8859-1')]) 6567db96d56Sopenharmony_ci self.assertEqual(self.image_url_resp.info()['content-length'], 6577db96d56Sopenharmony_ci str(len(self.image))) 6587db96d56Sopenharmony_ci self.assertEqual(urllib.request.urlopen("data:,").info().get_params(), 6597db96d56Sopenharmony_ci [('text/plain', ''), ('charset', 'US-ASCII')]) 6607db96d56Sopenharmony_ci 6617db96d56Sopenharmony_ci def test_geturl(self): 6627db96d56Sopenharmony_ci self.assertEqual(self.text_url_resp.geturl(), self.text_url) 6637db96d56Sopenharmony_ci self.assertEqual(self.text_url_base64_resp.geturl(), 6647db96d56Sopenharmony_ci self.text_url_base64) 6657db96d56Sopenharmony_ci self.assertEqual(self.image_url_resp.geturl(), self.image_url) 6667db96d56Sopenharmony_ci 6677db96d56Sopenharmony_ci def test_read_text(self): 6687db96d56Sopenharmony_ci self.assertEqual(self.text_url_resp.read().decode( 6697db96d56Sopenharmony_ci dict(self.text_url_resp.info().get_params())['charset']), self.text) 6707db96d56Sopenharmony_ci 6717db96d56Sopenharmony_ci def test_read_text_base64(self): 6727db96d56Sopenharmony_ci self.assertEqual(self.text_url_base64_resp.read().decode( 6737db96d56Sopenharmony_ci dict(self.text_url_base64_resp.info().get_params())['charset']), 6747db96d56Sopenharmony_ci self.text) 6757db96d56Sopenharmony_ci 6767db96d56Sopenharmony_ci def test_read_image(self): 6777db96d56Sopenharmony_ci self.assertEqual(self.image_url_resp.read(), self.image) 6787db96d56Sopenharmony_ci 6797db96d56Sopenharmony_ci def test_missing_comma(self): 6807db96d56Sopenharmony_ci self.assertRaises(ValueError,urllib.request.urlopen,'data:text/plain') 6817db96d56Sopenharmony_ci 6827db96d56Sopenharmony_ci def test_invalid_base64_data(self): 6837db96d56Sopenharmony_ci # missing padding character 6847db96d56Sopenharmony_ci self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') 6857db96d56Sopenharmony_ci 6867db96d56Sopenharmony_ci 6877db96d56Sopenharmony_ciclass urlretrieve_FileTests(unittest.TestCase): 6887db96d56Sopenharmony_ci """Test urllib.urlretrieve() on local files""" 6897db96d56Sopenharmony_ci 6907db96d56Sopenharmony_ci def setUp(self): 6917db96d56Sopenharmony_ci # clear _opener global variable 6927db96d56Sopenharmony_ci self.addCleanup(urllib.request.urlcleanup) 6937db96d56Sopenharmony_ci 6947db96d56Sopenharmony_ci # Create a list of temporary files. Each item in the list is a file 6957db96d56Sopenharmony_ci # name (absolute path or relative to the current working directory). 6967db96d56Sopenharmony_ci # All files in this list will be deleted in the tearDown method. Note, 6977db96d56Sopenharmony_ci # this only helps to makes sure temporary files get deleted, but it 6987db96d56Sopenharmony_ci # does nothing about trying to close files that may still be open. It 6997db96d56Sopenharmony_ci # is the responsibility of the developer to properly close files even 7007db96d56Sopenharmony_ci # when exceptional conditions occur. 7017db96d56Sopenharmony_ci self.tempFiles = [] 7027db96d56Sopenharmony_ci 7037db96d56Sopenharmony_ci # Create a temporary file. 7047db96d56Sopenharmony_ci self.registerFileForCleanUp(os_helper.TESTFN) 7057db96d56Sopenharmony_ci self.text = b'testing urllib.urlretrieve' 7067db96d56Sopenharmony_ci try: 7077db96d56Sopenharmony_ci FILE = open(os_helper.TESTFN, 'wb') 7087db96d56Sopenharmony_ci FILE.write(self.text) 7097db96d56Sopenharmony_ci FILE.close() 7107db96d56Sopenharmony_ci finally: 7117db96d56Sopenharmony_ci try: FILE.close() 7127db96d56Sopenharmony_ci except: pass 7137db96d56Sopenharmony_ci 7147db96d56Sopenharmony_ci def tearDown(self): 7157db96d56Sopenharmony_ci # Delete the temporary files. 7167db96d56Sopenharmony_ci for each in self.tempFiles: 7177db96d56Sopenharmony_ci try: os.remove(each) 7187db96d56Sopenharmony_ci except: pass 7197db96d56Sopenharmony_ci 7207db96d56Sopenharmony_ci def constructLocalFileUrl(self, filePath): 7217db96d56Sopenharmony_ci filePath = os.path.abspath(filePath) 7227db96d56Sopenharmony_ci try: 7237db96d56Sopenharmony_ci filePath.encode("utf-8") 7247db96d56Sopenharmony_ci except UnicodeEncodeError: 7257db96d56Sopenharmony_ci raise unittest.SkipTest("filePath is not encodable to utf8") 7267db96d56Sopenharmony_ci return "file://%s" % urllib.request.pathname2url(filePath) 7277db96d56Sopenharmony_ci 7287db96d56Sopenharmony_ci def createNewTempFile(self, data=b""): 7297db96d56Sopenharmony_ci """Creates a new temporary file containing the specified data, 7307db96d56Sopenharmony_ci registers the file for deletion during the test fixture tear down, and 7317db96d56Sopenharmony_ci returns the absolute path of the file.""" 7327db96d56Sopenharmony_ci 7337db96d56Sopenharmony_ci newFd, newFilePath = tempfile.mkstemp() 7347db96d56Sopenharmony_ci try: 7357db96d56Sopenharmony_ci self.registerFileForCleanUp(newFilePath) 7367db96d56Sopenharmony_ci newFile = os.fdopen(newFd, "wb") 7377db96d56Sopenharmony_ci newFile.write(data) 7387db96d56Sopenharmony_ci newFile.close() 7397db96d56Sopenharmony_ci finally: 7407db96d56Sopenharmony_ci try: newFile.close() 7417db96d56Sopenharmony_ci except: pass 7427db96d56Sopenharmony_ci return newFilePath 7437db96d56Sopenharmony_ci 7447db96d56Sopenharmony_ci def registerFileForCleanUp(self, fileName): 7457db96d56Sopenharmony_ci self.tempFiles.append(fileName) 7467db96d56Sopenharmony_ci 7477db96d56Sopenharmony_ci def test_basic(self): 7487db96d56Sopenharmony_ci # Make sure that a local file just gets its own location returned and 7497db96d56Sopenharmony_ci # a headers value is returned. 7507db96d56Sopenharmony_ci result = urllib.request.urlretrieve("file:%s" % os_helper.TESTFN) 7517db96d56Sopenharmony_ci self.assertEqual(result[0], os_helper.TESTFN) 7527db96d56Sopenharmony_ci self.assertIsInstance(result[1], email.message.Message, 7537db96d56Sopenharmony_ci "did not get an email.message.Message instance " 7547db96d56Sopenharmony_ci "as second returned value") 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_ci def test_copy(self): 7577db96d56Sopenharmony_ci # Test that setting the filename argument works. 7587db96d56Sopenharmony_ci second_temp = "%s.2" % os_helper.TESTFN 7597db96d56Sopenharmony_ci self.registerFileForCleanUp(second_temp) 7607db96d56Sopenharmony_ci result = urllib.request.urlretrieve(self.constructLocalFileUrl( 7617db96d56Sopenharmony_ci os_helper.TESTFN), second_temp) 7627db96d56Sopenharmony_ci self.assertEqual(second_temp, result[0]) 7637db96d56Sopenharmony_ci self.assertTrue(os.path.exists(second_temp), "copy of the file was not " 7647db96d56Sopenharmony_ci "made") 7657db96d56Sopenharmony_ci FILE = open(second_temp, 'rb') 7667db96d56Sopenharmony_ci try: 7677db96d56Sopenharmony_ci text = FILE.read() 7687db96d56Sopenharmony_ci FILE.close() 7697db96d56Sopenharmony_ci finally: 7707db96d56Sopenharmony_ci try: FILE.close() 7717db96d56Sopenharmony_ci except: pass 7727db96d56Sopenharmony_ci self.assertEqual(self.text, text) 7737db96d56Sopenharmony_ci 7747db96d56Sopenharmony_ci def test_reporthook(self): 7757db96d56Sopenharmony_ci # Make sure that the reporthook works. 7767db96d56Sopenharmony_ci def hooktester(block_count, block_read_size, file_size, count_holder=[0]): 7777db96d56Sopenharmony_ci self.assertIsInstance(block_count, int) 7787db96d56Sopenharmony_ci self.assertIsInstance(block_read_size, int) 7797db96d56Sopenharmony_ci self.assertIsInstance(file_size, int) 7807db96d56Sopenharmony_ci self.assertEqual(block_count, count_holder[0]) 7817db96d56Sopenharmony_ci count_holder[0] = count_holder[0] + 1 7827db96d56Sopenharmony_ci second_temp = "%s.2" % os_helper.TESTFN 7837db96d56Sopenharmony_ci self.registerFileForCleanUp(second_temp) 7847db96d56Sopenharmony_ci urllib.request.urlretrieve( 7857db96d56Sopenharmony_ci self.constructLocalFileUrl(os_helper.TESTFN), 7867db96d56Sopenharmony_ci second_temp, hooktester) 7877db96d56Sopenharmony_ci 7887db96d56Sopenharmony_ci def test_reporthook_0_bytes(self): 7897db96d56Sopenharmony_ci # Test on zero length file. Should call reporthook only 1 time. 7907db96d56Sopenharmony_ci report = [] 7917db96d56Sopenharmony_ci def hooktester(block_count, block_read_size, file_size, _report=report): 7927db96d56Sopenharmony_ci _report.append((block_count, block_read_size, file_size)) 7937db96d56Sopenharmony_ci srcFileName = self.createNewTempFile() 7947db96d56Sopenharmony_ci urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName), 7957db96d56Sopenharmony_ci os_helper.TESTFN, hooktester) 7967db96d56Sopenharmony_ci self.assertEqual(len(report), 1) 7977db96d56Sopenharmony_ci self.assertEqual(report[0][2], 0) 7987db96d56Sopenharmony_ci 7997db96d56Sopenharmony_ci def test_reporthook_5_bytes(self): 8007db96d56Sopenharmony_ci # Test on 5 byte file. Should call reporthook only 2 times (once when 8017db96d56Sopenharmony_ci # the "network connection" is established and once when the block is 8027db96d56Sopenharmony_ci # read). 8037db96d56Sopenharmony_ci report = [] 8047db96d56Sopenharmony_ci def hooktester(block_count, block_read_size, file_size, _report=report): 8057db96d56Sopenharmony_ci _report.append((block_count, block_read_size, file_size)) 8067db96d56Sopenharmony_ci srcFileName = self.createNewTempFile(b"x" * 5) 8077db96d56Sopenharmony_ci urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName), 8087db96d56Sopenharmony_ci os_helper.TESTFN, hooktester) 8097db96d56Sopenharmony_ci self.assertEqual(len(report), 2) 8107db96d56Sopenharmony_ci self.assertEqual(report[0][2], 5) 8117db96d56Sopenharmony_ci self.assertEqual(report[1][2], 5) 8127db96d56Sopenharmony_ci 8137db96d56Sopenharmony_ci def test_reporthook_8193_bytes(self): 8147db96d56Sopenharmony_ci # Test on 8193 byte file. Should call reporthook only 3 times (once 8157db96d56Sopenharmony_ci # when the "network connection" is established, once for the next 8192 8167db96d56Sopenharmony_ci # bytes, and once for the last byte). 8177db96d56Sopenharmony_ci report = [] 8187db96d56Sopenharmony_ci def hooktester(block_count, block_read_size, file_size, _report=report): 8197db96d56Sopenharmony_ci _report.append((block_count, block_read_size, file_size)) 8207db96d56Sopenharmony_ci srcFileName = self.createNewTempFile(b"x" * 8193) 8217db96d56Sopenharmony_ci urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName), 8227db96d56Sopenharmony_ci os_helper.TESTFN, hooktester) 8237db96d56Sopenharmony_ci self.assertEqual(len(report), 3) 8247db96d56Sopenharmony_ci self.assertEqual(report[0][2], 8193) 8257db96d56Sopenharmony_ci self.assertEqual(report[0][1], 8192) 8267db96d56Sopenharmony_ci self.assertEqual(report[1][1], 8192) 8277db96d56Sopenharmony_ci self.assertEqual(report[2][1], 8192) 8287db96d56Sopenharmony_ci 8297db96d56Sopenharmony_ci 8307db96d56Sopenharmony_ciclass urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin): 8317db96d56Sopenharmony_ci """Test urllib.urlretrieve() using fake http connections""" 8327db96d56Sopenharmony_ci 8337db96d56Sopenharmony_ci def test_short_content_raises_ContentTooShortError(self): 8347db96d56Sopenharmony_ci self.addCleanup(urllib.request.urlcleanup) 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci self.fakehttp(b'''HTTP/1.1 200 OK 8377db96d56Sopenharmony_ciDate: Wed, 02 Jan 2008 03:03:54 GMT 8387db96d56Sopenharmony_ciServer: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e 8397db96d56Sopenharmony_ciConnection: close 8407db96d56Sopenharmony_ciContent-Length: 100 8417db96d56Sopenharmony_ciContent-Type: text/html; charset=iso-8859-1 8427db96d56Sopenharmony_ci 8437db96d56Sopenharmony_ciFF 8447db96d56Sopenharmony_ci''') 8457db96d56Sopenharmony_ci 8467db96d56Sopenharmony_ci def _reporthook(par1, par2, par3): 8477db96d56Sopenharmony_ci pass 8487db96d56Sopenharmony_ci 8497db96d56Sopenharmony_ci with self.assertRaises(urllib.error.ContentTooShortError): 8507db96d56Sopenharmony_ci try: 8517db96d56Sopenharmony_ci urllib.request.urlretrieve(support.TEST_HTTP_URL, 8527db96d56Sopenharmony_ci reporthook=_reporthook) 8537db96d56Sopenharmony_ci finally: 8547db96d56Sopenharmony_ci self.unfakehttp() 8557db96d56Sopenharmony_ci 8567db96d56Sopenharmony_ci def test_short_content_raises_ContentTooShortError_without_reporthook(self): 8577db96d56Sopenharmony_ci self.addCleanup(urllib.request.urlcleanup) 8587db96d56Sopenharmony_ci 8597db96d56Sopenharmony_ci self.fakehttp(b'''HTTP/1.1 200 OK 8607db96d56Sopenharmony_ciDate: Wed, 02 Jan 2008 03:03:54 GMT 8617db96d56Sopenharmony_ciServer: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e 8627db96d56Sopenharmony_ciConnection: close 8637db96d56Sopenharmony_ciContent-Length: 100 8647db96d56Sopenharmony_ciContent-Type: text/html; charset=iso-8859-1 8657db96d56Sopenharmony_ci 8667db96d56Sopenharmony_ciFF 8677db96d56Sopenharmony_ci''') 8687db96d56Sopenharmony_ci with self.assertRaises(urllib.error.ContentTooShortError): 8697db96d56Sopenharmony_ci try: 8707db96d56Sopenharmony_ci urllib.request.urlretrieve(support.TEST_HTTP_URL) 8717db96d56Sopenharmony_ci finally: 8727db96d56Sopenharmony_ci self.unfakehttp() 8737db96d56Sopenharmony_ci 8747db96d56Sopenharmony_ci 8757db96d56Sopenharmony_ciclass QuotingTests(unittest.TestCase): 8767db96d56Sopenharmony_ci r"""Tests for urllib.quote() and urllib.quote_plus() 8777db96d56Sopenharmony_ci 8787db96d56Sopenharmony_ci According to RFC 3986 (Uniform Resource Identifiers), to escape a 8797db96d56Sopenharmony_ci character you write it as '%' + <2 character US-ASCII hex value>. 8807db96d56Sopenharmony_ci The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a 8817db96d56Sopenharmony_ci character properly. Case does not matter on the hex letters. 8827db96d56Sopenharmony_ci 8837db96d56Sopenharmony_ci The various character sets specified are: 8847db96d56Sopenharmony_ci 8857db96d56Sopenharmony_ci Reserved characters : ";/?:@&=+$," 8867db96d56Sopenharmony_ci Have special meaning in URIs and must be escaped if not being used for 8877db96d56Sopenharmony_ci their special meaning 8887db96d56Sopenharmony_ci Data characters : letters, digits, and "-_.!~*'()" 8897db96d56Sopenharmony_ci Unreserved and do not need to be escaped; can be, though, if desired 8907db96d56Sopenharmony_ci Control characters : 0x00 - 0x1F, 0x7F 8917db96d56Sopenharmony_ci Have no use in URIs so must be escaped 8927db96d56Sopenharmony_ci space : 0x20 8937db96d56Sopenharmony_ci Must be escaped 8947db96d56Sopenharmony_ci Delimiters : '<>#%"' 8957db96d56Sopenharmony_ci Must be escaped 8967db96d56Sopenharmony_ci Unwise : "{}|\^[]`" 8977db96d56Sopenharmony_ci Must be escaped 8987db96d56Sopenharmony_ci 8997db96d56Sopenharmony_ci """ 9007db96d56Sopenharmony_ci 9017db96d56Sopenharmony_ci def test_never_quote(self): 9027db96d56Sopenharmony_ci # Make sure quote() does not quote letters, digits, and "_,.-" 9037db96d56Sopenharmony_ci do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ", 9047db96d56Sopenharmony_ci "abcdefghijklmnopqrstuvwxyz", 9057db96d56Sopenharmony_ci "0123456789", 9067db96d56Sopenharmony_ci "_.-~"]) 9077db96d56Sopenharmony_ci result = urllib.parse.quote(do_not_quote) 9087db96d56Sopenharmony_ci self.assertEqual(do_not_quote, result, 9097db96d56Sopenharmony_ci "using quote(): %r != %r" % (do_not_quote, result)) 9107db96d56Sopenharmony_ci result = urllib.parse.quote_plus(do_not_quote) 9117db96d56Sopenharmony_ci self.assertEqual(do_not_quote, result, 9127db96d56Sopenharmony_ci "using quote_plus(): %r != %r" % (do_not_quote, result)) 9137db96d56Sopenharmony_ci 9147db96d56Sopenharmony_ci def test_default_safe(self): 9157db96d56Sopenharmony_ci # Test '/' is default value for 'safe' parameter 9167db96d56Sopenharmony_ci self.assertEqual(urllib.parse.quote.__defaults__[0], '/') 9177db96d56Sopenharmony_ci 9187db96d56Sopenharmony_ci def test_safe(self): 9197db96d56Sopenharmony_ci # Test setting 'safe' parameter does what it should do 9207db96d56Sopenharmony_ci quote_by_default = "<>" 9217db96d56Sopenharmony_ci result = urllib.parse.quote(quote_by_default, safe=quote_by_default) 9227db96d56Sopenharmony_ci self.assertEqual(quote_by_default, result, 9237db96d56Sopenharmony_ci "using quote(): %r != %r" % (quote_by_default, result)) 9247db96d56Sopenharmony_ci result = urllib.parse.quote_plus(quote_by_default, 9257db96d56Sopenharmony_ci safe=quote_by_default) 9267db96d56Sopenharmony_ci self.assertEqual(quote_by_default, result, 9277db96d56Sopenharmony_ci "using quote_plus(): %r != %r" % 9287db96d56Sopenharmony_ci (quote_by_default, result)) 9297db96d56Sopenharmony_ci # Safe expressed as bytes rather than str 9307db96d56Sopenharmony_ci result = urllib.parse.quote(quote_by_default, safe=b"<>") 9317db96d56Sopenharmony_ci self.assertEqual(quote_by_default, result, 9327db96d56Sopenharmony_ci "using quote(): %r != %r" % (quote_by_default, result)) 9337db96d56Sopenharmony_ci # "Safe" non-ASCII characters should have no effect 9347db96d56Sopenharmony_ci # (Since URIs are not allowed to have non-ASCII characters) 9357db96d56Sopenharmony_ci result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="\xfc") 9367db96d56Sopenharmony_ci expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="") 9377db96d56Sopenharmony_ci self.assertEqual(expect, result, 9387db96d56Sopenharmony_ci "using quote(): %r != %r" % 9397db96d56Sopenharmony_ci (expect, result)) 9407db96d56Sopenharmony_ci # Same as above, but using a bytes rather than str 9417db96d56Sopenharmony_ci result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe=b"\xfc") 9427db96d56Sopenharmony_ci expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="") 9437db96d56Sopenharmony_ci self.assertEqual(expect, result, 9447db96d56Sopenharmony_ci "using quote(): %r != %r" % 9457db96d56Sopenharmony_ci (expect, result)) 9467db96d56Sopenharmony_ci 9477db96d56Sopenharmony_ci def test_default_quoting(self): 9487db96d56Sopenharmony_ci # Make sure all characters that should be quoted are by default sans 9497db96d56Sopenharmony_ci # space (separate test for that). 9507db96d56Sopenharmony_ci should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F 9517db96d56Sopenharmony_ci should_quote.append(r'<>#%"{}|\^[]`') 9527db96d56Sopenharmony_ci should_quote.append(chr(127)) # For 0x7F 9537db96d56Sopenharmony_ci should_quote = ''.join(should_quote) 9547db96d56Sopenharmony_ci for char in should_quote: 9557db96d56Sopenharmony_ci result = urllib.parse.quote(char) 9567db96d56Sopenharmony_ci self.assertEqual(hexescape(char), result, 9577db96d56Sopenharmony_ci "using quote(): " 9587db96d56Sopenharmony_ci "%s should be escaped to %s, not %s" % 9597db96d56Sopenharmony_ci (char, hexescape(char), result)) 9607db96d56Sopenharmony_ci result = urllib.parse.quote_plus(char) 9617db96d56Sopenharmony_ci self.assertEqual(hexescape(char), result, 9627db96d56Sopenharmony_ci "using quote_plus(): " 9637db96d56Sopenharmony_ci "%s should be escapes to %s, not %s" % 9647db96d56Sopenharmony_ci (char, hexescape(char), result)) 9657db96d56Sopenharmony_ci del should_quote 9667db96d56Sopenharmony_ci partial_quote = "ab[]cd" 9677db96d56Sopenharmony_ci expected = "ab%5B%5Dcd" 9687db96d56Sopenharmony_ci result = urllib.parse.quote(partial_quote) 9697db96d56Sopenharmony_ci self.assertEqual(expected, result, 9707db96d56Sopenharmony_ci "using quote(): %r != %r" % (expected, result)) 9717db96d56Sopenharmony_ci result = urllib.parse.quote_plus(partial_quote) 9727db96d56Sopenharmony_ci self.assertEqual(expected, result, 9737db96d56Sopenharmony_ci "using quote_plus(): %r != %r" % (expected, result)) 9747db96d56Sopenharmony_ci 9757db96d56Sopenharmony_ci def test_quoting_space(self): 9767db96d56Sopenharmony_ci # Make sure quote() and quote_plus() handle spaces as specified in 9777db96d56Sopenharmony_ci # their unique way 9787db96d56Sopenharmony_ci result = urllib.parse.quote(' ') 9797db96d56Sopenharmony_ci self.assertEqual(result, hexescape(' '), 9807db96d56Sopenharmony_ci "using quote(): %r != %r" % (result, hexescape(' '))) 9817db96d56Sopenharmony_ci result = urllib.parse.quote_plus(' ') 9827db96d56Sopenharmony_ci self.assertEqual(result, '+', 9837db96d56Sopenharmony_ci "using quote_plus(): %r != +" % result) 9847db96d56Sopenharmony_ci given = "a b cd e f" 9857db96d56Sopenharmony_ci expect = given.replace(' ', hexescape(' ')) 9867db96d56Sopenharmony_ci result = urllib.parse.quote(given) 9877db96d56Sopenharmony_ci self.assertEqual(expect, result, 9887db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 9897db96d56Sopenharmony_ci expect = given.replace(' ', '+') 9907db96d56Sopenharmony_ci result = urllib.parse.quote_plus(given) 9917db96d56Sopenharmony_ci self.assertEqual(expect, result, 9927db96d56Sopenharmony_ci "using quote_plus(): %r != %r" % (expect, result)) 9937db96d56Sopenharmony_ci 9947db96d56Sopenharmony_ci def test_quoting_plus(self): 9957db96d56Sopenharmony_ci self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma'), 9967db96d56Sopenharmony_ci 'alpha%2Bbeta+gamma') 9977db96d56Sopenharmony_ci self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', '+'), 9987db96d56Sopenharmony_ci 'alpha+beta+gamma') 9997db96d56Sopenharmony_ci # Test with bytes 10007db96d56Sopenharmony_ci self.assertEqual(urllib.parse.quote_plus(b'alpha+beta gamma'), 10017db96d56Sopenharmony_ci 'alpha%2Bbeta+gamma') 10027db96d56Sopenharmony_ci # Test with safe bytes 10037db96d56Sopenharmony_ci self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', b'+'), 10047db96d56Sopenharmony_ci 'alpha+beta+gamma') 10057db96d56Sopenharmony_ci 10067db96d56Sopenharmony_ci def test_quote_bytes(self): 10077db96d56Sopenharmony_ci # Bytes should quote directly to percent-encoded values 10087db96d56Sopenharmony_ci given = b"\xa2\xd8ab\xff" 10097db96d56Sopenharmony_ci expect = "%A2%D8ab%FF" 10107db96d56Sopenharmony_ci result = urllib.parse.quote(given) 10117db96d56Sopenharmony_ci self.assertEqual(expect, result, 10127db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 10137db96d56Sopenharmony_ci # Encoding argument should raise type error on bytes input 10147db96d56Sopenharmony_ci self.assertRaises(TypeError, urllib.parse.quote, given, 10157db96d56Sopenharmony_ci encoding="latin-1") 10167db96d56Sopenharmony_ci # quote_from_bytes should work the same 10177db96d56Sopenharmony_ci result = urllib.parse.quote_from_bytes(given) 10187db96d56Sopenharmony_ci self.assertEqual(expect, result, 10197db96d56Sopenharmony_ci "using quote_from_bytes(): %r != %r" 10207db96d56Sopenharmony_ci % (expect, result)) 10217db96d56Sopenharmony_ci 10227db96d56Sopenharmony_ci def test_quote_with_unicode(self): 10237db96d56Sopenharmony_ci # Characters in Latin-1 range, encoded by default in UTF-8 10247db96d56Sopenharmony_ci given = "\xa2\xd8ab\xff" 10257db96d56Sopenharmony_ci expect = "%C2%A2%C3%98ab%C3%BF" 10267db96d56Sopenharmony_ci result = urllib.parse.quote(given) 10277db96d56Sopenharmony_ci self.assertEqual(expect, result, 10287db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 10297db96d56Sopenharmony_ci # Characters in Latin-1 range, encoded by with None (default) 10307db96d56Sopenharmony_ci result = urllib.parse.quote(given, encoding=None, errors=None) 10317db96d56Sopenharmony_ci self.assertEqual(expect, result, 10327db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 10337db96d56Sopenharmony_ci # Characters in Latin-1 range, encoded with Latin-1 10347db96d56Sopenharmony_ci given = "\xa2\xd8ab\xff" 10357db96d56Sopenharmony_ci expect = "%A2%D8ab%FF" 10367db96d56Sopenharmony_ci result = urllib.parse.quote(given, encoding="latin-1") 10377db96d56Sopenharmony_ci self.assertEqual(expect, result, 10387db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 10397db96d56Sopenharmony_ci # Characters in BMP, encoded by default in UTF-8 10407db96d56Sopenharmony_ci given = "\u6f22\u5b57" # "Kanji" 10417db96d56Sopenharmony_ci expect = "%E6%BC%A2%E5%AD%97" 10427db96d56Sopenharmony_ci result = urllib.parse.quote(given) 10437db96d56Sopenharmony_ci self.assertEqual(expect, result, 10447db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 10457db96d56Sopenharmony_ci # Characters in BMP, encoded with Latin-1 10467db96d56Sopenharmony_ci given = "\u6f22\u5b57" 10477db96d56Sopenharmony_ci self.assertRaises(UnicodeEncodeError, urllib.parse.quote, given, 10487db96d56Sopenharmony_ci encoding="latin-1") 10497db96d56Sopenharmony_ci # Characters in BMP, encoded with Latin-1, with replace error handling 10507db96d56Sopenharmony_ci given = "\u6f22\u5b57" 10517db96d56Sopenharmony_ci expect = "%3F%3F" # "??" 10527db96d56Sopenharmony_ci result = urllib.parse.quote(given, encoding="latin-1", 10537db96d56Sopenharmony_ci errors="replace") 10547db96d56Sopenharmony_ci self.assertEqual(expect, result, 10557db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 10567db96d56Sopenharmony_ci # Characters in BMP, Latin-1, with xmlcharref error handling 10577db96d56Sopenharmony_ci given = "\u6f22\u5b57" 10587db96d56Sopenharmony_ci expect = "%26%2328450%3B%26%2323383%3B" # "漢字" 10597db96d56Sopenharmony_ci result = urllib.parse.quote(given, encoding="latin-1", 10607db96d56Sopenharmony_ci errors="xmlcharrefreplace") 10617db96d56Sopenharmony_ci self.assertEqual(expect, result, 10627db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 10637db96d56Sopenharmony_ci 10647db96d56Sopenharmony_ci def test_quote_plus_with_unicode(self): 10657db96d56Sopenharmony_ci # Encoding (latin-1) test for quote_plus 10667db96d56Sopenharmony_ci given = "\xa2\xd8 \xff" 10677db96d56Sopenharmony_ci expect = "%A2%D8+%FF" 10687db96d56Sopenharmony_ci result = urllib.parse.quote_plus(given, encoding="latin-1") 10697db96d56Sopenharmony_ci self.assertEqual(expect, result, 10707db96d56Sopenharmony_ci "using quote_plus(): %r != %r" % (expect, result)) 10717db96d56Sopenharmony_ci # Errors test for quote_plus 10727db96d56Sopenharmony_ci given = "ab\u6f22\u5b57 cd" 10737db96d56Sopenharmony_ci expect = "ab%3F%3F+cd" 10747db96d56Sopenharmony_ci result = urllib.parse.quote_plus(given, encoding="latin-1", 10757db96d56Sopenharmony_ci errors="replace") 10767db96d56Sopenharmony_ci self.assertEqual(expect, result, 10777db96d56Sopenharmony_ci "using quote_plus(): %r != %r" % (expect, result)) 10787db96d56Sopenharmony_ci 10797db96d56Sopenharmony_ci 10807db96d56Sopenharmony_ciclass UnquotingTests(unittest.TestCase): 10817db96d56Sopenharmony_ci """Tests for unquote() and unquote_plus() 10827db96d56Sopenharmony_ci 10837db96d56Sopenharmony_ci See the doc string for quoting_Tests for details on quoting and such. 10847db96d56Sopenharmony_ci 10857db96d56Sopenharmony_ci """ 10867db96d56Sopenharmony_ci 10877db96d56Sopenharmony_ci def test_unquoting(self): 10887db96d56Sopenharmony_ci # Make sure unquoting of all ASCII values works 10897db96d56Sopenharmony_ci escape_list = [] 10907db96d56Sopenharmony_ci for num in range(128): 10917db96d56Sopenharmony_ci given = hexescape(chr(num)) 10927db96d56Sopenharmony_ci expect = chr(num) 10937db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 10947db96d56Sopenharmony_ci self.assertEqual(expect, result, 10957db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 10967db96d56Sopenharmony_ci result = urllib.parse.unquote_plus(given) 10977db96d56Sopenharmony_ci self.assertEqual(expect, result, 10987db96d56Sopenharmony_ci "using unquote_plus(): %r != %r" % 10997db96d56Sopenharmony_ci (expect, result)) 11007db96d56Sopenharmony_ci escape_list.append(given) 11017db96d56Sopenharmony_ci escape_string = ''.join(escape_list) 11027db96d56Sopenharmony_ci del escape_list 11037db96d56Sopenharmony_ci result = urllib.parse.unquote(escape_string) 11047db96d56Sopenharmony_ci self.assertEqual(result.count('%'), 1, 11057db96d56Sopenharmony_ci "using unquote(): not all characters escaped: " 11067db96d56Sopenharmony_ci "%s" % result) 11077db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None) 11087db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ()) 11097db96d56Sopenharmony_ci 11107db96d56Sopenharmony_ci def test_unquoting_badpercent(self): 11117db96d56Sopenharmony_ci # Test unquoting on bad percent-escapes 11127db96d56Sopenharmony_ci given = '%xab' 11137db96d56Sopenharmony_ci expect = given 11147db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 11157db96d56Sopenharmony_ci self.assertEqual(expect, result, "using unquote(): %r != %r" 11167db96d56Sopenharmony_ci % (expect, result)) 11177db96d56Sopenharmony_ci given = '%x' 11187db96d56Sopenharmony_ci expect = given 11197db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 11207db96d56Sopenharmony_ci self.assertEqual(expect, result, "using unquote(): %r != %r" 11217db96d56Sopenharmony_ci % (expect, result)) 11227db96d56Sopenharmony_ci given = '%' 11237db96d56Sopenharmony_ci expect = given 11247db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 11257db96d56Sopenharmony_ci self.assertEqual(expect, result, "using unquote(): %r != %r" 11267db96d56Sopenharmony_ci % (expect, result)) 11277db96d56Sopenharmony_ci # unquote_to_bytes 11287db96d56Sopenharmony_ci given = '%xab' 11297db96d56Sopenharmony_ci expect = bytes(given, 'ascii') 11307db96d56Sopenharmony_ci result = urllib.parse.unquote_to_bytes(given) 11317db96d56Sopenharmony_ci self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r" 11327db96d56Sopenharmony_ci % (expect, result)) 11337db96d56Sopenharmony_ci given = '%x' 11347db96d56Sopenharmony_ci expect = bytes(given, 'ascii') 11357db96d56Sopenharmony_ci result = urllib.parse.unquote_to_bytes(given) 11367db96d56Sopenharmony_ci self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r" 11377db96d56Sopenharmony_ci % (expect, result)) 11387db96d56Sopenharmony_ci given = '%' 11397db96d56Sopenharmony_ci expect = bytes(given, 'ascii') 11407db96d56Sopenharmony_ci result = urllib.parse.unquote_to_bytes(given) 11417db96d56Sopenharmony_ci self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r" 11427db96d56Sopenharmony_ci % (expect, result)) 11437db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, None) 11447db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, ()) 11457db96d56Sopenharmony_ci 11467db96d56Sopenharmony_ci def test_unquoting_mixed_case(self): 11477db96d56Sopenharmony_ci # Test unquoting on mixed-case hex digits in the percent-escapes 11487db96d56Sopenharmony_ci given = '%Ab%eA' 11497db96d56Sopenharmony_ci expect = b'\xab\xea' 11507db96d56Sopenharmony_ci result = urllib.parse.unquote_to_bytes(given) 11517db96d56Sopenharmony_ci self.assertEqual(expect, result, 11527db96d56Sopenharmony_ci "using unquote_to_bytes(): %r != %r" 11537db96d56Sopenharmony_ci % (expect, result)) 11547db96d56Sopenharmony_ci 11557db96d56Sopenharmony_ci def test_unquoting_parts(self): 11567db96d56Sopenharmony_ci # Make sure unquoting works when have non-quoted characters 11577db96d56Sopenharmony_ci # interspersed 11587db96d56Sopenharmony_ci given = 'ab%sd' % hexescape('c') 11597db96d56Sopenharmony_ci expect = "abcd" 11607db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 11617db96d56Sopenharmony_ci self.assertEqual(expect, result, 11627db96d56Sopenharmony_ci "using quote(): %r != %r" % (expect, result)) 11637db96d56Sopenharmony_ci result = urllib.parse.unquote_plus(given) 11647db96d56Sopenharmony_ci self.assertEqual(expect, result, 11657db96d56Sopenharmony_ci "using unquote_plus(): %r != %r" % (expect, result)) 11667db96d56Sopenharmony_ci 11677db96d56Sopenharmony_ci def test_unquoting_plus(self): 11687db96d56Sopenharmony_ci # Test difference between unquote() and unquote_plus() 11697db96d56Sopenharmony_ci given = "are+there+spaces..." 11707db96d56Sopenharmony_ci expect = given 11717db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 11727db96d56Sopenharmony_ci self.assertEqual(expect, result, 11737db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 11747db96d56Sopenharmony_ci expect = given.replace('+', ' ') 11757db96d56Sopenharmony_ci result = urllib.parse.unquote_plus(given) 11767db96d56Sopenharmony_ci self.assertEqual(expect, result, 11777db96d56Sopenharmony_ci "using unquote_plus(): %r != %r" % (expect, result)) 11787db96d56Sopenharmony_ci 11797db96d56Sopenharmony_ci def test_unquote_to_bytes(self): 11807db96d56Sopenharmony_ci given = 'br%C3%BCckner_sapporo_20050930.doc' 11817db96d56Sopenharmony_ci expect = b'br\xc3\xbcckner_sapporo_20050930.doc' 11827db96d56Sopenharmony_ci result = urllib.parse.unquote_to_bytes(given) 11837db96d56Sopenharmony_ci self.assertEqual(expect, result, 11847db96d56Sopenharmony_ci "using unquote_to_bytes(): %r != %r" 11857db96d56Sopenharmony_ci % (expect, result)) 11867db96d56Sopenharmony_ci # Test on a string with unescaped non-ASCII characters 11877db96d56Sopenharmony_ci # (Technically an invalid URI; expect those characters to be UTF-8 11887db96d56Sopenharmony_ci # encoded). 11897db96d56Sopenharmony_ci result = urllib.parse.unquote_to_bytes("\u6f22%C3%BC") 11907db96d56Sopenharmony_ci expect = b'\xe6\xbc\xa2\xc3\xbc' # UTF-8 for "\u6f22\u00fc" 11917db96d56Sopenharmony_ci self.assertEqual(expect, result, 11927db96d56Sopenharmony_ci "using unquote_to_bytes(): %r != %r" 11937db96d56Sopenharmony_ci % (expect, result)) 11947db96d56Sopenharmony_ci # Test with a bytes as input 11957db96d56Sopenharmony_ci given = b'%A2%D8ab%FF' 11967db96d56Sopenharmony_ci expect = b'\xa2\xd8ab\xff' 11977db96d56Sopenharmony_ci result = urllib.parse.unquote_to_bytes(given) 11987db96d56Sopenharmony_ci self.assertEqual(expect, result, 11997db96d56Sopenharmony_ci "using unquote_to_bytes(): %r != %r" 12007db96d56Sopenharmony_ci % (expect, result)) 12017db96d56Sopenharmony_ci # Test with a bytes as input, with unescaped non-ASCII bytes 12027db96d56Sopenharmony_ci # (Technically an invalid URI; expect those bytes to be preserved) 12037db96d56Sopenharmony_ci given = b'%A2\xd8ab%FF' 12047db96d56Sopenharmony_ci expect = b'\xa2\xd8ab\xff' 12057db96d56Sopenharmony_ci result = urllib.parse.unquote_to_bytes(given) 12067db96d56Sopenharmony_ci self.assertEqual(expect, result, 12077db96d56Sopenharmony_ci "using unquote_to_bytes(): %r != %r" 12087db96d56Sopenharmony_ci % (expect, result)) 12097db96d56Sopenharmony_ci 12107db96d56Sopenharmony_ci def test_unquote_with_unicode(self): 12117db96d56Sopenharmony_ci # Characters in the Latin-1 range, encoded with UTF-8 12127db96d56Sopenharmony_ci given = 'br%C3%BCckner_sapporo_20050930.doc' 12137db96d56Sopenharmony_ci expect = 'br\u00fcckner_sapporo_20050930.doc' 12147db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 12157db96d56Sopenharmony_ci self.assertEqual(expect, result, 12167db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12177db96d56Sopenharmony_ci # Characters in the Latin-1 range, encoded with None (default) 12187db96d56Sopenharmony_ci result = urllib.parse.unquote(given, encoding=None, errors=None) 12197db96d56Sopenharmony_ci self.assertEqual(expect, result, 12207db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12217db96d56Sopenharmony_ci 12227db96d56Sopenharmony_ci # Characters in the Latin-1 range, encoded with Latin-1 12237db96d56Sopenharmony_ci result = urllib.parse.unquote('br%FCckner_sapporo_20050930.doc', 12247db96d56Sopenharmony_ci encoding="latin-1") 12257db96d56Sopenharmony_ci expect = 'br\u00fcckner_sapporo_20050930.doc' 12267db96d56Sopenharmony_ci self.assertEqual(expect, result, 12277db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12287db96d56Sopenharmony_ci 12297db96d56Sopenharmony_ci # Characters in BMP, encoded with UTF-8 12307db96d56Sopenharmony_ci given = "%E6%BC%A2%E5%AD%97" 12317db96d56Sopenharmony_ci expect = "\u6f22\u5b57" # "Kanji" 12327db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 12337db96d56Sopenharmony_ci self.assertEqual(expect, result, 12347db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12357db96d56Sopenharmony_ci 12367db96d56Sopenharmony_ci # Decode with UTF-8, invalid sequence 12377db96d56Sopenharmony_ci given = "%F3%B1" 12387db96d56Sopenharmony_ci expect = "\ufffd" # Replacement character 12397db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 12407db96d56Sopenharmony_ci self.assertEqual(expect, result, 12417db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12427db96d56Sopenharmony_ci 12437db96d56Sopenharmony_ci # Decode with UTF-8, invalid sequence, replace errors 12447db96d56Sopenharmony_ci result = urllib.parse.unquote(given, errors="replace") 12457db96d56Sopenharmony_ci self.assertEqual(expect, result, 12467db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12477db96d56Sopenharmony_ci 12487db96d56Sopenharmony_ci # Decode with UTF-8, invalid sequence, ignoring errors 12497db96d56Sopenharmony_ci given = "%F3%B1" 12507db96d56Sopenharmony_ci expect = "" 12517db96d56Sopenharmony_ci result = urllib.parse.unquote(given, errors="ignore") 12527db96d56Sopenharmony_ci self.assertEqual(expect, result, 12537db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12547db96d56Sopenharmony_ci 12557db96d56Sopenharmony_ci # A mix of non-ASCII and percent-encoded characters, UTF-8 12567db96d56Sopenharmony_ci result = urllib.parse.unquote("\u6f22%C3%BC") 12577db96d56Sopenharmony_ci expect = '\u6f22\u00fc' 12587db96d56Sopenharmony_ci self.assertEqual(expect, result, 12597db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12607db96d56Sopenharmony_ci 12617db96d56Sopenharmony_ci # A mix of non-ASCII and percent-encoded characters, Latin-1 12627db96d56Sopenharmony_ci # (Note, the string contains non-Latin-1-representable characters) 12637db96d56Sopenharmony_ci result = urllib.parse.unquote("\u6f22%FC", encoding="latin-1") 12647db96d56Sopenharmony_ci expect = '\u6f22\u00fc' 12657db96d56Sopenharmony_ci self.assertEqual(expect, result, 12667db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12677db96d56Sopenharmony_ci 12687db96d56Sopenharmony_ci def test_unquoting_with_bytes_input(self): 12697db96d56Sopenharmony_ci # ASCII characters decoded to a string 12707db96d56Sopenharmony_ci given = b'blueberryjam' 12717db96d56Sopenharmony_ci expect = 'blueberryjam' 12727db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 12737db96d56Sopenharmony_ci self.assertEqual(expect, result, 12747db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12757db96d56Sopenharmony_ci 12767db96d56Sopenharmony_ci # A mix of non-ASCII hex-encoded characters and ASCII characters 12777db96d56Sopenharmony_ci given = b'bl\xc3\xa5b\xc3\xa6rsyltet\xc3\xb8y' 12787db96d56Sopenharmony_ci expect = 'bl\u00e5b\u00e6rsyltet\u00f8y' 12797db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 12807db96d56Sopenharmony_ci self.assertEqual(expect, result, 12817db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12827db96d56Sopenharmony_ci 12837db96d56Sopenharmony_ci # A mix of non-ASCII percent-encoded characters and ASCII characters 12847db96d56Sopenharmony_ci given = b'bl%c3%a5b%c3%a6rsyltet%c3%b8j' 12857db96d56Sopenharmony_ci expect = 'bl\u00e5b\u00e6rsyltet\u00f8j' 12867db96d56Sopenharmony_ci result = urllib.parse.unquote(given) 12877db96d56Sopenharmony_ci self.assertEqual(expect, result, 12887db96d56Sopenharmony_ci "using unquote(): %r != %r" % (expect, result)) 12897db96d56Sopenharmony_ci 12907db96d56Sopenharmony_ci 12917db96d56Sopenharmony_ciclass urlencode_Tests(unittest.TestCase): 12927db96d56Sopenharmony_ci """Tests for urlencode()""" 12937db96d56Sopenharmony_ci 12947db96d56Sopenharmony_ci def help_inputtype(self, given, test_type): 12957db96d56Sopenharmony_ci """Helper method for testing different input types. 12967db96d56Sopenharmony_ci 12977db96d56Sopenharmony_ci 'given' must lead to only the pairs: 12987db96d56Sopenharmony_ci * 1st, 1 12997db96d56Sopenharmony_ci * 2nd, 2 13007db96d56Sopenharmony_ci * 3rd, 3 13017db96d56Sopenharmony_ci 13027db96d56Sopenharmony_ci Test cannot assume anything about order. Docs make no guarantee and 13037db96d56Sopenharmony_ci have possible dictionary input. 13047db96d56Sopenharmony_ci 13057db96d56Sopenharmony_ci """ 13067db96d56Sopenharmony_ci expect_somewhere = ["1st=1", "2nd=2", "3rd=3"] 13077db96d56Sopenharmony_ci result = urllib.parse.urlencode(given) 13087db96d56Sopenharmony_ci for expected in expect_somewhere: 13097db96d56Sopenharmony_ci self.assertIn(expected, result, 13107db96d56Sopenharmony_ci "testing %s: %s not found in %s" % 13117db96d56Sopenharmony_ci (test_type, expected, result)) 13127db96d56Sopenharmony_ci self.assertEqual(result.count('&'), 2, 13137db96d56Sopenharmony_ci "testing %s: expected 2 '&'s; got %s" % 13147db96d56Sopenharmony_ci (test_type, result.count('&'))) 13157db96d56Sopenharmony_ci amp_location = result.index('&') 13167db96d56Sopenharmony_ci on_amp_left = result[amp_location - 1] 13177db96d56Sopenharmony_ci on_amp_right = result[amp_location + 1] 13187db96d56Sopenharmony_ci self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(), 13197db96d56Sopenharmony_ci "testing %s: '&' not located in proper place in %s" % 13207db96d56Sopenharmony_ci (test_type, result)) 13217db96d56Sopenharmony_ci self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps 13227db96d56Sopenharmony_ci "testing %s: " 13237db96d56Sopenharmony_ci "unexpected number of characters: %s != %s" % 13247db96d56Sopenharmony_ci (test_type, len(result), (5 * 3) + 2)) 13257db96d56Sopenharmony_ci 13267db96d56Sopenharmony_ci def test_using_mapping(self): 13277db96d56Sopenharmony_ci # Test passing in a mapping object as an argument. 13287db96d56Sopenharmony_ci self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'}, 13297db96d56Sopenharmony_ci "using dict as input type") 13307db96d56Sopenharmony_ci 13317db96d56Sopenharmony_ci def test_using_sequence(self): 13327db96d56Sopenharmony_ci # Test passing in a sequence of two-item sequences as an argument. 13337db96d56Sopenharmony_ci self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')], 13347db96d56Sopenharmony_ci "using sequence of two-item tuples as input") 13357db96d56Sopenharmony_ci 13367db96d56Sopenharmony_ci def test_quoting(self): 13377db96d56Sopenharmony_ci # Make sure keys and values are quoted using quote_plus() 13387db96d56Sopenharmony_ci given = {"&":"="} 13397db96d56Sopenharmony_ci expect = "%s=%s" % (hexescape('&'), hexescape('=')) 13407db96d56Sopenharmony_ci result = urllib.parse.urlencode(given) 13417db96d56Sopenharmony_ci self.assertEqual(expect, result) 13427db96d56Sopenharmony_ci given = {"key name":"A bunch of pluses"} 13437db96d56Sopenharmony_ci expect = "key+name=A+bunch+of+pluses" 13447db96d56Sopenharmony_ci result = urllib.parse.urlencode(given) 13457db96d56Sopenharmony_ci self.assertEqual(expect, result) 13467db96d56Sopenharmony_ci 13477db96d56Sopenharmony_ci def test_doseq(self): 13487db96d56Sopenharmony_ci # Test that passing True for 'doseq' parameter works correctly 13497db96d56Sopenharmony_ci given = {'sequence':['1', '2', '3']} 13507db96d56Sopenharmony_ci expect = "sequence=%s" % urllib.parse.quote_plus(str(['1', '2', '3'])) 13517db96d56Sopenharmony_ci result = urllib.parse.urlencode(given) 13527db96d56Sopenharmony_ci self.assertEqual(expect, result) 13537db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True) 13547db96d56Sopenharmony_ci for value in given["sequence"]: 13557db96d56Sopenharmony_ci expect = "sequence=%s" % value 13567db96d56Sopenharmony_ci self.assertIn(expect, result) 13577db96d56Sopenharmony_ci self.assertEqual(result.count('&'), 2, 13587db96d56Sopenharmony_ci "Expected 2 '&'s, got %s" % result.count('&')) 13597db96d56Sopenharmony_ci 13607db96d56Sopenharmony_ci def test_empty_sequence(self): 13617db96d56Sopenharmony_ci self.assertEqual("", urllib.parse.urlencode({})) 13627db96d56Sopenharmony_ci self.assertEqual("", urllib.parse.urlencode([])) 13637db96d56Sopenharmony_ci 13647db96d56Sopenharmony_ci def test_nonstring_values(self): 13657db96d56Sopenharmony_ci self.assertEqual("a=1", urllib.parse.urlencode({"a": 1})) 13667db96d56Sopenharmony_ci self.assertEqual("a=None", urllib.parse.urlencode({"a": None})) 13677db96d56Sopenharmony_ci 13687db96d56Sopenharmony_ci def test_nonstring_seq_values(self): 13697db96d56Sopenharmony_ci self.assertEqual("a=1&a=2", urllib.parse.urlencode({"a": [1, 2]}, True)) 13707db96d56Sopenharmony_ci self.assertEqual("a=None&a=a", 13717db96d56Sopenharmony_ci urllib.parse.urlencode({"a": [None, "a"]}, True)) 13727db96d56Sopenharmony_ci data = collections.OrderedDict([("a", 1), ("b", 1)]) 13737db96d56Sopenharmony_ci self.assertEqual("a=a&a=b", 13747db96d56Sopenharmony_ci urllib.parse.urlencode({"a": data}, True)) 13757db96d56Sopenharmony_ci 13767db96d56Sopenharmony_ci def test_urlencode_encoding(self): 13777db96d56Sopenharmony_ci # ASCII encoding. Expect %3F with errors="replace' 13787db96d56Sopenharmony_ci given = (('\u00a0', '\u00c1'),) 13797db96d56Sopenharmony_ci expect = '%3F=%3F' 13807db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, encoding="ASCII", errors="replace") 13817db96d56Sopenharmony_ci self.assertEqual(expect, result) 13827db96d56Sopenharmony_ci 13837db96d56Sopenharmony_ci # Default is UTF-8 encoding. 13847db96d56Sopenharmony_ci given = (('\u00a0', '\u00c1'),) 13857db96d56Sopenharmony_ci expect = '%C2%A0=%C3%81' 13867db96d56Sopenharmony_ci result = urllib.parse.urlencode(given) 13877db96d56Sopenharmony_ci self.assertEqual(expect, result) 13887db96d56Sopenharmony_ci 13897db96d56Sopenharmony_ci # Latin-1 encoding. 13907db96d56Sopenharmony_ci given = (('\u00a0', '\u00c1'),) 13917db96d56Sopenharmony_ci expect = '%A0=%C1' 13927db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, encoding="latin-1") 13937db96d56Sopenharmony_ci self.assertEqual(expect, result) 13947db96d56Sopenharmony_ci 13957db96d56Sopenharmony_ci def test_urlencode_encoding_doseq(self): 13967db96d56Sopenharmony_ci # ASCII Encoding. Expect %3F with errors="replace' 13977db96d56Sopenharmony_ci given = (('\u00a0', '\u00c1'),) 13987db96d56Sopenharmony_ci expect = '%3F=%3F' 13997db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, doseq=True, 14007db96d56Sopenharmony_ci encoding="ASCII", errors="replace") 14017db96d56Sopenharmony_ci self.assertEqual(expect, result) 14027db96d56Sopenharmony_ci 14037db96d56Sopenharmony_ci # ASCII Encoding. On a sequence of values. 14047db96d56Sopenharmony_ci given = (("\u00a0", (1, "\u00c1")),) 14057db96d56Sopenharmony_ci expect = '%3F=1&%3F=%3F' 14067db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True, 14077db96d56Sopenharmony_ci encoding="ASCII", errors="replace") 14087db96d56Sopenharmony_ci self.assertEqual(expect, result) 14097db96d56Sopenharmony_ci 14107db96d56Sopenharmony_ci # Utf-8 14117db96d56Sopenharmony_ci given = (("\u00a0", "\u00c1"),) 14127db96d56Sopenharmony_ci expect = '%C2%A0=%C3%81' 14137db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True) 14147db96d56Sopenharmony_ci self.assertEqual(expect, result) 14157db96d56Sopenharmony_ci 14167db96d56Sopenharmony_ci given = (("\u00a0", (42, "\u00c1")),) 14177db96d56Sopenharmony_ci expect = '%C2%A0=42&%C2%A0=%C3%81' 14187db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True) 14197db96d56Sopenharmony_ci self.assertEqual(expect, result) 14207db96d56Sopenharmony_ci 14217db96d56Sopenharmony_ci # latin-1 14227db96d56Sopenharmony_ci given = (("\u00a0", "\u00c1"),) 14237db96d56Sopenharmony_ci expect = '%A0=%C1' 14247db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True, encoding="latin-1") 14257db96d56Sopenharmony_ci self.assertEqual(expect, result) 14267db96d56Sopenharmony_ci 14277db96d56Sopenharmony_ci given = (("\u00a0", (42, "\u00c1")),) 14287db96d56Sopenharmony_ci expect = '%A0=42&%A0=%C1' 14297db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True, encoding="latin-1") 14307db96d56Sopenharmony_ci self.assertEqual(expect, result) 14317db96d56Sopenharmony_ci 14327db96d56Sopenharmony_ci def test_urlencode_bytes(self): 14337db96d56Sopenharmony_ci given = ((b'\xa0\x24', b'\xc1\x24'),) 14347db96d56Sopenharmony_ci expect = '%A0%24=%C1%24' 14357db96d56Sopenharmony_ci result = urllib.parse.urlencode(given) 14367db96d56Sopenharmony_ci self.assertEqual(expect, result) 14377db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True) 14387db96d56Sopenharmony_ci self.assertEqual(expect, result) 14397db96d56Sopenharmony_ci 14407db96d56Sopenharmony_ci # Sequence of values 14417db96d56Sopenharmony_ci given = ((b'\xa0\x24', (42, b'\xc1\x24')),) 14427db96d56Sopenharmony_ci expect = '%A0%24=42&%A0%24=%C1%24' 14437db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True) 14447db96d56Sopenharmony_ci self.assertEqual(expect, result) 14457db96d56Sopenharmony_ci 14467db96d56Sopenharmony_ci def test_urlencode_encoding_safe_parameter(self): 14477db96d56Sopenharmony_ci 14487db96d56Sopenharmony_ci # Send '$' (\x24) as safe character 14497db96d56Sopenharmony_ci # Default utf-8 encoding 14507db96d56Sopenharmony_ci 14517db96d56Sopenharmony_ci given = ((b'\xa0\x24', b'\xc1\x24'),) 14527db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, safe=":$") 14537db96d56Sopenharmony_ci expect = '%A0$=%C1$' 14547db96d56Sopenharmony_ci self.assertEqual(expect, result) 14557db96d56Sopenharmony_ci 14567db96d56Sopenharmony_ci given = ((b'\xa0\x24', b'\xc1\x24'),) 14577db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, doseq=True, safe=":$") 14587db96d56Sopenharmony_ci expect = '%A0$=%C1$' 14597db96d56Sopenharmony_ci self.assertEqual(expect, result) 14607db96d56Sopenharmony_ci 14617db96d56Sopenharmony_ci # Safe parameter in sequence 14627db96d56Sopenharmony_ci given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),) 14637db96d56Sopenharmony_ci expect = '%A0$=%C1$&%A0$=13&%A0$=42' 14647db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True, safe=":$") 14657db96d56Sopenharmony_ci self.assertEqual(expect, result) 14667db96d56Sopenharmony_ci 14677db96d56Sopenharmony_ci # Test all above in latin-1 encoding 14687db96d56Sopenharmony_ci 14697db96d56Sopenharmony_ci given = ((b'\xa0\x24', b'\xc1\x24'),) 14707db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, safe=":$", 14717db96d56Sopenharmony_ci encoding="latin-1") 14727db96d56Sopenharmony_ci expect = '%A0$=%C1$' 14737db96d56Sopenharmony_ci self.assertEqual(expect, result) 14747db96d56Sopenharmony_ci 14757db96d56Sopenharmony_ci given = ((b'\xa0\x24', b'\xc1\x24'),) 14767db96d56Sopenharmony_ci expect = '%A0$=%C1$' 14777db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, doseq=True, safe=":$", 14787db96d56Sopenharmony_ci encoding="latin-1") 14797db96d56Sopenharmony_ci 14807db96d56Sopenharmony_ci given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),) 14817db96d56Sopenharmony_ci expect = '%A0$=%C1$&%A0$=13&%A0$=42' 14827db96d56Sopenharmony_ci result = urllib.parse.urlencode(given, True, safe=":$", 14837db96d56Sopenharmony_ci encoding="latin-1") 14847db96d56Sopenharmony_ci self.assertEqual(expect, result) 14857db96d56Sopenharmony_ci 14867db96d56Sopenharmony_ciclass Pathname_Tests(unittest.TestCase): 14877db96d56Sopenharmony_ci """Test pathname2url() and url2pathname()""" 14887db96d56Sopenharmony_ci 14897db96d56Sopenharmony_ci def test_basic(self): 14907db96d56Sopenharmony_ci # Make sure simple tests pass 14917db96d56Sopenharmony_ci expected_path = os.path.join("parts", "of", "a", "path") 14927db96d56Sopenharmony_ci expected_url = "parts/of/a/path" 14937db96d56Sopenharmony_ci result = urllib.request.pathname2url(expected_path) 14947db96d56Sopenharmony_ci self.assertEqual(expected_url, result, 14957db96d56Sopenharmony_ci "pathname2url() failed; %s != %s" % 14967db96d56Sopenharmony_ci (result, expected_url)) 14977db96d56Sopenharmony_ci result = urllib.request.url2pathname(expected_url) 14987db96d56Sopenharmony_ci self.assertEqual(expected_path, result, 14997db96d56Sopenharmony_ci "url2pathame() failed; %s != %s" % 15007db96d56Sopenharmony_ci (result, expected_path)) 15017db96d56Sopenharmony_ci 15027db96d56Sopenharmony_ci def test_quoting(self): 15037db96d56Sopenharmony_ci # Test automatic quoting and unquoting works for pathnam2url() and 15047db96d56Sopenharmony_ci # url2pathname() respectively 15057db96d56Sopenharmony_ci given = os.path.join("needs", "quot=ing", "here") 15067db96d56Sopenharmony_ci expect = "needs/%s/here" % urllib.parse.quote("quot=ing") 15077db96d56Sopenharmony_ci result = urllib.request.pathname2url(given) 15087db96d56Sopenharmony_ci self.assertEqual(expect, result, 15097db96d56Sopenharmony_ci "pathname2url() failed; %s != %s" % 15107db96d56Sopenharmony_ci (expect, result)) 15117db96d56Sopenharmony_ci expect = given 15127db96d56Sopenharmony_ci result = urllib.request.url2pathname(result) 15137db96d56Sopenharmony_ci self.assertEqual(expect, result, 15147db96d56Sopenharmony_ci "url2pathname() failed; %s != %s" % 15157db96d56Sopenharmony_ci (expect, result)) 15167db96d56Sopenharmony_ci given = os.path.join("make sure", "using_quote") 15177db96d56Sopenharmony_ci expect = "%s/using_quote" % urllib.parse.quote("make sure") 15187db96d56Sopenharmony_ci result = urllib.request.pathname2url(given) 15197db96d56Sopenharmony_ci self.assertEqual(expect, result, 15207db96d56Sopenharmony_ci "pathname2url() failed; %s != %s" % 15217db96d56Sopenharmony_ci (expect, result)) 15227db96d56Sopenharmony_ci given = "make+sure/using_unquote" 15237db96d56Sopenharmony_ci expect = os.path.join("make+sure", "using_unquote") 15247db96d56Sopenharmony_ci result = urllib.request.url2pathname(given) 15257db96d56Sopenharmony_ci self.assertEqual(expect, result, 15267db96d56Sopenharmony_ci "url2pathname() failed; %s != %s" % 15277db96d56Sopenharmony_ci (expect, result)) 15287db96d56Sopenharmony_ci 15297db96d56Sopenharmony_ci @unittest.skipUnless(sys.platform == 'win32', 15307db96d56Sopenharmony_ci 'test specific to the nturl2path functions.') 15317db96d56Sopenharmony_ci def test_prefixes(self): 15327db96d56Sopenharmony_ci # Test special prefixes are correctly handled in pathname2url() 15337db96d56Sopenharmony_ci given = '\\\\?\\C:\\dir' 15347db96d56Sopenharmony_ci expect = '///C:/dir' 15357db96d56Sopenharmony_ci result = urllib.request.pathname2url(given) 15367db96d56Sopenharmony_ci self.assertEqual(expect, result, 15377db96d56Sopenharmony_ci "pathname2url() failed; %s != %s" % 15387db96d56Sopenharmony_ci (expect, result)) 15397db96d56Sopenharmony_ci given = '\\\\?\\unc\\server\\share\\dir' 15407db96d56Sopenharmony_ci expect = '/server/share/dir' 15417db96d56Sopenharmony_ci result = urllib.request.pathname2url(given) 15427db96d56Sopenharmony_ci self.assertEqual(expect, result, 15437db96d56Sopenharmony_ci "pathname2url() failed; %s != %s" % 15447db96d56Sopenharmony_ci (expect, result)) 15457db96d56Sopenharmony_ci 15467db96d56Sopenharmony_ci 15477db96d56Sopenharmony_ci @unittest.skipUnless(sys.platform == 'win32', 15487db96d56Sopenharmony_ci 'test specific to the urllib.url2path function.') 15497db96d56Sopenharmony_ci def test_ntpath(self): 15507db96d56Sopenharmony_ci given = ('/C:/', '///C:/', '/C|//') 15517db96d56Sopenharmony_ci expect = 'C:\\' 15527db96d56Sopenharmony_ci for url in given: 15537db96d56Sopenharmony_ci result = urllib.request.url2pathname(url) 15547db96d56Sopenharmony_ci self.assertEqual(expect, result, 15557db96d56Sopenharmony_ci 'urllib.request..url2pathname() failed; %s != %s' % 15567db96d56Sopenharmony_ci (expect, result)) 15577db96d56Sopenharmony_ci given = '///C|/path' 15587db96d56Sopenharmony_ci expect = 'C:\\path' 15597db96d56Sopenharmony_ci result = urllib.request.url2pathname(given) 15607db96d56Sopenharmony_ci self.assertEqual(expect, result, 15617db96d56Sopenharmony_ci 'urllib.request.url2pathname() failed; %s != %s' % 15627db96d56Sopenharmony_ci (expect, result)) 15637db96d56Sopenharmony_ci 15647db96d56Sopenharmony_ciclass Utility_Tests(unittest.TestCase): 15657db96d56Sopenharmony_ci """Testcase to test the various utility functions in the urllib.""" 15667db96d56Sopenharmony_ci 15677db96d56Sopenharmony_ci def test_thishost(self): 15687db96d56Sopenharmony_ci """Test the urllib.request.thishost utility function returns a tuple""" 15697db96d56Sopenharmony_ci self.assertIsInstance(urllib.request.thishost(), tuple) 15707db96d56Sopenharmony_ci 15717db96d56Sopenharmony_ci 15727db96d56Sopenharmony_ciclass URLopener_Tests(FakeHTTPMixin, unittest.TestCase): 15737db96d56Sopenharmony_ci """Testcase to test the open method of URLopener class.""" 15747db96d56Sopenharmony_ci 15757db96d56Sopenharmony_ci def test_quoted_open(self): 15767db96d56Sopenharmony_ci class DummyURLopener(urllib.request.URLopener): 15777db96d56Sopenharmony_ci def open_spam(self, url): 15787db96d56Sopenharmony_ci return url 15797db96d56Sopenharmony_ci with warnings_helper.check_warnings( 15807db96d56Sopenharmony_ci ('DummyURLopener style of invoking requests is deprecated.', 15817db96d56Sopenharmony_ci DeprecationWarning)): 15827db96d56Sopenharmony_ci self.assertEqual(DummyURLopener().open( 15837db96d56Sopenharmony_ci 'spam://example/ /'),'//example/%20/') 15847db96d56Sopenharmony_ci 15857db96d56Sopenharmony_ci # test the safe characters are not quoted by urlopen 15867db96d56Sopenharmony_ci self.assertEqual(DummyURLopener().open( 15877db96d56Sopenharmony_ci "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"), 15887db96d56Sopenharmony_ci "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/") 15897db96d56Sopenharmony_ci 15907db96d56Sopenharmony_ci @warnings_helper.ignore_warnings(category=DeprecationWarning) 15917db96d56Sopenharmony_ci def test_urlopener_retrieve_file(self): 15927db96d56Sopenharmony_ci with os_helper.temp_dir() as tmpdir: 15937db96d56Sopenharmony_ci fd, tmpfile = tempfile.mkstemp(dir=tmpdir) 15947db96d56Sopenharmony_ci os.close(fd) 15957db96d56Sopenharmony_ci fileurl = "file:" + urllib.request.pathname2url(tmpfile) 15967db96d56Sopenharmony_ci filename, _ = urllib.request.URLopener().retrieve(fileurl) 15977db96d56Sopenharmony_ci # Some buildbots have TEMP folder that uses a lowercase drive letter. 15987db96d56Sopenharmony_ci self.assertEqual(os.path.normcase(filename), os.path.normcase(tmpfile)) 15997db96d56Sopenharmony_ci 16007db96d56Sopenharmony_ci @warnings_helper.ignore_warnings(category=DeprecationWarning) 16017db96d56Sopenharmony_ci def test_urlopener_retrieve_remote(self): 16027db96d56Sopenharmony_ci url = "http://www.python.org/file.txt" 16037db96d56Sopenharmony_ci self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!") 16047db96d56Sopenharmony_ci self.addCleanup(self.unfakehttp) 16057db96d56Sopenharmony_ci filename, _ = urllib.request.URLopener().retrieve(url) 16067db96d56Sopenharmony_ci self.assertEqual(os.path.splitext(filename)[1], ".txt") 16077db96d56Sopenharmony_ci 16087db96d56Sopenharmony_ci @warnings_helper.ignore_warnings(category=DeprecationWarning) 16097db96d56Sopenharmony_ci def test_local_file_open(self): 16107db96d56Sopenharmony_ci # bpo-35907, CVE-2019-9948: urllib must reject local_file:// scheme 16117db96d56Sopenharmony_ci class DummyURLopener(urllib.request.URLopener): 16127db96d56Sopenharmony_ci def open_local_file(self, url): 16137db96d56Sopenharmony_ci return url 16147db96d56Sopenharmony_ci for url in ('local_file://example', 'local-file://example'): 16157db96d56Sopenharmony_ci self.assertRaises(OSError, urllib.request.urlopen, url) 16167db96d56Sopenharmony_ci self.assertRaises(OSError, urllib.request.URLopener().open, url) 16177db96d56Sopenharmony_ci self.assertRaises(OSError, urllib.request.URLopener().retrieve, url) 16187db96d56Sopenharmony_ci self.assertRaises(OSError, DummyURLopener().open, url) 16197db96d56Sopenharmony_ci self.assertRaises(OSError, DummyURLopener().retrieve, url) 16207db96d56Sopenharmony_ci 16217db96d56Sopenharmony_ci 16227db96d56Sopenharmony_ciclass RequestTests(unittest.TestCase): 16237db96d56Sopenharmony_ci """Unit tests for urllib.request.Request.""" 16247db96d56Sopenharmony_ci 16257db96d56Sopenharmony_ci def test_default_values(self): 16267db96d56Sopenharmony_ci Request = urllib.request.Request 16277db96d56Sopenharmony_ci request = Request("http://www.python.org") 16287db96d56Sopenharmony_ci self.assertEqual(request.get_method(), 'GET') 16297db96d56Sopenharmony_ci request = Request("http://www.python.org", {}) 16307db96d56Sopenharmony_ci self.assertEqual(request.get_method(), 'POST') 16317db96d56Sopenharmony_ci 16327db96d56Sopenharmony_ci def test_with_method_arg(self): 16337db96d56Sopenharmony_ci Request = urllib.request.Request 16347db96d56Sopenharmony_ci request = Request("http://www.python.org", method='HEAD') 16357db96d56Sopenharmony_ci self.assertEqual(request.method, 'HEAD') 16367db96d56Sopenharmony_ci self.assertEqual(request.get_method(), 'HEAD') 16377db96d56Sopenharmony_ci request = Request("http://www.python.org", {}, method='HEAD') 16387db96d56Sopenharmony_ci self.assertEqual(request.method, 'HEAD') 16397db96d56Sopenharmony_ci self.assertEqual(request.get_method(), 'HEAD') 16407db96d56Sopenharmony_ci request = Request("http://www.python.org", method='GET') 16417db96d56Sopenharmony_ci self.assertEqual(request.get_method(), 'GET') 16427db96d56Sopenharmony_ci request.method = 'HEAD' 16437db96d56Sopenharmony_ci self.assertEqual(request.get_method(), 'HEAD') 16447db96d56Sopenharmony_ci 16457db96d56Sopenharmony_ci 16467db96d56Sopenharmony_ciclass URL2PathNameTests(unittest.TestCase): 16477db96d56Sopenharmony_ci 16487db96d56Sopenharmony_ci def test_converting_drive_letter(self): 16497db96d56Sopenharmony_ci self.assertEqual(url2pathname("///C|"), 'C:') 16507db96d56Sopenharmony_ci self.assertEqual(url2pathname("///C:"), 'C:') 16517db96d56Sopenharmony_ci self.assertEqual(url2pathname("///C|/"), 'C:\\') 16527db96d56Sopenharmony_ci 16537db96d56Sopenharmony_ci def test_converting_when_no_drive_letter(self): 16547db96d56Sopenharmony_ci # cannot end a raw string in \ 16557db96d56Sopenharmony_ci self.assertEqual(url2pathname("///C/test/"), r'\\\C\test' '\\') 16567db96d56Sopenharmony_ci self.assertEqual(url2pathname("////C/test/"), r'\\C\test' '\\') 16577db96d56Sopenharmony_ci 16587db96d56Sopenharmony_ci def test_simple_compare(self): 16597db96d56Sopenharmony_ci self.assertEqual(url2pathname("///C|/foo/bar/spam.foo"), 16607db96d56Sopenharmony_ci r'C:\foo\bar\spam.foo') 16617db96d56Sopenharmony_ci 16627db96d56Sopenharmony_ci def test_non_ascii_drive_letter(self): 16637db96d56Sopenharmony_ci self.assertRaises(IOError, url2pathname, "///\u00e8|/") 16647db96d56Sopenharmony_ci 16657db96d56Sopenharmony_ci def test_roundtrip_url2pathname(self): 16667db96d56Sopenharmony_ci list_of_paths = ['C:', 16677db96d56Sopenharmony_ci r'\\\C\test\\', 16687db96d56Sopenharmony_ci r'C:\foo\bar\spam.foo' 16697db96d56Sopenharmony_ci ] 16707db96d56Sopenharmony_ci for path in list_of_paths: 16717db96d56Sopenharmony_ci self.assertEqual(url2pathname(pathname2url(path)), path) 16727db96d56Sopenharmony_ci 16737db96d56Sopenharmony_ciclass PathName2URLTests(unittest.TestCase): 16747db96d56Sopenharmony_ci 16757db96d56Sopenharmony_ci def test_converting_drive_letter(self): 16767db96d56Sopenharmony_ci self.assertEqual(pathname2url("C:"), '///C:') 16777db96d56Sopenharmony_ci self.assertEqual(pathname2url("C:\\"), '///C:') 16787db96d56Sopenharmony_ci 16797db96d56Sopenharmony_ci def test_converting_when_no_drive_letter(self): 16807db96d56Sopenharmony_ci self.assertEqual(pathname2url(r"\\\folder\test" "\\"), 16817db96d56Sopenharmony_ci '/////folder/test/') 16827db96d56Sopenharmony_ci self.assertEqual(pathname2url(r"\\folder\test" "\\"), 16837db96d56Sopenharmony_ci '////folder/test/') 16847db96d56Sopenharmony_ci self.assertEqual(pathname2url(r"\folder\test" "\\"), 16857db96d56Sopenharmony_ci '/folder/test/') 16867db96d56Sopenharmony_ci 16877db96d56Sopenharmony_ci def test_simple_compare(self): 16887db96d56Sopenharmony_ci self.assertEqual(pathname2url(r'C:\foo\bar\spam.foo'), 16897db96d56Sopenharmony_ci "///C:/foo/bar/spam.foo" ) 16907db96d56Sopenharmony_ci 16917db96d56Sopenharmony_ci def test_long_drive_letter(self): 16927db96d56Sopenharmony_ci self.assertRaises(IOError, pathname2url, "XX:\\") 16937db96d56Sopenharmony_ci 16947db96d56Sopenharmony_ci def test_roundtrip_pathname2url(self): 16957db96d56Sopenharmony_ci list_of_paths = ['///C:', 16967db96d56Sopenharmony_ci '/////folder/test/', 16977db96d56Sopenharmony_ci '///C:/foo/bar/spam.foo'] 16987db96d56Sopenharmony_ci for path in list_of_paths: 16997db96d56Sopenharmony_ci self.assertEqual(pathname2url(url2pathname(path)), path) 17007db96d56Sopenharmony_ci 17017db96d56Sopenharmony_ciif __name__ == '__main__': 17027db96d56Sopenharmony_ci unittest.main() 1703