blob: 3fc499ec0762fdff3085e052e85bf08825a6aa64 [file] [log] [blame]
Brett Cannon74bfd702003-04-25 09:39:47 +00001"""Regresssion tests for urllib"""
2
Jeremy Hylton1afc1692008-06-18 20:49:58 +00003import urllib.parse
4import urllib.request
guido@google.coma119df92011-03-29 11:41:02 -07005import urllib.error
Georg Brandl24420152008-05-26 16:32:26 +00006import http.client
Barry Warsaw820c1202008-06-12 04:06:45 +00007import email.message
Jeremy Hylton66dc8c52007-08-04 03:42:26 +00008import io
Brett Cannon74bfd702003-04-25 09:39:47 +00009import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000010from test import support
Brett Cannon74bfd702003-04-25 09:39:47 +000011import os
Senthil Kumaran2d2ea1b2011-04-14 13:16:30 +080012import sys
Georg Brandl5a650a22005-08-26 08:51:34 +000013import tempfile
Jeremy Hylton6102e292000-08-31 15:48:10 +000014
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080015from base64 import b64encode
Georg Brandl2daf6ae2012-02-20 19:54:16 +010016import collections
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080017
Brett Cannon74bfd702003-04-25 09:39:47 +000018def hexescape(char):
19 """Escape char as RFC 2396 specifies"""
20 hex_repr = hex(ord(char))[2:].upper()
21 if len(hex_repr) == 1:
22 hex_repr = "0%s" % hex_repr
23 return "%" + hex_repr
Jeremy Hylton6102e292000-08-31 15:48:10 +000024
Jeremy Hylton1afc1692008-06-18 20:49:58 +000025# Shortcut for testing FancyURLopener
26_urlopener = None
27def urlopen(url, data=None, proxies=None):
28 """urlopen(url [, data]) -> open file-like object"""
29 global _urlopener
30 if proxies is not None:
31 opener = urllib.request.FancyURLopener(proxies=proxies)
32 elif not _urlopener:
33 opener = urllib.request.FancyURLopener()
34 _urlopener = opener
35 else:
36 opener = _urlopener
37 if data is None:
38 return opener.open(url)
39 else:
40 return opener.open(url, data)
41
Senthil Kumarance260142011-11-01 01:35:17 +080042
43class FakeHTTPMixin(object):
44 def fakehttp(self, fakedata):
45 class FakeSocket(io.BytesIO):
46 io_refs = 1
47
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080048 def sendall(self, data):
49 FakeHTTPConnection.buf = data
Senthil Kumarance260142011-11-01 01:35:17 +080050
51 def makefile(self, *args, **kwds):
52 self.io_refs += 1
53 return self
54
55 def read(self, amt=None):
56 if self.closed:
57 return b""
58 return io.BytesIO.read(self, amt)
59
60 def readline(self, length=None):
61 if self.closed:
62 return b""
63 return io.BytesIO.readline(self, length)
64
65 def close(self):
66 self.io_refs -= 1
67 if self.io_refs == 0:
68 io.BytesIO.close(self)
69
70 class FakeHTTPConnection(http.client.HTTPConnection):
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080071
72 # buffer to store data for verification in urlopen tests.
73 buf = None
74
Senthil Kumarance260142011-11-01 01:35:17 +080075 def connect(self):
76 self.sock = FakeSocket(fakedata)
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080077
Senthil Kumarance260142011-11-01 01:35:17 +080078 self._connection_class = http.client.HTTPConnection
79 http.client.HTTPConnection = FakeHTTPConnection
80
81 def unfakehttp(self):
82 http.client.HTTPConnection = self._connection_class
83
84
Brett Cannon74bfd702003-04-25 09:39:47 +000085class urlopen_FileTests(unittest.TestCase):
86 """Test urlopen() opening a temporary file.
Jeremy Hylton6102e292000-08-31 15:48:10 +000087
Brett Cannon74bfd702003-04-25 09:39:47 +000088 Try to test as much functionality as possible so as to cut down on reliance
Andrew M. Kuchlingf1a2f9e2004-06-29 13:07:53 +000089 on connecting to the Net for testing.
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000090
Brett Cannon74bfd702003-04-25 09:39:47 +000091 """
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000092
Brett Cannon74bfd702003-04-25 09:39:47 +000093 def setUp(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +000094 # Create a temp file to use for testing
95 self.text = bytes("test_urllib: %s\n" % self.__class__.__name__,
96 "ascii")
97 f = open(support.TESTFN, 'wb')
Brett Cannon74bfd702003-04-25 09:39:47 +000098 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +000099 f.write(self.text)
Brett Cannon74bfd702003-04-25 09:39:47 +0000100 finally:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000101 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000102 self.pathname = support.TESTFN
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000103 self.returned_obj = urlopen("file:%s" % self.pathname)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +0000104
Brett Cannon74bfd702003-04-25 09:39:47 +0000105 def tearDown(self):
106 """Shut down the open object"""
107 self.returned_obj.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000108 os.remove(support.TESTFN)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +0000109
Brett Cannon74bfd702003-04-25 09:39:47 +0000110 def test_interface(self):
111 # Make sure object returned by urlopen() has the specified methods
112 for attr in ("read", "readline", "readlines", "fileno",
Christian Heimes9bd667a2008-01-20 15:14:11 +0000113 "close", "info", "geturl", "getcode", "__iter__"):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000114 self.assertTrue(hasattr(self.returned_obj, attr),
Brett Cannon74bfd702003-04-25 09:39:47 +0000115 "object returned by urlopen() lacks %s attribute" %
116 attr)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000117
Brett Cannon74bfd702003-04-25 09:39:47 +0000118 def test_read(self):
119 self.assertEqual(self.text, self.returned_obj.read())
Skip Montanaro080c9972001-01-28 21:12:22 +0000120
Brett Cannon74bfd702003-04-25 09:39:47 +0000121 def test_readline(self):
122 self.assertEqual(self.text, self.returned_obj.readline())
Guido van Rossuma0982942007-07-10 08:30:03 +0000123 self.assertEqual(b'', self.returned_obj.readline(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000124 "calling readline() after exhausting the file did not"
125 " return an empty string")
Skip Montanaro080c9972001-01-28 21:12:22 +0000126
Brett Cannon74bfd702003-04-25 09:39:47 +0000127 def test_readlines(self):
128 lines_list = self.returned_obj.readlines()
129 self.assertEqual(len(lines_list), 1,
130 "readlines() returned the wrong number of lines")
131 self.assertEqual(lines_list[0], self.text,
132 "readlines() returned improper text")
Skip Montanaro080c9972001-01-28 21:12:22 +0000133
Brett Cannon74bfd702003-04-25 09:39:47 +0000134 def test_fileno(self):
135 file_num = self.returned_obj.fileno()
Ezio Melottie9615932010-01-24 19:26:24 +0000136 self.assertIsInstance(file_num, int, "fileno() did not return an int")
Brett Cannon74bfd702003-04-25 09:39:47 +0000137 self.assertEqual(os.read(file_num, len(self.text)), self.text,
138 "Reading on the file descriptor returned by fileno() "
139 "did not return the expected text")
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000140
Brett Cannon74bfd702003-04-25 09:39:47 +0000141 def test_close(self):
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800142 # Test close() by calling it here and then having it be called again
Brett Cannon74bfd702003-04-25 09:39:47 +0000143 # by the tearDown() method for the test
144 self.returned_obj.close()
Skip Montanaro080c9972001-01-28 21:12:22 +0000145
Brett Cannon74bfd702003-04-25 09:39:47 +0000146 def test_info(self):
Ezio Melottie9615932010-01-24 19:26:24 +0000147 self.assertIsInstance(self.returned_obj.info(), email.message.Message)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000148
Brett Cannon74bfd702003-04-25 09:39:47 +0000149 def test_geturl(self):
150 self.assertEqual(self.returned_obj.geturl(), self.pathname)
Skip Montanaro080c9972001-01-28 21:12:22 +0000151
Christian Heimes9bd667a2008-01-20 15:14:11 +0000152 def test_getcode(self):
Florent Xicluna419e3842010-08-08 16:16:07 +0000153 self.assertIsNone(self.returned_obj.getcode())
Christian Heimes9bd667a2008-01-20 15:14:11 +0000154
Brett Cannon74bfd702003-04-25 09:39:47 +0000155 def test_iter(self):
156 # Test iterator
157 # Don't need to count number of iterations since test would fail the
158 # instant it returned anything beyond the first line from the
Raymond Hettinger038018a2011-06-26 14:29:35 +0200159 # comparison.
160 # Use the iterator in the usual implicit way to test for ticket #4608.
161 for line in self.returned_obj:
Brett Cannon74bfd702003-04-25 09:39:47 +0000162 self.assertEqual(line, self.text)
Skip Montanaro080c9972001-01-28 21:12:22 +0000163
Senthil Kumaran3800ea92012-01-21 11:52:48 +0800164 def test_relativelocalfile(self):
165 self.assertRaises(ValueError,urllib.request.urlopen,'./' + self.pathname)
166
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000167class ProxyTests(unittest.TestCase):
168
169 def setUp(self):
Walter Dörwaldb525e182009-04-26 21:39:21 +0000170 # Records changes to env vars
171 self.env = support.EnvironmentVarGuard()
Benjamin Peterson46a99002010-01-09 18:45:30 +0000172 # Delete all proxy related env vars
Antoine Pitroub3a88b52010-10-14 18:31:39 +0000173 for k in list(os.environ):
Antoine Pitrou8c8f1ac2010-10-14 18:32:54 +0000174 if 'proxy' in k.lower():
Benjamin Peterson46a99002010-01-09 18:45:30 +0000175 self.env.unset(k)
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000176
177 def tearDown(self):
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000178 # Restore all proxy related env vars
Walter Dörwaldb525e182009-04-26 21:39:21 +0000179 self.env.__exit__()
180 del self.env
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000181
182 def test_getproxies_environment_keep_no_proxies(self):
Walter Dörwaldb525e182009-04-26 21:39:21 +0000183 self.env.set('NO_PROXY', 'localhost')
184 proxies = urllib.request.getproxies_environment()
185 # getproxies_environment use lowered case truncated (no '_proxy') keys
Florent Xicluna419e3842010-08-08 16:16:07 +0000186 self.assertEqual('localhost', proxies['no'])
Senthil Kumaran89976f12011-08-06 12:27:40 +0800187 # List of no_proxies with space.
188 self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
189 self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com'))
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000190
Senthil Kumarance260142011-11-01 01:35:17 +0800191class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin):
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000192 """Test urlopen() opening a fake http connection."""
193
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000194 def check_read(self, ver):
195 self.fakehttp(b"HTTP/" + ver + b" 200 OK\r\n\r\nHello!")
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000196 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000197 fp = urlopen("http://python.org/")
Jeremy Hylton66dc8c52007-08-04 03:42:26 +0000198 self.assertEqual(fp.readline(), b"Hello!")
199 self.assertEqual(fp.readline(), b"")
Christian Heimes9bd667a2008-01-20 15:14:11 +0000200 self.assertEqual(fp.geturl(), 'http://python.org/')
201 self.assertEqual(fp.getcode(), 200)
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000202 finally:
203 self.unfakehttp()
204
Senthil Kumaran26430412011-04-13 07:01:19 +0800205 def test_url_fragment(self):
206 # Issue #11703: geturl() omits fragments in the original URL.
207 url = 'http://docs.python.org/library/urllib.html#OK'
Senthil Kumaranb17abb12011-04-13 07:22:29 +0800208 self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
Senthil Kumaran26430412011-04-13 07:01:19 +0800209 try:
210 fp = urllib.request.urlopen(url)
211 self.assertEqual(fp.geturl(), url)
212 finally:
213 self.unfakehttp()
214
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800215 def test_willclose(self):
216 self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
Senthil Kumaranacbaa922011-03-20 05:30:16 +0800217 try:
218 resp = urlopen("http://www.python.org")
219 self.assertTrue(resp.fp.will_close)
220 finally:
221 self.unfakehttp()
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800222
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000223 def test_read_0_9(self):
224 # "0.9" response accepted (but not "simple responses" without
225 # a status line)
226 self.check_read(b"0.9")
227
228 def test_read_1_0(self):
229 self.check_read(b"1.0")
230
231 def test_read_1_1(self):
232 self.check_read(b"1.1")
233
Christian Heimes57dddfb2008-01-02 18:30:52 +0000234 def test_read_bogus(self):
235 # urlopen() should raise IOError for many error codes.
236 self.fakehttp(b'''HTTP/1.1 401 Authentication Required
237Date: Wed, 02 Jan 2008 03:03:54 GMT
238Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
239Connection: close
240Content-Type: text/html; charset=iso-8859-1
241''')
242 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000243 self.assertRaises(IOError, urlopen, "http://python.org/")
Christian Heimes57dddfb2008-01-02 18:30:52 +0000244 finally:
245 self.unfakehttp()
246
guido@google.coma119df92011-03-29 11:41:02 -0700247 def test_invalid_redirect(self):
248 # urlopen() should raise IOError for many error codes.
249 self.fakehttp(b'''HTTP/1.1 302 Found
250Date: Wed, 02 Jan 2008 03:03:54 GMT
251Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
252Location: file://guidocomputer.athome.com:/python/license
253Connection: close
254Content-Type: text/html; charset=iso-8859-1
255''')
256 try:
257 self.assertRaises(urllib.error.HTTPError, urlopen,
258 "http://python.org/")
259 finally:
260 self.unfakehttp()
261
Guido van Rossumd8faa362007-04-27 19:54:29 +0000262 def test_empty_socket(self):
Jeremy Hylton66dc8c52007-08-04 03:42:26 +0000263 # urlopen() raises IOError if the underlying socket does not send any
264 # data. (#1680230)
Christian Heimes57dddfb2008-01-02 18:30:52 +0000265 self.fakehttp(b'')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000266 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000267 self.assertRaises(IOError, urlopen, "http://something")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000268 finally:
269 self.unfakehttp()
270
Senthil Kumarancad7b312012-10-27 02:26:46 -0700271 def test_missing_localfile(self):
272 # Test for #10836
273 with self.assertRaises(urllib.error.URLError) as e:
274 urlopen('file://localhost/a/file/which/doesnot/exists.py')
275 self.assertTrue(e.exception.filename)
276 self.assertTrue(e.exception.reason)
277
278 def test_file_notexists(self):
279 fd, tmp_file = tempfile.mkstemp()
280 tmp_fileurl = 'file://localhost/' + tmp_file.replace(os.path.sep, '/')
281 try:
282 self.assertTrue(os.path.exists(tmp_file))
283 with urlopen(tmp_fileurl) as fobj:
284 self.assertTrue(fobj)
285 finally:
286 os.close(fd)
287 os.unlink(tmp_file)
288 self.assertFalse(os.path.exists(tmp_file))
289 with self.assertRaises(urllib.error.URLError):
290 urlopen(tmp_fileurl)
291
292 def test_ftp_nohost(self):
293 test_ftp_url = 'ftp:///path'
294 with self.assertRaises(urllib.error.URLError) as e:
295 urlopen(test_ftp_url)
296 self.assertFalse(e.exception.filename)
297 self.assertTrue(e.exception.reason)
298
299 def test_ftp_nonexisting(self):
300 with self.assertRaises(urllib.error.URLError) as e:
301 urlopen('ftp://localhost/a/file/which/doesnot/exists.py')
302 self.assertFalse(e.exception.filename)
303 self.assertTrue(e.exception.reason)
304
305
Senthil Kumarande0eb242010-08-01 17:53:37 +0000306 def test_userpass_inurl(self):
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000307 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
Senthil Kumarande0eb242010-08-01 17:53:37 +0000308 try:
309 fp = urlopen("http://user:pass@python.org/")
310 self.assertEqual(fp.readline(), b"Hello!")
311 self.assertEqual(fp.readline(), b"")
312 self.assertEqual(fp.geturl(), 'http://user:pass@python.org/')
313 self.assertEqual(fp.getcode(), 200)
314 finally:
315 self.unfakehttp()
316
Senthil Kumaranc5c5a142012-01-14 19:09:04 +0800317 def test_userpass_inurl_w_spaces(self):
318 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
319 try:
320 userpass = "a b:c d"
321 url = "http://{}@python.org/".format(userpass)
322 fakehttp_wrapper = http.client.HTTPConnection
323 authorization = ("Authorization: Basic %s\r\n" %
324 b64encode(userpass.encode("ASCII")).decode("ASCII"))
325 fp = urlopen(url)
326 # The authorization header must be in place
327 self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8"))
328 self.assertEqual(fp.readline(), b"Hello!")
329 self.assertEqual(fp.readline(), b"")
330 # the spaces are quoted in URL so no match
331 self.assertNotEqual(fp.geturl(), url)
332 self.assertEqual(fp.getcode(), 200)
333 finally:
334 self.unfakehttp()
335
Brett Cannon19691362003-04-29 05:08:06 +0000336class urlretrieve_FileTests(unittest.TestCase):
Brett Cannon74bfd702003-04-25 09:39:47 +0000337 """Test urllib.urlretrieve() on local files"""
Skip Montanaro080c9972001-01-28 21:12:22 +0000338
Brett Cannon19691362003-04-29 05:08:06 +0000339 def setUp(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000340 # Create a list of temporary files. Each item in the list is a file
341 # name (absolute path or relative to the current working directory).
342 # All files in this list will be deleted in the tearDown method. Note,
343 # this only helps to makes sure temporary files get deleted, but it
344 # does nothing about trying to close files that may still be open. It
345 # is the responsibility of the developer to properly close files even
346 # when exceptional conditions occur.
347 self.tempFiles = []
348
Brett Cannon19691362003-04-29 05:08:06 +0000349 # Create a temporary file.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000350 self.registerFileForCleanUp(support.TESTFN)
Guido van Rossuma0982942007-07-10 08:30:03 +0000351 self.text = b'testing urllib.urlretrieve'
Georg Brandl5a650a22005-08-26 08:51:34 +0000352 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000353 FILE = open(support.TESTFN, 'wb')
Georg Brandl5a650a22005-08-26 08:51:34 +0000354 FILE.write(self.text)
355 FILE.close()
356 finally:
357 try: FILE.close()
358 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000359
360 def tearDown(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000361 # Delete the temporary files.
362 for each in self.tempFiles:
363 try: os.remove(each)
364 except: pass
365
366 def constructLocalFileUrl(self, filePath):
Victor Stinner6c6f8512010-08-07 10:09:35 +0000367 filePath = os.path.abspath(filePath)
368 try:
369 filePath.encode("utf8")
370 except UnicodeEncodeError:
371 raise unittest.SkipTest("filePath is not encodable to utf8")
372 return "file://%s" % urllib.request.pathname2url(filePath)
Georg Brandl5a650a22005-08-26 08:51:34 +0000373
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000374 def createNewTempFile(self, data=b""):
Georg Brandl5a650a22005-08-26 08:51:34 +0000375 """Creates a new temporary file containing the specified data,
376 registers the file for deletion during the test fixture tear down, and
377 returns the absolute path of the file."""
378
379 newFd, newFilePath = tempfile.mkstemp()
380 try:
381 self.registerFileForCleanUp(newFilePath)
382 newFile = os.fdopen(newFd, "wb")
383 newFile.write(data)
384 newFile.close()
385 finally:
386 try: newFile.close()
387 except: pass
388 return newFilePath
389
390 def registerFileForCleanUp(self, fileName):
391 self.tempFiles.append(fileName)
Brett Cannon19691362003-04-29 05:08:06 +0000392
393 def test_basic(self):
394 # Make sure that a local file just gets its own location returned and
395 # a headers value is returned.
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000396 result = urllib.request.urlretrieve("file:%s" % support.TESTFN)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000397 self.assertEqual(result[0], support.TESTFN)
Ezio Melottie9615932010-01-24 19:26:24 +0000398 self.assertIsInstance(result[1], email.message.Message,
399 "did not get a email.message.Message instance "
400 "as second returned value")
Brett Cannon19691362003-04-29 05:08:06 +0000401
402 def test_copy(self):
403 # Test that setting the filename argument works.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000404 second_temp = "%s.2" % support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000405 self.registerFileForCleanUp(second_temp)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000406 result = urllib.request.urlretrieve(self.constructLocalFileUrl(
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000407 support.TESTFN), second_temp)
Brett Cannon19691362003-04-29 05:08:06 +0000408 self.assertEqual(second_temp, result[0])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000409 self.assertTrue(os.path.exists(second_temp), "copy of the file was not "
Brett Cannon19691362003-04-29 05:08:06 +0000410 "made")
Alex Martelli01c77c62006-08-24 02:58:11 +0000411 FILE = open(second_temp, 'rb')
Brett Cannon19691362003-04-29 05:08:06 +0000412 try:
413 text = FILE.read()
Brett Cannon19691362003-04-29 05:08:06 +0000414 FILE.close()
Georg Brandl5a650a22005-08-26 08:51:34 +0000415 finally:
416 try: FILE.close()
417 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000418 self.assertEqual(self.text, text)
419
420 def test_reporthook(self):
421 # Make sure that the reporthook works.
422 def hooktester(count, block_size, total_size, count_holder=[0]):
Ezio Melottie9615932010-01-24 19:26:24 +0000423 self.assertIsInstance(count, int)
424 self.assertIsInstance(block_size, int)
425 self.assertIsInstance(total_size, int)
Brett Cannon19691362003-04-29 05:08:06 +0000426 self.assertEqual(count, count_holder[0])
427 count_holder[0] = count_holder[0] + 1
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000428 second_temp = "%s.2" % support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000429 self.registerFileForCleanUp(second_temp)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000430 urllib.request.urlretrieve(
431 self.constructLocalFileUrl(support.TESTFN),
Georg Brandl5a650a22005-08-26 08:51:34 +0000432 second_temp, hooktester)
433
434 def test_reporthook_0_bytes(self):
435 # Test on zero length file. Should call reporthook only 1 time.
436 report = []
437 def hooktester(count, block_size, total_size, _report=report):
438 _report.append((count, block_size, total_size))
439 srcFileName = self.createNewTempFile()
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000440 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000441 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000442 self.assertEqual(len(report), 1)
443 self.assertEqual(report[0][2], 0)
444
445 def test_reporthook_5_bytes(self):
446 # Test on 5 byte file. Should call reporthook only 2 times (once when
447 # the "network connection" is established and once when the block is
448 # read). Since the block size is 8192 bytes, only one block read is
449 # required to read the entire file.
450 report = []
451 def hooktester(count, block_size, total_size, _report=report):
452 _report.append((count, block_size, total_size))
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000453 srcFileName = self.createNewTempFile(b"x" * 5)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000454 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000455 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000456 self.assertEqual(len(report), 2)
457 self.assertEqual(report[0][1], 8192)
458 self.assertEqual(report[0][2], 5)
459
460 def test_reporthook_8193_bytes(self):
461 # Test on 8193 byte file. Should call reporthook only 3 times (once
462 # when the "network connection" is established, once for the next 8192
463 # bytes, and once for the last byte).
464 report = []
465 def hooktester(count, block_size, total_size, _report=report):
466 _report.append((count, block_size, total_size))
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000467 srcFileName = self.createNewTempFile(b"x" * 8193)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000468 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000469 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000470 self.assertEqual(len(report), 3)
471 self.assertEqual(report[0][1], 8192)
472 self.assertEqual(report[0][2], 8193)
Skip Montanaro080c9972001-01-28 21:12:22 +0000473
Senthil Kumarance260142011-11-01 01:35:17 +0800474
475class urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin):
476 """Test urllib.urlretrieve() using fake http connections"""
477
478 def test_short_content_raises_ContentTooShortError(self):
479 self.fakehttp(b'''HTTP/1.1 200 OK
480Date: Wed, 02 Jan 2008 03:03:54 GMT
481Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
482Connection: close
483Content-Length: 100
484Content-Type: text/html; charset=iso-8859-1
485
486FF
487''')
488
489 def _reporthook(par1, par2, par3):
490 pass
491
492 with self.assertRaises(urllib.error.ContentTooShortError):
493 try:
494 urllib.request.urlretrieve('http://example.com/',
495 reporthook=_reporthook)
496 finally:
497 self.unfakehttp()
498
499 def test_short_content_raises_ContentTooShortError_without_reporthook(self):
500 self.fakehttp(b'''HTTP/1.1 200 OK
501Date: Wed, 02 Jan 2008 03:03:54 GMT
502Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
503Connection: close
504Content-Length: 100
505Content-Type: text/html; charset=iso-8859-1
506
507FF
508''')
509 with self.assertRaises(urllib.error.ContentTooShortError):
510 try:
511 urllib.request.urlretrieve('http://example.com/')
512 finally:
513 self.unfakehttp()
514
515
Brett Cannon74bfd702003-04-25 09:39:47 +0000516class QuotingTests(unittest.TestCase):
517 """Tests for urllib.quote() and urllib.quote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000518
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000519 According to RFC 2396 (Uniform Resource Identifiers), to escape a
520 character you write it as '%' + <2 character US-ASCII hex value>.
521 The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a
522 character properly. Case does not matter on the hex letters.
Brett Cannon74bfd702003-04-25 09:39:47 +0000523
524 The various character sets specified are:
Tim Petersc2659cf2003-05-12 20:19:37 +0000525
Brett Cannon74bfd702003-04-25 09:39:47 +0000526 Reserved characters : ";/?:@&=+$,"
527 Have special meaning in URIs and must be escaped if not being used for
528 their special meaning
529 Data characters : letters, digits, and "-_.!~*'()"
530 Unreserved and do not need to be escaped; can be, though, if desired
531 Control characters : 0x00 - 0x1F, 0x7F
532 Have no use in URIs so must be escaped
533 space : 0x20
534 Must be escaped
535 Delimiters : '<>#%"'
536 Must be escaped
537 Unwise : "{}|\^[]`"
538 Must be escaped
Tim Petersc2659cf2003-05-12 20:19:37 +0000539
Brett Cannon74bfd702003-04-25 09:39:47 +0000540 """
541
542 def test_never_quote(self):
543 # Make sure quote() does not quote letters, digits, and "_,.-"
544 do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
545 "abcdefghijklmnopqrstuvwxyz",
546 "0123456789",
547 "_.-"])
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000548 result = urllib.parse.quote(do_not_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000549 self.assertEqual(do_not_quote, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000550 "using quote(): %r != %r" % (do_not_quote, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000551 result = urllib.parse.quote_plus(do_not_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000552 self.assertEqual(do_not_quote, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000553 "using quote_plus(): %r != %r" % (do_not_quote, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000554
555 def test_default_safe(self):
556 # Test '/' is default value for 'safe' parameter
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000557 self.assertEqual(urllib.parse.quote.__defaults__[0], '/')
Brett Cannon74bfd702003-04-25 09:39:47 +0000558
559 def test_safe(self):
560 # Test setting 'safe' parameter does what it should do
561 quote_by_default = "<>"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000562 result = urllib.parse.quote(quote_by_default, safe=quote_by_default)
Brett Cannon74bfd702003-04-25 09:39:47 +0000563 self.assertEqual(quote_by_default, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000564 "using quote(): %r != %r" % (quote_by_default, result))
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000565 result = urllib.parse.quote_plus(quote_by_default,
566 safe=quote_by_default)
Brett Cannon74bfd702003-04-25 09:39:47 +0000567 self.assertEqual(quote_by_default, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000568 "using quote_plus(): %r != %r" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000569 (quote_by_default, result))
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000570 # Safe expressed as bytes rather than str
571 result = urllib.parse.quote(quote_by_default, safe=b"<>")
572 self.assertEqual(quote_by_default, result,
573 "using quote(): %r != %r" % (quote_by_default, result))
574 # "Safe" non-ASCII characters should have no effect
575 # (Since URIs are not allowed to have non-ASCII characters)
576 result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="\xfc")
577 expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="")
578 self.assertEqual(expect, result,
579 "using quote(): %r != %r" %
580 (expect, result))
581 # Same as above, but using a bytes rather than str
582 result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe=b"\xfc")
583 expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="")
584 self.assertEqual(expect, result,
585 "using quote(): %r != %r" %
586 (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000587
588 def test_default_quoting(self):
589 # Make sure all characters that should be quoted are by default sans
590 # space (separate test for that).
591 should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
592 should_quote.append('<>#%"{}|\^[]`')
593 should_quote.append(chr(127)) # For 0x7F
594 should_quote = ''.join(should_quote)
595 for char in should_quote:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000596 result = urllib.parse.quote(char)
Brett Cannon74bfd702003-04-25 09:39:47 +0000597 self.assertEqual(hexescape(char), result,
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000598 "using quote(): "
599 "%s should be escaped to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000600 (char, hexescape(char), result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000601 result = urllib.parse.quote_plus(char)
Brett Cannon74bfd702003-04-25 09:39:47 +0000602 self.assertEqual(hexescape(char), result,
603 "using quote_plus(): "
Tim Petersc2659cf2003-05-12 20:19:37 +0000604 "%s should be escapes to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000605 (char, hexescape(char), result))
606 del should_quote
607 partial_quote = "ab[]cd"
608 expected = "ab%5B%5Dcd"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000609 result = urllib.parse.quote(partial_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000610 self.assertEqual(expected, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000611 "using quote(): %r != %r" % (expected, result))
Senthil Kumaran305a68e2011-09-13 06:40:27 +0800612 result = urllib.parse.quote_plus(partial_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000613 self.assertEqual(expected, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000614 "using quote_plus(): %r != %r" % (expected, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000615
616 def test_quoting_space(self):
617 # Make sure quote() and quote_plus() handle spaces as specified in
618 # their unique way
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000619 result = urllib.parse.quote(' ')
Brett Cannon74bfd702003-04-25 09:39:47 +0000620 self.assertEqual(result, hexescape(' '),
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000621 "using quote(): %r != %r" % (result, hexescape(' ')))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000622 result = urllib.parse.quote_plus(' ')
Brett Cannon74bfd702003-04-25 09:39:47 +0000623 self.assertEqual(result, '+',
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000624 "using quote_plus(): %r != +" % result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000625 given = "a b cd e f"
626 expect = given.replace(' ', hexescape(' '))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000627 result = urllib.parse.quote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000628 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000629 "using quote(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000630 expect = given.replace(' ', '+')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000631 result = urllib.parse.quote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000632 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000633 "using quote_plus(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000634
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000635 def test_quoting_plus(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000636 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma'),
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000637 'alpha%2Bbeta+gamma')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000638 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', '+'),
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000639 'alpha+beta+gamma')
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000640 # Test with bytes
641 self.assertEqual(urllib.parse.quote_plus(b'alpha+beta gamma'),
642 'alpha%2Bbeta+gamma')
643 # Test with safe bytes
644 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', b'+'),
645 'alpha+beta+gamma')
646
647 def test_quote_bytes(self):
648 # Bytes should quote directly to percent-encoded values
649 given = b"\xa2\xd8ab\xff"
650 expect = "%A2%D8ab%FF"
651 result = urllib.parse.quote(given)
652 self.assertEqual(expect, result,
653 "using quote(): %r != %r" % (expect, result))
654 # Encoding argument should raise type error on bytes input
655 self.assertRaises(TypeError, urllib.parse.quote, given,
656 encoding="latin-1")
657 # quote_from_bytes should work the same
658 result = urllib.parse.quote_from_bytes(given)
659 self.assertEqual(expect, result,
660 "using quote_from_bytes(): %r != %r"
661 % (expect, result))
662
663 def test_quote_with_unicode(self):
664 # Characters in Latin-1 range, encoded by default in UTF-8
665 given = "\xa2\xd8ab\xff"
666 expect = "%C2%A2%C3%98ab%C3%BF"
667 result = urllib.parse.quote(given)
668 self.assertEqual(expect, result,
669 "using quote(): %r != %r" % (expect, result))
670 # Characters in Latin-1 range, encoded by with None (default)
671 result = urllib.parse.quote(given, encoding=None, errors=None)
672 self.assertEqual(expect, result,
673 "using quote(): %r != %r" % (expect, result))
674 # Characters in Latin-1 range, encoded with Latin-1
675 given = "\xa2\xd8ab\xff"
676 expect = "%A2%D8ab%FF"
677 result = urllib.parse.quote(given, encoding="latin-1")
678 self.assertEqual(expect, result,
679 "using quote(): %r != %r" % (expect, result))
680 # Characters in BMP, encoded by default in UTF-8
681 given = "\u6f22\u5b57" # "Kanji"
682 expect = "%E6%BC%A2%E5%AD%97"
683 result = urllib.parse.quote(given)
684 self.assertEqual(expect, result,
685 "using quote(): %r != %r" % (expect, result))
686 # Characters in BMP, encoded with Latin-1
687 given = "\u6f22\u5b57"
688 self.assertRaises(UnicodeEncodeError, urllib.parse.quote, given,
689 encoding="latin-1")
690 # Characters in BMP, encoded with Latin-1, with replace error handling
691 given = "\u6f22\u5b57"
692 expect = "%3F%3F" # "??"
693 result = urllib.parse.quote(given, encoding="latin-1",
694 errors="replace")
695 self.assertEqual(expect, result,
696 "using quote(): %r != %r" % (expect, result))
697 # Characters in BMP, Latin-1, with xmlcharref error handling
698 given = "\u6f22\u5b57"
699 expect = "%26%2328450%3B%26%2323383%3B" # "&#28450;&#23383;"
700 result = urllib.parse.quote(given, encoding="latin-1",
701 errors="xmlcharrefreplace")
702 self.assertEqual(expect, result,
703 "using quote(): %r != %r" % (expect, result))
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000704
Georg Brandlfaf41492009-05-26 18:31:11 +0000705 def test_quote_plus_with_unicode(self):
706 # Encoding (latin-1) test for quote_plus
707 given = "\xa2\xd8 \xff"
708 expect = "%A2%D8+%FF"
709 result = urllib.parse.quote_plus(given, encoding="latin-1")
710 self.assertEqual(expect, result,
711 "using quote_plus(): %r != %r" % (expect, result))
712 # Errors test for quote_plus
713 given = "ab\u6f22\u5b57 cd"
714 expect = "ab%3F%3F+cd"
715 result = urllib.parse.quote_plus(given, encoding="latin-1",
716 errors="replace")
717 self.assertEqual(expect, result,
718 "using quote_plus(): %r != %r" % (expect, result))
719
Senthil Kumarand496c4c2010-07-30 19:34:36 +0000720
Brett Cannon74bfd702003-04-25 09:39:47 +0000721class UnquotingTests(unittest.TestCase):
722 """Tests for unquote() and unquote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000723
Brett Cannon74bfd702003-04-25 09:39:47 +0000724 See the doc string for quoting_Tests for details on quoting and such.
725
726 """
727
728 def test_unquoting(self):
729 # Make sure unquoting of all ASCII values works
730 escape_list = []
731 for num in range(128):
732 given = hexescape(chr(num))
733 expect = chr(num)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000734 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000735 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000736 "using unquote(): %r != %r" % (expect, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000737 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000738 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000739 "using unquote_plus(): %r != %r" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000740 (expect, result))
741 escape_list.append(given)
742 escape_string = ''.join(escape_list)
743 del escape_list
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000744 result = urllib.parse.unquote(escape_string)
Brett Cannon74bfd702003-04-25 09:39:47 +0000745 self.assertEqual(result.count('%'), 1,
Brett Cannon74bfd702003-04-25 09:39:47 +0000746 "using unquote(): not all characters escaped: "
747 "%s" % result)
Georg Brandl604ef372010-07-31 08:20:02 +0000748 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None)
749 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ())
Florent Xicluna62829dc2010-08-14 20:51:58 +0000750 with support.check_warnings(('', BytesWarning), quiet=True):
751 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, b'')
Brett Cannon74bfd702003-04-25 09:39:47 +0000752
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000753 def test_unquoting_badpercent(self):
754 # Test unquoting on bad percent-escapes
755 given = '%xab'
756 expect = given
757 result = urllib.parse.unquote(given)
758 self.assertEqual(expect, result, "using unquote(): %r != %r"
759 % (expect, result))
760 given = '%x'
761 expect = given
762 result = urllib.parse.unquote(given)
763 self.assertEqual(expect, result, "using unquote(): %r != %r"
764 % (expect, result))
765 given = '%'
766 expect = given
767 result = urllib.parse.unquote(given)
768 self.assertEqual(expect, result, "using unquote(): %r != %r"
769 % (expect, result))
770 # unquote_to_bytes
771 given = '%xab'
772 expect = bytes(given, 'ascii')
773 result = urllib.parse.unquote_to_bytes(given)
774 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
775 % (expect, result))
776 given = '%x'
777 expect = bytes(given, 'ascii')
778 result = urllib.parse.unquote_to_bytes(given)
779 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
780 % (expect, result))
781 given = '%'
782 expect = bytes(given, 'ascii')
783 result = urllib.parse.unquote_to_bytes(given)
784 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
785 % (expect, result))
Georg Brandl604ef372010-07-31 08:20:02 +0000786 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, None)
787 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, ())
Senthil Kumaran79e17f62010-07-19 18:17:19 +0000788
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000789 def test_unquoting_mixed_case(self):
790 # Test unquoting on mixed-case hex digits in the percent-escapes
791 given = '%Ab%eA'
792 expect = b'\xab\xea'
793 result = urllib.parse.unquote_to_bytes(given)
794 self.assertEqual(expect, result,
795 "using unquote_to_bytes(): %r != %r"
796 % (expect, result))
797
Brett Cannon74bfd702003-04-25 09:39:47 +0000798 def test_unquoting_parts(self):
799 # Make sure unquoting works when have non-quoted characters
800 # interspersed
801 given = 'ab%sd' % hexescape('c')
802 expect = "abcd"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000803 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000804 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000805 "using quote(): %r != %r" % (expect, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000806 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000807 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000808 "using unquote_plus(): %r != %r" % (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +0000809
Brett Cannon74bfd702003-04-25 09:39:47 +0000810 def test_unquoting_plus(self):
811 # Test difference between unquote() and unquote_plus()
812 given = "are+there+spaces..."
813 expect = given
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000814 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000815 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000816 "using unquote(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000817 expect = given.replace('+', ' ')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000818 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000819 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000820 "using unquote_plus(): %r != %r" % (expect, result))
821
822 def test_unquote_to_bytes(self):
823 given = 'br%C3%BCckner_sapporo_20050930.doc'
824 expect = b'br\xc3\xbcckner_sapporo_20050930.doc'
825 result = urllib.parse.unquote_to_bytes(given)
826 self.assertEqual(expect, result,
827 "using unquote_to_bytes(): %r != %r"
828 % (expect, result))
829 # Test on a string with unescaped non-ASCII characters
830 # (Technically an invalid URI; expect those characters to be UTF-8
831 # encoded).
832 result = urllib.parse.unquote_to_bytes("\u6f22%C3%BC")
833 expect = b'\xe6\xbc\xa2\xc3\xbc' # UTF-8 for "\u6f22\u00fc"
834 self.assertEqual(expect, result,
835 "using unquote_to_bytes(): %r != %r"
836 % (expect, result))
837 # Test with a bytes as input
838 given = b'%A2%D8ab%FF'
839 expect = b'\xa2\xd8ab\xff'
840 result = urllib.parse.unquote_to_bytes(given)
841 self.assertEqual(expect, result,
842 "using unquote_to_bytes(): %r != %r"
843 % (expect, result))
844 # Test with a bytes as input, with unescaped non-ASCII bytes
845 # (Technically an invalid URI; expect those bytes to be preserved)
846 given = b'%A2\xd8ab%FF'
847 expect = b'\xa2\xd8ab\xff'
848 result = urllib.parse.unquote_to_bytes(given)
849 self.assertEqual(expect, result,
850 "using unquote_to_bytes(): %r != %r"
851 % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000852
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000853 def test_unquote_with_unicode(self):
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000854 # Characters in the Latin-1 range, encoded with UTF-8
855 given = 'br%C3%BCckner_sapporo_20050930.doc'
856 expect = 'br\u00fcckner_sapporo_20050930.doc'
857 result = urllib.parse.unquote(given)
858 self.assertEqual(expect, result,
859 "using unquote(): %r != %r" % (expect, result))
860 # Characters in the Latin-1 range, encoded with None (default)
861 result = urllib.parse.unquote(given, encoding=None, errors=None)
862 self.assertEqual(expect, result,
863 "using unquote(): %r != %r" % (expect, result))
864
865 # Characters in the Latin-1 range, encoded with Latin-1
866 result = urllib.parse.unquote('br%FCckner_sapporo_20050930.doc',
867 encoding="latin-1")
868 expect = 'br\u00fcckner_sapporo_20050930.doc'
869 self.assertEqual(expect, result,
870 "using unquote(): %r != %r" % (expect, result))
871
872 # Characters in BMP, encoded with UTF-8
873 given = "%E6%BC%A2%E5%AD%97"
874 expect = "\u6f22\u5b57" # "Kanji"
875 result = urllib.parse.unquote(given)
876 self.assertEqual(expect, result,
877 "using unquote(): %r != %r" % (expect, result))
878
879 # Decode with UTF-8, invalid sequence
880 given = "%F3%B1"
881 expect = "\ufffd" # Replacement character
882 result = urllib.parse.unquote(given)
883 self.assertEqual(expect, result,
884 "using unquote(): %r != %r" % (expect, result))
885
886 # Decode with UTF-8, invalid sequence, replace errors
887 result = urllib.parse.unquote(given, errors="replace")
888 self.assertEqual(expect, result,
889 "using unquote(): %r != %r" % (expect, result))
890
891 # Decode with UTF-8, invalid sequence, ignoring errors
892 given = "%F3%B1"
893 expect = ""
894 result = urllib.parse.unquote(given, errors="ignore")
895 self.assertEqual(expect, result,
896 "using unquote(): %r != %r" % (expect, result))
897
898 # A mix of non-ASCII and percent-encoded characters, UTF-8
899 result = urllib.parse.unquote("\u6f22%C3%BC")
900 expect = '\u6f22\u00fc'
901 self.assertEqual(expect, result,
902 "using unquote(): %r != %r" % (expect, result))
903
904 # A mix of non-ASCII and percent-encoded characters, Latin-1
905 # (Note, the string contains non-Latin-1-representable characters)
906 result = urllib.parse.unquote("\u6f22%FC", encoding="latin-1")
907 expect = '\u6f22\u00fc'
908 self.assertEqual(expect, result,
909 "using unquote(): %r != %r" % (expect, result))
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000910
Brett Cannon74bfd702003-04-25 09:39:47 +0000911class urlencode_Tests(unittest.TestCase):
912 """Tests for urlencode()"""
913
914 def help_inputtype(self, given, test_type):
915 """Helper method for testing different input types.
Tim Petersc2659cf2003-05-12 20:19:37 +0000916
Brett Cannon74bfd702003-04-25 09:39:47 +0000917 'given' must lead to only the pairs:
918 * 1st, 1
919 * 2nd, 2
920 * 3rd, 3
Tim Petersc2659cf2003-05-12 20:19:37 +0000921
Brett Cannon74bfd702003-04-25 09:39:47 +0000922 Test cannot assume anything about order. Docs make no guarantee and
923 have possible dictionary input.
Tim Petersc2659cf2003-05-12 20:19:37 +0000924
Brett Cannon74bfd702003-04-25 09:39:47 +0000925 """
926 expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000927 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000928 for expected in expect_somewhere:
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000929 self.assertIn(expected, result,
Brett Cannon74bfd702003-04-25 09:39:47 +0000930 "testing %s: %s not found in %s" %
931 (test_type, expected, result))
932 self.assertEqual(result.count('&'), 2,
933 "testing %s: expected 2 '&'s; got %s" %
934 (test_type, result.count('&')))
935 amp_location = result.index('&')
936 on_amp_left = result[amp_location - 1]
937 on_amp_right = result[amp_location + 1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000938 self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000939 "testing %s: '&' not located in proper place in %s" %
940 (test_type, result))
941 self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
942 "testing %s: "
943 "unexpected number of characters: %s != %s" %
944 (test_type, len(result), (5 * 3) + 2))
945
946 def test_using_mapping(self):
947 # Test passing in a mapping object as an argument.
948 self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
949 "using dict as input type")
950
951 def test_using_sequence(self):
952 # Test passing in a sequence of two-item sequences as an argument.
953 self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
954 "using sequence of two-item tuples as input")
955
956 def test_quoting(self):
957 # Make sure keys and values are quoted using quote_plus()
958 given = {"&":"="}
959 expect = "%s=%s" % (hexescape('&'), hexescape('='))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000960 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000961 self.assertEqual(expect, result)
962 given = {"key name":"A bunch of pluses"}
963 expect = "key+name=A+bunch+of+pluses"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000964 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000965 self.assertEqual(expect, result)
966
967 def test_doseq(self):
968 # Test that passing True for 'doseq' parameter works correctly
969 given = {'sequence':['1', '2', '3']}
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000970 expect = "sequence=%s" % urllib.parse.quote_plus(str(['1', '2', '3']))
971 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000972 self.assertEqual(expect, result)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000973 result = urllib.parse.urlencode(given, True)
Brett Cannon74bfd702003-04-25 09:39:47 +0000974 for value in given["sequence"]:
975 expect = "sequence=%s" % value
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000976 self.assertIn(expect, result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000977 self.assertEqual(result.count('&'), 2,
978 "Expected 2 '&'s, got %s" % result.count('&'))
979
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000980 def test_empty_sequence(self):
981 self.assertEqual("", urllib.parse.urlencode({}))
982 self.assertEqual("", urllib.parse.urlencode([]))
983
984 def test_nonstring_values(self):
985 self.assertEqual("a=1", urllib.parse.urlencode({"a": 1}))
986 self.assertEqual("a=None", urllib.parse.urlencode({"a": None}))
987
988 def test_nonstring_seq_values(self):
989 self.assertEqual("a=1&a=2", urllib.parse.urlencode({"a": [1, 2]}, True))
990 self.assertEqual("a=None&a=a",
991 urllib.parse.urlencode({"a": [None, "a"]}, True))
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100992 data = collections.OrderedDict([("a", 1), ("b", 1)])
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000993 self.assertEqual("a=a&a=b",
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100994 urllib.parse.urlencode({"a": data}, True))
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000995
Senthil Kumarandf022da2010-07-03 17:48:22 +0000996 def test_urlencode_encoding(self):
997 # ASCII encoding. Expect %3F with errors="replace'
998 given = (('\u00a0', '\u00c1'),)
999 expect = '%3F=%3F'
1000 result = urllib.parse.urlencode(given, encoding="ASCII", errors="replace")
1001 self.assertEqual(expect, result)
1002
1003 # Default is UTF-8 encoding.
1004 given = (('\u00a0', '\u00c1'),)
1005 expect = '%C2%A0=%C3%81'
1006 result = urllib.parse.urlencode(given)
1007 self.assertEqual(expect, result)
1008
1009 # Latin-1 encoding.
1010 given = (('\u00a0', '\u00c1'),)
1011 expect = '%A0=%C1'
1012 result = urllib.parse.urlencode(given, encoding="latin-1")
1013 self.assertEqual(expect, result)
1014
1015 def test_urlencode_encoding_doseq(self):
1016 # ASCII Encoding. Expect %3F with errors="replace'
1017 given = (('\u00a0', '\u00c1'),)
1018 expect = '%3F=%3F'
1019 result = urllib.parse.urlencode(given, doseq=True,
1020 encoding="ASCII", errors="replace")
1021 self.assertEqual(expect, result)
1022
1023 # ASCII Encoding. On a sequence of values.
1024 given = (("\u00a0", (1, "\u00c1")),)
1025 expect = '%3F=1&%3F=%3F'
1026 result = urllib.parse.urlencode(given, True,
1027 encoding="ASCII", errors="replace")
1028 self.assertEqual(expect, result)
1029
1030 # Utf-8
1031 given = (("\u00a0", "\u00c1"),)
1032 expect = '%C2%A0=%C3%81'
1033 result = urllib.parse.urlencode(given, True)
1034 self.assertEqual(expect, result)
1035
1036 given = (("\u00a0", (42, "\u00c1")),)
1037 expect = '%C2%A0=42&%C2%A0=%C3%81'
1038 result = urllib.parse.urlencode(given, True)
1039 self.assertEqual(expect, result)
1040
1041 # latin-1
1042 given = (("\u00a0", "\u00c1"),)
1043 expect = '%A0=%C1'
1044 result = urllib.parse.urlencode(given, True, encoding="latin-1")
1045 self.assertEqual(expect, result)
1046
1047 given = (("\u00a0", (42, "\u00c1")),)
1048 expect = '%A0=42&%A0=%C1'
1049 result = urllib.parse.urlencode(given, True, encoding="latin-1")
1050 self.assertEqual(expect, result)
1051
1052 def test_urlencode_bytes(self):
1053 given = ((b'\xa0\x24', b'\xc1\x24'),)
1054 expect = '%A0%24=%C1%24'
1055 result = urllib.parse.urlencode(given)
1056 self.assertEqual(expect, result)
1057 result = urllib.parse.urlencode(given, True)
1058 self.assertEqual(expect, result)
1059
1060 # Sequence of values
1061 given = ((b'\xa0\x24', (42, b'\xc1\x24')),)
1062 expect = '%A0%24=42&%A0%24=%C1%24'
1063 result = urllib.parse.urlencode(given, True)
1064 self.assertEqual(expect, result)
1065
1066 def test_urlencode_encoding_safe_parameter(self):
1067
1068 # Send '$' (\x24) as safe character
1069 # Default utf-8 encoding
1070
1071 given = ((b'\xa0\x24', b'\xc1\x24'),)
1072 result = urllib.parse.urlencode(given, safe=":$")
1073 expect = '%A0$=%C1$'
1074 self.assertEqual(expect, result)
1075
1076 given = ((b'\xa0\x24', b'\xc1\x24'),)
1077 result = urllib.parse.urlencode(given, doseq=True, safe=":$")
1078 expect = '%A0$=%C1$'
1079 self.assertEqual(expect, result)
1080
1081 # Safe parameter in sequence
1082 given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
1083 expect = '%A0$=%C1$&%A0$=13&%A0$=42'
1084 result = urllib.parse.urlencode(given, True, safe=":$")
1085 self.assertEqual(expect, result)
1086
1087 # Test all above in latin-1 encoding
1088
1089 given = ((b'\xa0\x24', b'\xc1\x24'),)
1090 result = urllib.parse.urlencode(given, safe=":$",
1091 encoding="latin-1")
1092 expect = '%A0$=%C1$'
1093 self.assertEqual(expect, result)
1094
1095 given = ((b'\xa0\x24', b'\xc1\x24'),)
1096 expect = '%A0$=%C1$'
1097 result = urllib.parse.urlencode(given, doseq=True, safe=":$",
1098 encoding="latin-1")
1099
1100 given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
1101 expect = '%A0$=%C1$&%A0$=13&%A0$=42'
1102 result = urllib.parse.urlencode(given, True, safe=":$",
1103 encoding="latin-1")
1104 self.assertEqual(expect, result)
1105
Brett Cannon74bfd702003-04-25 09:39:47 +00001106class Pathname_Tests(unittest.TestCase):
1107 """Test pathname2url() and url2pathname()"""
1108
1109 def test_basic(self):
1110 # Make sure simple tests pass
1111 expected_path = os.path.join("parts", "of", "a", "path")
1112 expected_url = "parts/of/a/path"
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001113 result = urllib.request.pathname2url(expected_path)
Brett Cannon74bfd702003-04-25 09:39:47 +00001114 self.assertEqual(expected_url, result,
1115 "pathname2url() failed; %s != %s" %
1116 (result, expected_url))
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001117 result = urllib.request.url2pathname(expected_url)
Brett Cannon74bfd702003-04-25 09:39:47 +00001118 self.assertEqual(expected_path, result,
1119 "url2pathame() failed; %s != %s" %
1120 (result, expected_path))
1121
1122 def test_quoting(self):
1123 # Test automatic quoting and unquoting works for pathnam2url() and
1124 # url2pathname() respectively
1125 given = os.path.join("needs", "quot=ing", "here")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001126 expect = "needs/%s/here" % urllib.parse.quote("quot=ing")
1127 result = urllib.request.pathname2url(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001128 self.assertEqual(expect, result,
1129 "pathname2url() failed; %s != %s" %
1130 (expect, result))
1131 expect = given
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001132 result = urllib.request.url2pathname(result)
Brett Cannon74bfd702003-04-25 09:39:47 +00001133 self.assertEqual(expect, result,
1134 "url2pathname() failed; %s != %s" %
1135 (expect, result))
1136 given = os.path.join("make sure", "using_quote")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001137 expect = "%s/using_quote" % urllib.parse.quote("make sure")
1138 result = urllib.request.pathname2url(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001139 self.assertEqual(expect, result,
1140 "pathname2url() failed; %s != %s" %
1141 (expect, result))
1142 given = "make+sure/using_unquote"
1143 expect = os.path.join("make+sure", "using_unquote")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001144 result = urllib.request.url2pathname(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001145 self.assertEqual(expect, result,
1146 "url2pathname() failed; %s != %s" %
1147 (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +00001148
Senthil Kumaran2d2ea1b2011-04-14 13:16:30 +08001149 @unittest.skipUnless(sys.platform == 'win32',
1150 'test specific to the urllib.url2path function.')
1151 def test_ntpath(self):
1152 given = ('/C:/', '///C:/', '/C|//')
1153 expect = 'C:\\'
1154 for url in given:
1155 result = urllib.request.url2pathname(url)
1156 self.assertEqual(expect, result,
1157 'urllib.request..url2pathname() failed; %s != %s' %
1158 (expect, result))
1159 given = '///C|/path'
1160 expect = 'C:\\path'
1161 result = urllib.request.url2pathname(given)
1162 self.assertEqual(expect, result,
1163 'urllib.request.url2pathname() failed; %s != %s' %
1164 (expect, result))
1165
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001166class Utility_Tests(unittest.TestCase):
1167 """Testcase to test the various utility functions in the urllib."""
1168
1169 def test_splitpasswd(self):
1170 """Some of password examples are not sensible, but it is added to
1171 confirming to RFC2617 and addressing issue4675.
1172 """
1173 self.assertEqual(('user', 'ab'),urllib.parse.splitpasswd('user:ab'))
1174 self.assertEqual(('user', 'a\nb'),urllib.parse.splitpasswd('user:a\nb'))
1175 self.assertEqual(('user', 'a\tb'),urllib.parse.splitpasswd('user:a\tb'))
1176 self.assertEqual(('user', 'a\rb'),urllib.parse.splitpasswd('user:a\rb'))
1177 self.assertEqual(('user', 'a\fb'),urllib.parse.splitpasswd('user:a\fb'))
1178 self.assertEqual(('user', 'a\vb'),urllib.parse.splitpasswd('user:a\vb'))
1179 self.assertEqual(('user', 'a:b'),urllib.parse.splitpasswd('user:a:b'))
Senthil Kumaranc5c5a142012-01-14 19:09:04 +08001180 self.assertEqual(('user', 'a b'),urllib.parse.splitpasswd('user:a b'))
1181 self.assertEqual(('user 2', 'ab'),urllib.parse.splitpasswd('user 2:ab'))
1182 self.assertEqual(('user+1', 'a+b'),urllib.parse.splitpasswd('user+1:a+b'))
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001183
Senthil Kumaran1b7da512011-10-06 00:32:02 +08001184 def test_thishost(self):
1185 """Test the urllib.request.thishost utility function returns a tuple"""
1186 self.assertIsInstance(urllib.request.thishost(), tuple)
1187
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001188
1189class URLopener_Tests(unittest.TestCase):
1190 """Testcase to test the open method of URLopener class."""
1191
1192 def test_quoted_open(self):
1193 class DummyURLopener(urllib.request.URLopener):
1194 def open_spam(self, url):
1195 return url
1196
1197 self.assertEqual(DummyURLopener().open(
1198 'spam://example/ /'),'//example/%20/')
1199
Senthil Kumaran734f0592010-02-20 22:19:04 +00001200 # test the safe characters are not quoted by urlopen
1201 self.assertEqual(DummyURLopener().open(
1202 "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"),
1203 "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/")
1204
Guido van Rossume7ba4952007-06-06 23:52:48 +00001205# Just commented them out.
1206# Can't really tell why keep failing in windows and sparc.
Ezio Melotti13925002011-03-16 11:05:33 +02001207# Everywhere else they work ok, but on those machines, sometimes
Guido van Rossume7ba4952007-06-06 23:52:48 +00001208# fail in one of the tests, sometimes in other. I have a linux, and
1209# the tests go ok.
1210# If anybody has one of the problematic enviroments, please help!
1211# . Facundo
1212#
1213# def server(evt):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001214# import socket, time
Guido van Rossume7ba4952007-06-06 23:52:48 +00001215# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1216# serv.settimeout(3)
1217# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1218# serv.bind(("", 9093))
1219# serv.listen(5)
1220# try:
1221# conn, addr = serv.accept()
1222# conn.send("1 Hola mundo\n")
1223# cantdata = 0
1224# while cantdata < 13:
1225# data = conn.recv(13-cantdata)
1226# cantdata += len(data)
1227# time.sleep(.3)
1228# conn.send("2 No more lines\n")
1229# conn.close()
1230# except socket.timeout:
1231# pass
1232# finally:
1233# serv.close()
1234# evt.set()
1235#
1236# class FTPWrapperTests(unittest.TestCase):
1237#
1238# def setUp(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001239# import ftplib, time, threading
Guido van Rossume7ba4952007-06-06 23:52:48 +00001240# ftplib.FTP.port = 9093
1241# self.evt = threading.Event()
1242# threading.Thread(target=server, args=(self.evt,)).start()
1243# time.sleep(.1)
1244#
1245# def tearDown(self):
1246# self.evt.wait()
1247#
1248# def testBasic(self):
1249# # connects
1250# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
Georg Brandlf78e02b2008-06-10 17:40:04 +00001251# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001252#
1253# def testTimeoutNone(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001254# # global default timeout is ignored
1255# import socket
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001256# self.assertTrue(socket.getdefaulttimeout() is None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001257# socket.setdefaulttimeout(30)
1258# try:
1259# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1260# finally:
Georg Brandlf78e02b2008-06-10 17:40:04 +00001261# socket.setdefaulttimeout(None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001262# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
Georg Brandlf78e02b2008-06-10 17:40:04 +00001263# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001264#
Georg Brandlf78e02b2008-06-10 17:40:04 +00001265# def testTimeoutDefault(self):
1266# # global default timeout is used
1267# import socket
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001268# self.assertTrue(socket.getdefaulttimeout() is None)
Georg Brandlf78e02b2008-06-10 17:40:04 +00001269# socket.setdefaulttimeout(30)
1270# try:
1271# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1272# finally:
1273# socket.setdefaulttimeout(None)
1274# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1275# ftp.close()
1276#
1277# def testTimeoutValue(self):
1278# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
1279# timeout=30)
1280# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1281# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001282
Skip Montanaro080c9972001-01-28 21:12:22 +00001283
1284
Brett Cannon74bfd702003-04-25 09:39:47 +00001285def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001286 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +00001287 urlopen_FileTests,
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001288 urlopen_HttpTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001289 urlretrieve_FileTests,
Senthil Kumarance260142011-11-01 01:35:17 +08001290 urlretrieve_HttpTests,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001291 ProxyTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001292 QuotingTests,
1293 UnquotingTests,
1294 urlencode_Tests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001295 Pathname_Tests,
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001296 Utility_Tests,
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001297 URLopener_Tests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001298 #FTPWrapperTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001299 )
Brett Cannon74bfd702003-04-25 09:39:47 +00001300
1301
1302
1303if __name__ == '__main__':
1304 test_main()