blob: 4cb46827bb9c093129fb2e6e1bc1f2d3f2b2b4ff [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
16
Brett Cannon74bfd702003-04-25 09:39:47 +000017def hexescape(char):
18 """Escape char as RFC 2396 specifies"""
19 hex_repr = hex(ord(char))[2:].upper()
20 if len(hex_repr) == 1:
21 hex_repr = "0%s" % hex_repr
22 return "%" + hex_repr
Jeremy Hylton6102e292000-08-31 15:48:10 +000023
Jeremy Hylton1afc1692008-06-18 20:49:58 +000024# Shortcut for testing FancyURLopener
25_urlopener = None
26def urlopen(url, data=None, proxies=None):
27 """urlopen(url [, data]) -> open file-like object"""
28 global _urlopener
29 if proxies is not None:
30 opener = urllib.request.FancyURLopener(proxies=proxies)
31 elif not _urlopener:
32 opener = urllib.request.FancyURLopener()
33 _urlopener = opener
34 else:
35 opener = _urlopener
36 if data is None:
37 return opener.open(url)
38 else:
39 return opener.open(url, data)
40
Senthil Kumarance260142011-11-01 01:35:17 +080041
42class FakeHTTPMixin(object):
43 def fakehttp(self, fakedata):
44 class FakeSocket(io.BytesIO):
45 io_refs = 1
46
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080047 def sendall(self, data):
48 FakeHTTPConnection.buf = data
Senthil Kumarance260142011-11-01 01:35:17 +080049
50 def makefile(self, *args, **kwds):
51 self.io_refs += 1
52 return self
53
54 def read(self, amt=None):
55 if self.closed:
56 return b""
57 return io.BytesIO.read(self, amt)
58
59 def readline(self, length=None):
60 if self.closed:
61 return b""
62 return io.BytesIO.readline(self, length)
63
64 def close(self):
65 self.io_refs -= 1
66 if self.io_refs == 0:
67 io.BytesIO.close(self)
68
69 class FakeHTTPConnection(http.client.HTTPConnection):
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080070
71 # buffer to store data for verification in urlopen tests.
72 buf = None
73
Senthil Kumarance260142011-11-01 01:35:17 +080074 def connect(self):
75 self.sock = FakeSocket(fakedata)
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080076
Senthil Kumarance260142011-11-01 01:35:17 +080077 self._connection_class = http.client.HTTPConnection
78 http.client.HTTPConnection = FakeHTTPConnection
79
80 def unfakehttp(self):
81 http.client.HTTPConnection = self._connection_class
82
83
Brett Cannon74bfd702003-04-25 09:39:47 +000084class urlopen_FileTests(unittest.TestCase):
85 """Test urlopen() opening a temporary file.
Jeremy Hylton6102e292000-08-31 15:48:10 +000086
Brett Cannon74bfd702003-04-25 09:39:47 +000087 Try to test as much functionality as possible so as to cut down on reliance
Andrew M. Kuchlingf1a2f9e2004-06-29 13:07:53 +000088 on connecting to the Net for testing.
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000089
Brett Cannon74bfd702003-04-25 09:39:47 +000090 """
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000091
Brett Cannon74bfd702003-04-25 09:39:47 +000092 def setUp(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +000093 # Create a temp file to use for testing
94 self.text = bytes("test_urllib: %s\n" % self.__class__.__name__,
95 "ascii")
96 f = open(support.TESTFN, 'wb')
Brett Cannon74bfd702003-04-25 09:39:47 +000097 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +000098 f.write(self.text)
Brett Cannon74bfd702003-04-25 09:39:47 +000099 finally:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000100 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000101 self.pathname = support.TESTFN
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000102 self.returned_obj = urlopen("file:%s" % self.pathname)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +0000103
Brett Cannon74bfd702003-04-25 09:39:47 +0000104 def tearDown(self):
105 """Shut down the open object"""
106 self.returned_obj.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000107 os.remove(support.TESTFN)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +0000108
Brett Cannon74bfd702003-04-25 09:39:47 +0000109 def test_interface(self):
110 # Make sure object returned by urlopen() has the specified methods
111 for attr in ("read", "readline", "readlines", "fileno",
Christian Heimes9bd667a2008-01-20 15:14:11 +0000112 "close", "info", "geturl", "getcode", "__iter__"):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000113 self.assertTrue(hasattr(self.returned_obj, attr),
Brett Cannon74bfd702003-04-25 09:39:47 +0000114 "object returned by urlopen() lacks %s attribute" %
115 attr)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000116
Brett Cannon74bfd702003-04-25 09:39:47 +0000117 def test_read(self):
118 self.assertEqual(self.text, self.returned_obj.read())
Skip Montanaro080c9972001-01-28 21:12:22 +0000119
Brett Cannon74bfd702003-04-25 09:39:47 +0000120 def test_readline(self):
121 self.assertEqual(self.text, self.returned_obj.readline())
Guido van Rossuma0982942007-07-10 08:30:03 +0000122 self.assertEqual(b'', self.returned_obj.readline(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000123 "calling readline() after exhausting the file did not"
124 " return an empty string")
Skip Montanaro080c9972001-01-28 21:12:22 +0000125
Brett Cannon74bfd702003-04-25 09:39:47 +0000126 def test_readlines(self):
127 lines_list = self.returned_obj.readlines()
128 self.assertEqual(len(lines_list), 1,
129 "readlines() returned the wrong number of lines")
130 self.assertEqual(lines_list[0], self.text,
131 "readlines() returned improper text")
Skip Montanaro080c9972001-01-28 21:12:22 +0000132
Brett Cannon74bfd702003-04-25 09:39:47 +0000133 def test_fileno(self):
134 file_num = self.returned_obj.fileno()
Ezio Melottie9615932010-01-24 19:26:24 +0000135 self.assertIsInstance(file_num, int, "fileno() did not return an int")
Brett Cannon74bfd702003-04-25 09:39:47 +0000136 self.assertEqual(os.read(file_num, len(self.text)), self.text,
137 "Reading on the file descriptor returned by fileno() "
138 "did not return the expected text")
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000139
Brett Cannon74bfd702003-04-25 09:39:47 +0000140 def test_close(self):
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800141 # Test close() by calling it here and then having it be called again
Brett Cannon74bfd702003-04-25 09:39:47 +0000142 # by the tearDown() method for the test
143 self.returned_obj.close()
Skip Montanaro080c9972001-01-28 21:12:22 +0000144
Brett Cannon74bfd702003-04-25 09:39:47 +0000145 def test_info(self):
Ezio Melottie9615932010-01-24 19:26:24 +0000146 self.assertIsInstance(self.returned_obj.info(), email.message.Message)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000147
Brett Cannon74bfd702003-04-25 09:39:47 +0000148 def test_geturl(self):
149 self.assertEqual(self.returned_obj.geturl(), self.pathname)
Skip Montanaro080c9972001-01-28 21:12:22 +0000150
Christian Heimes9bd667a2008-01-20 15:14:11 +0000151 def test_getcode(self):
Florent Xicluna419e3842010-08-08 16:16:07 +0000152 self.assertIsNone(self.returned_obj.getcode())
Christian Heimes9bd667a2008-01-20 15:14:11 +0000153
Brett Cannon74bfd702003-04-25 09:39:47 +0000154 def test_iter(self):
155 # Test iterator
156 # Don't need to count number of iterations since test would fail the
157 # instant it returned anything beyond the first line from the
Raymond Hettinger038018a2011-06-26 14:29:35 +0200158 # comparison.
159 # Use the iterator in the usual implicit way to test for ticket #4608.
160 for line in self.returned_obj:
Brett Cannon74bfd702003-04-25 09:39:47 +0000161 self.assertEqual(line, self.text)
Skip Montanaro080c9972001-01-28 21:12:22 +0000162
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000163class ProxyTests(unittest.TestCase):
164
165 def setUp(self):
Walter Dörwaldb525e182009-04-26 21:39:21 +0000166 # Records changes to env vars
167 self.env = support.EnvironmentVarGuard()
Benjamin Peterson46a99002010-01-09 18:45:30 +0000168 # Delete all proxy related env vars
Antoine Pitroub3a88b52010-10-14 18:31:39 +0000169 for k in list(os.environ):
Antoine Pitrou8c8f1ac2010-10-14 18:32:54 +0000170 if 'proxy' in k.lower():
Benjamin Peterson46a99002010-01-09 18:45:30 +0000171 self.env.unset(k)
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000172
173 def tearDown(self):
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000174 # Restore all proxy related env vars
Walter Dörwaldb525e182009-04-26 21:39:21 +0000175 self.env.__exit__()
176 del self.env
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000177
178 def test_getproxies_environment_keep_no_proxies(self):
Walter Dörwaldb525e182009-04-26 21:39:21 +0000179 self.env.set('NO_PROXY', 'localhost')
180 proxies = urllib.request.getproxies_environment()
181 # getproxies_environment use lowered case truncated (no '_proxy') keys
Florent Xicluna419e3842010-08-08 16:16:07 +0000182 self.assertEqual('localhost', proxies['no'])
Senthil Kumaran89976f12011-08-06 12:27:40 +0800183 # List of no_proxies with space.
184 self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
185 self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com'))
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000186
Senthil Kumarance260142011-11-01 01:35:17 +0800187class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin):
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000188 """Test urlopen() opening a fake http connection."""
189
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000190 def check_read(self, ver):
191 self.fakehttp(b"HTTP/" + ver + b" 200 OK\r\n\r\nHello!")
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000192 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000193 fp = urlopen("http://python.org/")
Jeremy Hylton66dc8c52007-08-04 03:42:26 +0000194 self.assertEqual(fp.readline(), b"Hello!")
195 self.assertEqual(fp.readline(), b"")
Christian Heimes9bd667a2008-01-20 15:14:11 +0000196 self.assertEqual(fp.geturl(), 'http://python.org/')
197 self.assertEqual(fp.getcode(), 200)
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000198 finally:
199 self.unfakehttp()
200
Senthil Kumaran26430412011-04-13 07:01:19 +0800201 def test_url_fragment(self):
202 # Issue #11703: geturl() omits fragments in the original URL.
203 url = 'http://docs.python.org/library/urllib.html#OK'
Senthil Kumaranb17abb12011-04-13 07:22:29 +0800204 self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
Senthil Kumaran26430412011-04-13 07:01:19 +0800205 try:
206 fp = urllib.request.urlopen(url)
207 self.assertEqual(fp.geturl(), url)
208 finally:
209 self.unfakehttp()
210
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800211 def test_willclose(self):
212 self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
Senthil Kumaranacbaa922011-03-20 05:30:16 +0800213 try:
214 resp = urlopen("http://www.python.org")
215 self.assertTrue(resp.fp.will_close)
216 finally:
217 self.unfakehttp()
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800218
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000219 def test_read_0_9(self):
220 # "0.9" response accepted (but not "simple responses" without
221 # a status line)
222 self.check_read(b"0.9")
223
224 def test_read_1_0(self):
225 self.check_read(b"1.0")
226
227 def test_read_1_1(self):
228 self.check_read(b"1.1")
229
Christian Heimes57dddfb2008-01-02 18:30:52 +0000230 def test_read_bogus(self):
231 # urlopen() should raise IOError for many error codes.
232 self.fakehttp(b'''HTTP/1.1 401 Authentication Required
233Date: Wed, 02 Jan 2008 03:03:54 GMT
234Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
235Connection: close
236Content-Type: text/html; charset=iso-8859-1
237''')
238 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000239 self.assertRaises(IOError, urlopen, "http://python.org/")
Christian Heimes57dddfb2008-01-02 18:30:52 +0000240 finally:
241 self.unfakehttp()
242
guido@google.coma119df92011-03-29 11:41:02 -0700243 def test_invalid_redirect(self):
244 # urlopen() should raise IOError for many error codes.
245 self.fakehttp(b'''HTTP/1.1 302 Found
246Date: Wed, 02 Jan 2008 03:03:54 GMT
247Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
248Location: file://guidocomputer.athome.com:/python/license
249Connection: close
250Content-Type: text/html; charset=iso-8859-1
251''')
252 try:
253 self.assertRaises(urllib.error.HTTPError, urlopen,
254 "http://python.org/")
255 finally:
256 self.unfakehttp()
257
Guido van Rossumd8faa362007-04-27 19:54:29 +0000258 def test_empty_socket(self):
Jeremy Hylton66dc8c52007-08-04 03:42:26 +0000259 # urlopen() raises IOError if the underlying socket does not send any
260 # data. (#1680230)
Christian Heimes57dddfb2008-01-02 18:30:52 +0000261 self.fakehttp(b'')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000262 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000263 self.assertRaises(IOError, urlopen, "http://something")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000264 finally:
265 self.unfakehttp()
266
Senthil Kumarande0eb242010-08-01 17:53:37 +0000267 def test_userpass_inurl(self):
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000268 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
Senthil Kumarande0eb242010-08-01 17:53:37 +0000269 try:
270 fp = urlopen("http://user:pass@python.org/")
271 self.assertEqual(fp.readline(), b"Hello!")
272 self.assertEqual(fp.readline(), b"")
273 self.assertEqual(fp.geturl(), 'http://user:pass@python.org/')
274 self.assertEqual(fp.getcode(), 200)
275 finally:
276 self.unfakehttp()
277
Senthil Kumaranc5c5a142012-01-14 19:09:04 +0800278 def test_userpass_inurl_w_spaces(self):
279 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
280 try:
281 userpass = "a b:c d"
282 url = "http://{}@python.org/".format(userpass)
283 fakehttp_wrapper = http.client.HTTPConnection
284 authorization = ("Authorization: Basic %s\r\n" %
285 b64encode(userpass.encode("ASCII")).decode("ASCII"))
286 fp = urlopen(url)
287 # The authorization header must be in place
288 self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8"))
289 self.assertEqual(fp.readline(), b"Hello!")
290 self.assertEqual(fp.readline(), b"")
291 # the spaces are quoted in URL so no match
292 self.assertNotEqual(fp.geturl(), url)
293 self.assertEqual(fp.getcode(), 200)
294 finally:
295 self.unfakehttp()
296
Brett Cannon19691362003-04-29 05:08:06 +0000297class urlretrieve_FileTests(unittest.TestCase):
Brett Cannon74bfd702003-04-25 09:39:47 +0000298 """Test urllib.urlretrieve() on local files"""
Skip Montanaro080c9972001-01-28 21:12:22 +0000299
Brett Cannon19691362003-04-29 05:08:06 +0000300 def setUp(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000301 # Create a list of temporary files. Each item in the list is a file
302 # name (absolute path or relative to the current working directory).
303 # All files in this list will be deleted in the tearDown method. Note,
304 # this only helps to makes sure temporary files get deleted, but it
305 # does nothing about trying to close files that may still be open. It
306 # is the responsibility of the developer to properly close files even
307 # when exceptional conditions occur.
308 self.tempFiles = []
309
Brett Cannon19691362003-04-29 05:08:06 +0000310 # Create a temporary file.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000311 self.registerFileForCleanUp(support.TESTFN)
Guido van Rossuma0982942007-07-10 08:30:03 +0000312 self.text = b'testing urllib.urlretrieve'
Georg Brandl5a650a22005-08-26 08:51:34 +0000313 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000314 FILE = open(support.TESTFN, 'wb')
Georg Brandl5a650a22005-08-26 08:51:34 +0000315 FILE.write(self.text)
316 FILE.close()
317 finally:
318 try: FILE.close()
319 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000320
321 def tearDown(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000322 # Delete the temporary files.
323 for each in self.tempFiles:
324 try: os.remove(each)
325 except: pass
326
327 def constructLocalFileUrl(self, filePath):
Victor Stinner6c6f8512010-08-07 10:09:35 +0000328 filePath = os.path.abspath(filePath)
329 try:
Marc-André Lemburg8f36af72011-02-25 15:42:01 +0000330 filePath.encode("utf-8")
Victor Stinner6c6f8512010-08-07 10:09:35 +0000331 except UnicodeEncodeError:
332 raise unittest.SkipTest("filePath is not encodable to utf8")
333 return "file://%s" % urllib.request.pathname2url(filePath)
Georg Brandl5a650a22005-08-26 08:51:34 +0000334
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000335 def createNewTempFile(self, data=b""):
Georg Brandl5a650a22005-08-26 08:51:34 +0000336 """Creates a new temporary file containing the specified data,
337 registers the file for deletion during the test fixture tear down, and
338 returns the absolute path of the file."""
339
340 newFd, newFilePath = tempfile.mkstemp()
341 try:
342 self.registerFileForCleanUp(newFilePath)
343 newFile = os.fdopen(newFd, "wb")
344 newFile.write(data)
345 newFile.close()
346 finally:
347 try: newFile.close()
348 except: pass
349 return newFilePath
350
351 def registerFileForCleanUp(self, fileName):
352 self.tempFiles.append(fileName)
Brett Cannon19691362003-04-29 05:08:06 +0000353
354 def test_basic(self):
355 # Make sure that a local file just gets its own location returned and
356 # a headers value is returned.
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000357 result = urllib.request.urlretrieve("file:%s" % support.TESTFN)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000358 self.assertEqual(result[0], support.TESTFN)
Ezio Melottie9615932010-01-24 19:26:24 +0000359 self.assertIsInstance(result[1], email.message.Message,
360 "did not get a email.message.Message instance "
361 "as second returned value")
Brett Cannon19691362003-04-29 05:08:06 +0000362
363 def test_copy(self):
364 # Test that setting the filename argument works.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000365 second_temp = "%s.2" % support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000366 self.registerFileForCleanUp(second_temp)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000367 result = urllib.request.urlretrieve(self.constructLocalFileUrl(
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000368 support.TESTFN), second_temp)
Brett Cannon19691362003-04-29 05:08:06 +0000369 self.assertEqual(second_temp, result[0])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000370 self.assertTrue(os.path.exists(second_temp), "copy of the file was not "
Brett Cannon19691362003-04-29 05:08:06 +0000371 "made")
Alex Martelli01c77c62006-08-24 02:58:11 +0000372 FILE = open(second_temp, 'rb')
Brett Cannon19691362003-04-29 05:08:06 +0000373 try:
374 text = FILE.read()
Brett Cannon19691362003-04-29 05:08:06 +0000375 FILE.close()
Georg Brandl5a650a22005-08-26 08:51:34 +0000376 finally:
377 try: FILE.close()
378 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000379 self.assertEqual(self.text, text)
380
381 def test_reporthook(self):
382 # Make sure that the reporthook works.
383 def hooktester(count, block_size, total_size, count_holder=[0]):
Ezio Melottie9615932010-01-24 19:26:24 +0000384 self.assertIsInstance(count, int)
385 self.assertIsInstance(block_size, int)
386 self.assertIsInstance(total_size, int)
Brett Cannon19691362003-04-29 05:08:06 +0000387 self.assertEqual(count, count_holder[0])
388 count_holder[0] = count_holder[0] + 1
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000389 second_temp = "%s.2" % support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000390 self.registerFileForCleanUp(second_temp)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000391 urllib.request.urlretrieve(
392 self.constructLocalFileUrl(support.TESTFN),
Georg Brandl5a650a22005-08-26 08:51:34 +0000393 second_temp, hooktester)
394
395 def test_reporthook_0_bytes(self):
396 # Test on zero length file. Should call reporthook only 1 time.
397 report = []
398 def hooktester(count, block_size, total_size, _report=report):
399 _report.append((count, block_size, total_size))
400 srcFileName = self.createNewTempFile()
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000401 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000402 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000403 self.assertEqual(len(report), 1)
404 self.assertEqual(report[0][2], 0)
405
406 def test_reporthook_5_bytes(self):
407 # Test on 5 byte file. Should call reporthook only 2 times (once when
408 # the "network connection" is established and once when the block is
409 # read). Since the block size is 8192 bytes, only one block read is
410 # required to read the entire file.
411 report = []
412 def hooktester(count, block_size, total_size, _report=report):
413 _report.append((count, block_size, total_size))
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000414 srcFileName = self.createNewTempFile(b"x" * 5)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000415 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000416 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000417 self.assertEqual(len(report), 2)
418 self.assertEqual(report[0][1], 8192)
419 self.assertEqual(report[0][2], 5)
420
421 def test_reporthook_8193_bytes(self):
422 # Test on 8193 byte file. Should call reporthook only 3 times (once
423 # when the "network connection" is established, once for the next 8192
424 # bytes, and once for the last byte).
425 report = []
426 def hooktester(count, block_size, total_size, _report=report):
427 _report.append((count, block_size, total_size))
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000428 srcFileName = self.createNewTempFile(b"x" * 8193)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000429 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000430 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000431 self.assertEqual(len(report), 3)
432 self.assertEqual(report[0][1], 8192)
433 self.assertEqual(report[0][2], 8193)
Skip Montanaro080c9972001-01-28 21:12:22 +0000434
Senthil Kumarance260142011-11-01 01:35:17 +0800435
436class urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin):
437 """Test urllib.urlretrieve() using fake http connections"""
438
439 def test_short_content_raises_ContentTooShortError(self):
440 self.fakehttp(b'''HTTP/1.1 200 OK
441Date: Wed, 02 Jan 2008 03:03:54 GMT
442Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
443Connection: close
444Content-Length: 100
445Content-Type: text/html; charset=iso-8859-1
446
447FF
448''')
449
450 def _reporthook(par1, par2, par3):
451 pass
452
453 with self.assertRaises(urllib.error.ContentTooShortError):
454 try:
455 urllib.request.urlretrieve('http://example.com/',
456 reporthook=_reporthook)
457 finally:
458 self.unfakehttp()
459
460 def test_short_content_raises_ContentTooShortError_without_reporthook(self):
461 self.fakehttp(b'''HTTP/1.1 200 OK
462Date: Wed, 02 Jan 2008 03:03:54 GMT
463Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
464Connection: close
465Content-Length: 100
466Content-Type: text/html; charset=iso-8859-1
467
468FF
469''')
470 with self.assertRaises(urllib.error.ContentTooShortError):
471 try:
472 urllib.request.urlretrieve('http://example.com/')
473 finally:
474 self.unfakehttp()
475
476
Brett Cannon74bfd702003-04-25 09:39:47 +0000477class QuotingTests(unittest.TestCase):
478 """Tests for urllib.quote() and urllib.quote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000479
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000480 According to RFC 2396 (Uniform Resource Identifiers), to escape a
481 character you write it as '%' + <2 character US-ASCII hex value>.
482 The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a
483 character properly. Case does not matter on the hex letters.
Brett Cannon74bfd702003-04-25 09:39:47 +0000484
485 The various character sets specified are:
Tim Petersc2659cf2003-05-12 20:19:37 +0000486
Brett Cannon74bfd702003-04-25 09:39:47 +0000487 Reserved characters : ";/?:@&=+$,"
488 Have special meaning in URIs and must be escaped if not being used for
489 their special meaning
490 Data characters : letters, digits, and "-_.!~*'()"
491 Unreserved and do not need to be escaped; can be, though, if desired
492 Control characters : 0x00 - 0x1F, 0x7F
493 Have no use in URIs so must be escaped
494 space : 0x20
495 Must be escaped
496 Delimiters : '<>#%"'
497 Must be escaped
498 Unwise : "{}|\^[]`"
499 Must be escaped
Tim Petersc2659cf2003-05-12 20:19:37 +0000500
Brett Cannon74bfd702003-04-25 09:39:47 +0000501 """
502
503 def test_never_quote(self):
504 # Make sure quote() does not quote letters, digits, and "_,.-"
505 do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
506 "abcdefghijklmnopqrstuvwxyz",
507 "0123456789",
508 "_.-"])
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000509 result = urllib.parse.quote(do_not_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000510 self.assertEqual(do_not_quote, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000511 "using quote(): %r != %r" % (do_not_quote, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000512 result = urllib.parse.quote_plus(do_not_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000513 self.assertEqual(do_not_quote, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000514 "using quote_plus(): %r != %r" % (do_not_quote, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000515
516 def test_default_safe(self):
517 # Test '/' is default value for 'safe' parameter
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000518 self.assertEqual(urllib.parse.quote.__defaults__[0], '/')
Brett Cannon74bfd702003-04-25 09:39:47 +0000519
520 def test_safe(self):
521 # Test setting 'safe' parameter does what it should do
522 quote_by_default = "<>"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000523 result = urllib.parse.quote(quote_by_default, safe=quote_by_default)
Brett Cannon74bfd702003-04-25 09:39:47 +0000524 self.assertEqual(quote_by_default, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000525 "using quote(): %r != %r" % (quote_by_default, result))
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000526 result = urllib.parse.quote_plus(quote_by_default,
527 safe=quote_by_default)
Brett Cannon74bfd702003-04-25 09:39:47 +0000528 self.assertEqual(quote_by_default, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000529 "using quote_plus(): %r != %r" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000530 (quote_by_default, result))
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000531 # Safe expressed as bytes rather than str
532 result = urllib.parse.quote(quote_by_default, safe=b"<>")
533 self.assertEqual(quote_by_default, result,
534 "using quote(): %r != %r" % (quote_by_default, result))
535 # "Safe" non-ASCII characters should have no effect
536 # (Since URIs are not allowed to have non-ASCII characters)
537 result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="\xfc")
538 expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="")
539 self.assertEqual(expect, result,
540 "using quote(): %r != %r" %
541 (expect, result))
542 # Same as above, but using a bytes rather than str
543 result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe=b"\xfc")
544 expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="")
545 self.assertEqual(expect, result,
546 "using quote(): %r != %r" %
547 (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000548
549 def test_default_quoting(self):
550 # Make sure all characters that should be quoted are by default sans
551 # space (separate test for that).
552 should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
553 should_quote.append('<>#%"{}|\^[]`')
554 should_quote.append(chr(127)) # For 0x7F
555 should_quote = ''.join(should_quote)
556 for char in should_quote:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000557 result = urllib.parse.quote(char)
Brett Cannon74bfd702003-04-25 09:39:47 +0000558 self.assertEqual(hexescape(char), result,
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000559 "using quote(): "
560 "%s should be escaped to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000561 (char, hexescape(char), result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000562 result = urllib.parse.quote_plus(char)
Brett Cannon74bfd702003-04-25 09:39:47 +0000563 self.assertEqual(hexescape(char), result,
564 "using quote_plus(): "
Tim Petersc2659cf2003-05-12 20:19:37 +0000565 "%s should be escapes to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000566 (char, hexescape(char), result))
567 del should_quote
568 partial_quote = "ab[]cd"
569 expected = "ab%5B%5Dcd"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000570 result = urllib.parse.quote(partial_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000571 self.assertEqual(expected, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000572 "using quote(): %r != %r" % (expected, result))
Senthil Kumaran305a68e2011-09-13 06:40:27 +0800573 result = urllib.parse.quote_plus(partial_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000574 self.assertEqual(expected, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000575 "using quote_plus(): %r != %r" % (expected, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000576
577 def test_quoting_space(self):
578 # Make sure quote() and quote_plus() handle spaces as specified in
579 # their unique way
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000580 result = urllib.parse.quote(' ')
Brett Cannon74bfd702003-04-25 09:39:47 +0000581 self.assertEqual(result, hexescape(' '),
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000582 "using quote(): %r != %r" % (result, hexescape(' ')))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000583 result = urllib.parse.quote_plus(' ')
Brett Cannon74bfd702003-04-25 09:39:47 +0000584 self.assertEqual(result, '+',
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000585 "using quote_plus(): %r != +" % result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000586 given = "a b cd e f"
587 expect = given.replace(' ', hexescape(' '))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000588 result = urllib.parse.quote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000589 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000590 "using quote(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000591 expect = given.replace(' ', '+')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000592 result = urllib.parse.quote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000593 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000594 "using quote_plus(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000595
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000596 def test_quoting_plus(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000597 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma'),
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000598 'alpha%2Bbeta+gamma')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000599 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', '+'),
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000600 'alpha+beta+gamma')
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000601 # Test with bytes
602 self.assertEqual(urllib.parse.quote_plus(b'alpha+beta gamma'),
603 'alpha%2Bbeta+gamma')
604 # Test with safe bytes
605 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', b'+'),
606 'alpha+beta+gamma')
607
608 def test_quote_bytes(self):
609 # Bytes should quote directly to percent-encoded values
610 given = b"\xa2\xd8ab\xff"
611 expect = "%A2%D8ab%FF"
612 result = urllib.parse.quote(given)
613 self.assertEqual(expect, result,
614 "using quote(): %r != %r" % (expect, result))
615 # Encoding argument should raise type error on bytes input
616 self.assertRaises(TypeError, urllib.parse.quote, given,
617 encoding="latin-1")
618 # quote_from_bytes should work the same
619 result = urllib.parse.quote_from_bytes(given)
620 self.assertEqual(expect, result,
621 "using quote_from_bytes(): %r != %r"
622 % (expect, result))
623
624 def test_quote_with_unicode(self):
625 # Characters in Latin-1 range, encoded by default in UTF-8
626 given = "\xa2\xd8ab\xff"
627 expect = "%C2%A2%C3%98ab%C3%BF"
628 result = urllib.parse.quote(given)
629 self.assertEqual(expect, result,
630 "using quote(): %r != %r" % (expect, result))
631 # Characters in Latin-1 range, encoded by with None (default)
632 result = urllib.parse.quote(given, encoding=None, errors=None)
633 self.assertEqual(expect, result,
634 "using quote(): %r != %r" % (expect, result))
635 # Characters in Latin-1 range, encoded with Latin-1
636 given = "\xa2\xd8ab\xff"
637 expect = "%A2%D8ab%FF"
638 result = urllib.parse.quote(given, encoding="latin-1")
639 self.assertEqual(expect, result,
640 "using quote(): %r != %r" % (expect, result))
641 # Characters in BMP, encoded by default in UTF-8
642 given = "\u6f22\u5b57" # "Kanji"
643 expect = "%E6%BC%A2%E5%AD%97"
644 result = urllib.parse.quote(given)
645 self.assertEqual(expect, result,
646 "using quote(): %r != %r" % (expect, result))
647 # Characters in BMP, encoded with Latin-1
648 given = "\u6f22\u5b57"
649 self.assertRaises(UnicodeEncodeError, urllib.parse.quote, given,
650 encoding="latin-1")
651 # Characters in BMP, encoded with Latin-1, with replace error handling
652 given = "\u6f22\u5b57"
653 expect = "%3F%3F" # "??"
654 result = urllib.parse.quote(given, encoding="latin-1",
655 errors="replace")
656 self.assertEqual(expect, result,
657 "using quote(): %r != %r" % (expect, result))
658 # Characters in BMP, Latin-1, with xmlcharref error handling
659 given = "\u6f22\u5b57"
660 expect = "%26%2328450%3B%26%2323383%3B" # "&#28450;&#23383;"
661 result = urllib.parse.quote(given, encoding="latin-1",
662 errors="xmlcharrefreplace")
663 self.assertEqual(expect, result,
664 "using quote(): %r != %r" % (expect, result))
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000665
Georg Brandlfaf41492009-05-26 18:31:11 +0000666 def test_quote_plus_with_unicode(self):
667 # Encoding (latin-1) test for quote_plus
668 given = "\xa2\xd8 \xff"
669 expect = "%A2%D8+%FF"
670 result = urllib.parse.quote_plus(given, encoding="latin-1")
671 self.assertEqual(expect, result,
672 "using quote_plus(): %r != %r" % (expect, result))
673 # Errors test for quote_plus
674 given = "ab\u6f22\u5b57 cd"
675 expect = "ab%3F%3F+cd"
676 result = urllib.parse.quote_plus(given, encoding="latin-1",
677 errors="replace")
678 self.assertEqual(expect, result,
679 "using quote_plus(): %r != %r" % (expect, result))
680
Senthil Kumarand496c4c2010-07-30 19:34:36 +0000681
Brett Cannon74bfd702003-04-25 09:39:47 +0000682class UnquotingTests(unittest.TestCase):
683 """Tests for unquote() and unquote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000684
Brett Cannon74bfd702003-04-25 09:39:47 +0000685 See the doc string for quoting_Tests for details on quoting and such.
686
687 """
688
689 def test_unquoting(self):
690 # Make sure unquoting of all ASCII values works
691 escape_list = []
692 for num in range(128):
693 given = hexescape(chr(num))
694 expect = chr(num)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000695 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000696 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000697 "using unquote(): %r != %r" % (expect, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000698 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000699 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000700 "using unquote_plus(): %r != %r" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000701 (expect, result))
702 escape_list.append(given)
703 escape_string = ''.join(escape_list)
704 del escape_list
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000705 result = urllib.parse.unquote(escape_string)
Brett Cannon74bfd702003-04-25 09:39:47 +0000706 self.assertEqual(result.count('%'), 1,
Brett Cannon74bfd702003-04-25 09:39:47 +0000707 "using unquote(): not all characters escaped: "
708 "%s" % result)
Georg Brandl604ef372010-07-31 08:20:02 +0000709 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None)
710 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ())
Florent Xicluna62829dc2010-08-14 20:51:58 +0000711 with support.check_warnings(('', BytesWarning), quiet=True):
712 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, b'')
Brett Cannon74bfd702003-04-25 09:39:47 +0000713
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000714 def test_unquoting_badpercent(self):
715 # Test unquoting on bad percent-escapes
716 given = '%xab'
717 expect = given
718 result = urllib.parse.unquote(given)
719 self.assertEqual(expect, result, "using unquote(): %r != %r"
720 % (expect, result))
721 given = '%x'
722 expect = given
723 result = urllib.parse.unquote(given)
724 self.assertEqual(expect, result, "using unquote(): %r != %r"
725 % (expect, result))
726 given = '%'
727 expect = given
728 result = urllib.parse.unquote(given)
729 self.assertEqual(expect, result, "using unquote(): %r != %r"
730 % (expect, result))
731 # unquote_to_bytes
732 given = '%xab'
733 expect = bytes(given, 'ascii')
734 result = urllib.parse.unquote_to_bytes(given)
735 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
736 % (expect, result))
737 given = '%x'
738 expect = bytes(given, 'ascii')
739 result = urllib.parse.unquote_to_bytes(given)
740 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
741 % (expect, result))
742 given = '%'
743 expect = bytes(given, 'ascii')
744 result = urllib.parse.unquote_to_bytes(given)
745 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
746 % (expect, result))
Georg Brandl604ef372010-07-31 08:20:02 +0000747 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, None)
748 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, ())
Senthil Kumaran79e17f62010-07-19 18:17:19 +0000749
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000750 def test_unquoting_mixed_case(self):
751 # Test unquoting on mixed-case hex digits in the percent-escapes
752 given = '%Ab%eA'
753 expect = b'\xab\xea'
754 result = urllib.parse.unquote_to_bytes(given)
755 self.assertEqual(expect, result,
756 "using unquote_to_bytes(): %r != %r"
757 % (expect, result))
758
Brett Cannon74bfd702003-04-25 09:39:47 +0000759 def test_unquoting_parts(self):
760 # Make sure unquoting works when have non-quoted characters
761 # interspersed
762 given = 'ab%sd' % hexescape('c')
763 expect = "abcd"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000764 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000765 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000766 "using quote(): %r != %r" % (expect, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000767 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000768 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000769 "using unquote_plus(): %r != %r" % (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +0000770
Brett Cannon74bfd702003-04-25 09:39:47 +0000771 def test_unquoting_plus(self):
772 # Test difference between unquote() and unquote_plus()
773 given = "are+there+spaces..."
774 expect = given
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000775 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000776 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000777 "using unquote(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000778 expect = given.replace('+', ' ')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000779 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000780 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000781 "using unquote_plus(): %r != %r" % (expect, result))
782
783 def test_unquote_to_bytes(self):
784 given = 'br%C3%BCckner_sapporo_20050930.doc'
785 expect = b'br\xc3\xbcckner_sapporo_20050930.doc'
786 result = urllib.parse.unquote_to_bytes(given)
787 self.assertEqual(expect, result,
788 "using unquote_to_bytes(): %r != %r"
789 % (expect, result))
790 # Test on a string with unescaped non-ASCII characters
791 # (Technically an invalid URI; expect those characters to be UTF-8
792 # encoded).
793 result = urllib.parse.unquote_to_bytes("\u6f22%C3%BC")
794 expect = b'\xe6\xbc\xa2\xc3\xbc' # UTF-8 for "\u6f22\u00fc"
795 self.assertEqual(expect, result,
796 "using unquote_to_bytes(): %r != %r"
797 % (expect, result))
798 # Test with a bytes as input
799 given = b'%A2%D8ab%FF'
800 expect = b'\xa2\xd8ab\xff'
801 result = urllib.parse.unquote_to_bytes(given)
802 self.assertEqual(expect, result,
803 "using unquote_to_bytes(): %r != %r"
804 % (expect, result))
805 # Test with a bytes as input, with unescaped non-ASCII bytes
806 # (Technically an invalid URI; expect those bytes to be preserved)
807 given = b'%A2\xd8ab%FF'
808 expect = b'\xa2\xd8ab\xff'
809 result = urllib.parse.unquote_to_bytes(given)
810 self.assertEqual(expect, result,
811 "using unquote_to_bytes(): %r != %r"
812 % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000813
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000814 def test_unquote_with_unicode(self):
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000815 # Characters in the Latin-1 range, encoded with UTF-8
816 given = 'br%C3%BCckner_sapporo_20050930.doc'
817 expect = 'br\u00fcckner_sapporo_20050930.doc'
818 result = urllib.parse.unquote(given)
819 self.assertEqual(expect, result,
820 "using unquote(): %r != %r" % (expect, result))
821 # Characters in the Latin-1 range, encoded with None (default)
822 result = urllib.parse.unquote(given, encoding=None, errors=None)
823 self.assertEqual(expect, result,
824 "using unquote(): %r != %r" % (expect, result))
825
826 # Characters in the Latin-1 range, encoded with Latin-1
827 result = urllib.parse.unquote('br%FCckner_sapporo_20050930.doc',
828 encoding="latin-1")
829 expect = 'br\u00fcckner_sapporo_20050930.doc'
830 self.assertEqual(expect, result,
831 "using unquote(): %r != %r" % (expect, result))
832
833 # Characters in BMP, encoded with UTF-8
834 given = "%E6%BC%A2%E5%AD%97"
835 expect = "\u6f22\u5b57" # "Kanji"
836 result = urllib.parse.unquote(given)
837 self.assertEqual(expect, result,
838 "using unquote(): %r != %r" % (expect, result))
839
840 # Decode with UTF-8, invalid sequence
841 given = "%F3%B1"
842 expect = "\ufffd" # Replacement character
843 result = urllib.parse.unquote(given)
844 self.assertEqual(expect, result,
845 "using unquote(): %r != %r" % (expect, result))
846
847 # Decode with UTF-8, invalid sequence, replace errors
848 result = urllib.parse.unquote(given, errors="replace")
849 self.assertEqual(expect, result,
850 "using unquote(): %r != %r" % (expect, result))
851
852 # Decode with UTF-8, invalid sequence, ignoring errors
853 given = "%F3%B1"
854 expect = ""
855 result = urllib.parse.unquote(given, errors="ignore")
856 self.assertEqual(expect, result,
857 "using unquote(): %r != %r" % (expect, result))
858
859 # A mix of non-ASCII and percent-encoded characters, UTF-8
860 result = urllib.parse.unquote("\u6f22%C3%BC")
861 expect = '\u6f22\u00fc'
862 self.assertEqual(expect, result,
863 "using unquote(): %r != %r" % (expect, result))
864
865 # A mix of non-ASCII and percent-encoded characters, Latin-1
866 # (Note, the string contains non-Latin-1-representable characters)
867 result = urllib.parse.unquote("\u6f22%FC", encoding="latin-1")
868 expect = '\u6f22\u00fc'
869 self.assertEqual(expect, result,
870 "using unquote(): %r != %r" % (expect, result))
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000871
Brett Cannon74bfd702003-04-25 09:39:47 +0000872class urlencode_Tests(unittest.TestCase):
873 """Tests for urlencode()"""
874
875 def help_inputtype(self, given, test_type):
876 """Helper method for testing different input types.
Tim Petersc2659cf2003-05-12 20:19:37 +0000877
Brett Cannon74bfd702003-04-25 09:39:47 +0000878 'given' must lead to only the pairs:
879 * 1st, 1
880 * 2nd, 2
881 * 3rd, 3
Tim Petersc2659cf2003-05-12 20:19:37 +0000882
Brett Cannon74bfd702003-04-25 09:39:47 +0000883 Test cannot assume anything about order. Docs make no guarantee and
884 have possible dictionary input.
Tim Petersc2659cf2003-05-12 20:19:37 +0000885
Brett Cannon74bfd702003-04-25 09:39:47 +0000886 """
887 expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000888 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000889 for expected in expect_somewhere:
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000890 self.assertIn(expected, result,
Brett Cannon74bfd702003-04-25 09:39:47 +0000891 "testing %s: %s not found in %s" %
892 (test_type, expected, result))
893 self.assertEqual(result.count('&'), 2,
894 "testing %s: expected 2 '&'s; got %s" %
895 (test_type, result.count('&')))
896 amp_location = result.index('&')
897 on_amp_left = result[amp_location - 1]
898 on_amp_right = result[amp_location + 1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000899 self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000900 "testing %s: '&' not located in proper place in %s" %
901 (test_type, result))
902 self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
903 "testing %s: "
904 "unexpected number of characters: %s != %s" %
905 (test_type, len(result), (5 * 3) + 2))
906
907 def test_using_mapping(self):
908 # Test passing in a mapping object as an argument.
909 self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
910 "using dict as input type")
911
912 def test_using_sequence(self):
913 # Test passing in a sequence of two-item sequences as an argument.
914 self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
915 "using sequence of two-item tuples as input")
916
917 def test_quoting(self):
918 # Make sure keys and values are quoted using quote_plus()
919 given = {"&":"="}
920 expect = "%s=%s" % (hexescape('&'), hexescape('='))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000921 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000922 self.assertEqual(expect, result)
923 given = {"key name":"A bunch of pluses"}
924 expect = "key+name=A+bunch+of+pluses"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000925 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000926 self.assertEqual(expect, result)
927
928 def test_doseq(self):
929 # Test that passing True for 'doseq' parameter works correctly
930 given = {'sequence':['1', '2', '3']}
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000931 expect = "sequence=%s" % urllib.parse.quote_plus(str(['1', '2', '3']))
932 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000933 self.assertEqual(expect, result)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000934 result = urllib.parse.urlencode(given, True)
Brett Cannon74bfd702003-04-25 09:39:47 +0000935 for value in given["sequence"]:
936 expect = "sequence=%s" % value
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000937 self.assertIn(expect, result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000938 self.assertEqual(result.count('&'), 2,
939 "Expected 2 '&'s, got %s" % result.count('&'))
940
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000941 def test_empty_sequence(self):
942 self.assertEqual("", urllib.parse.urlencode({}))
943 self.assertEqual("", urllib.parse.urlencode([]))
944
945 def test_nonstring_values(self):
946 self.assertEqual("a=1", urllib.parse.urlencode({"a": 1}))
947 self.assertEqual("a=None", urllib.parse.urlencode({"a": None}))
948
949 def test_nonstring_seq_values(self):
950 self.assertEqual("a=1&a=2", urllib.parse.urlencode({"a": [1, 2]}, True))
951 self.assertEqual("a=None&a=a",
952 urllib.parse.urlencode({"a": [None, "a"]}, True))
953 self.assertEqual("a=a&a=b",
954 urllib.parse.urlencode({"a": {"a": 1, "b": 1}}, True))
955
Senthil Kumarandf022da2010-07-03 17:48:22 +0000956 def test_urlencode_encoding(self):
957 # ASCII encoding. Expect %3F with errors="replace'
958 given = (('\u00a0', '\u00c1'),)
959 expect = '%3F=%3F'
960 result = urllib.parse.urlencode(given, encoding="ASCII", errors="replace")
961 self.assertEqual(expect, result)
962
963 # Default is UTF-8 encoding.
964 given = (('\u00a0', '\u00c1'),)
965 expect = '%C2%A0=%C3%81'
966 result = urllib.parse.urlencode(given)
967 self.assertEqual(expect, result)
968
969 # Latin-1 encoding.
970 given = (('\u00a0', '\u00c1'),)
971 expect = '%A0=%C1'
972 result = urllib.parse.urlencode(given, encoding="latin-1")
973 self.assertEqual(expect, result)
974
975 def test_urlencode_encoding_doseq(self):
976 # ASCII Encoding. Expect %3F with errors="replace'
977 given = (('\u00a0', '\u00c1'),)
978 expect = '%3F=%3F'
979 result = urllib.parse.urlencode(given, doseq=True,
980 encoding="ASCII", errors="replace")
981 self.assertEqual(expect, result)
982
983 # ASCII Encoding. On a sequence of values.
984 given = (("\u00a0", (1, "\u00c1")),)
985 expect = '%3F=1&%3F=%3F'
986 result = urllib.parse.urlencode(given, True,
987 encoding="ASCII", errors="replace")
988 self.assertEqual(expect, result)
989
990 # Utf-8
991 given = (("\u00a0", "\u00c1"),)
992 expect = '%C2%A0=%C3%81'
993 result = urllib.parse.urlencode(given, True)
994 self.assertEqual(expect, result)
995
996 given = (("\u00a0", (42, "\u00c1")),)
997 expect = '%C2%A0=42&%C2%A0=%C3%81'
998 result = urllib.parse.urlencode(given, True)
999 self.assertEqual(expect, result)
1000
1001 # latin-1
1002 given = (("\u00a0", "\u00c1"),)
1003 expect = '%A0=%C1'
1004 result = urllib.parse.urlencode(given, True, encoding="latin-1")
1005 self.assertEqual(expect, result)
1006
1007 given = (("\u00a0", (42, "\u00c1")),)
1008 expect = '%A0=42&%A0=%C1'
1009 result = urllib.parse.urlencode(given, True, encoding="latin-1")
1010 self.assertEqual(expect, result)
1011
1012 def test_urlencode_bytes(self):
1013 given = ((b'\xa0\x24', b'\xc1\x24'),)
1014 expect = '%A0%24=%C1%24'
1015 result = urllib.parse.urlencode(given)
1016 self.assertEqual(expect, result)
1017 result = urllib.parse.urlencode(given, True)
1018 self.assertEqual(expect, result)
1019
1020 # Sequence of values
1021 given = ((b'\xa0\x24', (42, b'\xc1\x24')),)
1022 expect = '%A0%24=42&%A0%24=%C1%24'
1023 result = urllib.parse.urlencode(given, True)
1024 self.assertEqual(expect, result)
1025
1026 def test_urlencode_encoding_safe_parameter(self):
1027
1028 # Send '$' (\x24) as safe character
1029 # Default utf-8 encoding
1030
1031 given = ((b'\xa0\x24', b'\xc1\x24'),)
1032 result = urllib.parse.urlencode(given, safe=":$")
1033 expect = '%A0$=%C1$'
1034 self.assertEqual(expect, result)
1035
1036 given = ((b'\xa0\x24', b'\xc1\x24'),)
1037 result = urllib.parse.urlencode(given, doseq=True, safe=":$")
1038 expect = '%A0$=%C1$'
1039 self.assertEqual(expect, result)
1040
1041 # Safe parameter in sequence
1042 given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
1043 expect = '%A0$=%C1$&%A0$=13&%A0$=42'
1044 result = urllib.parse.urlencode(given, True, safe=":$")
1045 self.assertEqual(expect, result)
1046
1047 # Test all above in latin-1 encoding
1048
1049 given = ((b'\xa0\x24', b'\xc1\x24'),)
1050 result = urllib.parse.urlencode(given, safe=":$",
1051 encoding="latin-1")
1052 expect = '%A0$=%C1$'
1053 self.assertEqual(expect, result)
1054
1055 given = ((b'\xa0\x24', b'\xc1\x24'),)
1056 expect = '%A0$=%C1$'
1057 result = urllib.parse.urlencode(given, doseq=True, safe=":$",
1058 encoding="latin-1")
1059
1060 given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
1061 expect = '%A0$=%C1$&%A0$=13&%A0$=42'
1062 result = urllib.parse.urlencode(given, True, safe=":$",
1063 encoding="latin-1")
1064 self.assertEqual(expect, result)
1065
Brett Cannon74bfd702003-04-25 09:39:47 +00001066class Pathname_Tests(unittest.TestCase):
1067 """Test pathname2url() and url2pathname()"""
1068
1069 def test_basic(self):
1070 # Make sure simple tests pass
1071 expected_path = os.path.join("parts", "of", "a", "path")
1072 expected_url = "parts/of/a/path"
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001073 result = urllib.request.pathname2url(expected_path)
Brett Cannon74bfd702003-04-25 09:39:47 +00001074 self.assertEqual(expected_url, result,
1075 "pathname2url() failed; %s != %s" %
1076 (result, expected_url))
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001077 result = urllib.request.url2pathname(expected_url)
Brett Cannon74bfd702003-04-25 09:39:47 +00001078 self.assertEqual(expected_path, result,
1079 "url2pathame() failed; %s != %s" %
1080 (result, expected_path))
1081
1082 def test_quoting(self):
1083 # Test automatic quoting and unquoting works for pathnam2url() and
1084 # url2pathname() respectively
1085 given = os.path.join("needs", "quot=ing", "here")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001086 expect = "needs/%s/here" % urllib.parse.quote("quot=ing")
1087 result = urllib.request.pathname2url(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001088 self.assertEqual(expect, result,
1089 "pathname2url() failed; %s != %s" %
1090 (expect, result))
1091 expect = given
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001092 result = urllib.request.url2pathname(result)
Brett Cannon74bfd702003-04-25 09:39:47 +00001093 self.assertEqual(expect, result,
1094 "url2pathname() failed; %s != %s" %
1095 (expect, result))
1096 given = os.path.join("make sure", "using_quote")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001097 expect = "%s/using_quote" % urllib.parse.quote("make sure")
1098 result = urllib.request.pathname2url(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001099 self.assertEqual(expect, result,
1100 "pathname2url() failed; %s != %s" %
1101 (expect, result))
1102 given = "make+sure/using_unquote"
1103 expect = os.path.join("make+sure", "using_unquote")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001104 result = urllib.request.url2pathname(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001105 self.assertEqual(expect, result,
1106 "url2pathname() failed; %s != %s" %
1107 (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +00001108
Senthil Kumaran2d2ea1b2011-04-14 13:16:30 +08001109 @unittest.skipUnless(sys.platform == 'win32',
1110 'test specific to the urllib.url2path function.')
1111 def test_ntpath(self):
1112 given = ('/C:/', '///C:/', '/C|//')
1113 expect = 'C:\\'
1114 for url in given:
1115 result = urllib.request.url2pathname(url)
1116 self.assertEqual(expect, result,
1117 'urllib.request..url2pathname() failed; %s != %s' %
1118 (expect, result))
1119 given = '///C|/path'
1120 expect = 'C:\\path'
1121 result = urllib.request.url2pathname(given)
1122 self.assertEqual(expect, result,
1123 'urllib.request.url2pathname() failed; %s != %s' %
1124 (expect, result))
1125
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001126class Utility_Tests(unittest.TestCase):
1127 """Testcase to test the various utility functions in the urllib."""
1128
1129 def test_splitpasswd(self):
1130 """Some of password examples are not sensible, but it is added to
1131 confirming to RFC2617 and addressing issue4675.
1132 """
1133 self.assertEqual(('user', 'ab'),urllib.parse.splitpasswd('user:ab'))
1134 self.assertEqual(('user', 'a\nb'),urllib.parse.splitpasswd('user:a\nb'))
1135 self.assertEqual(('user', 'a\tb'),urllib.parse.splitpasswd('user:a\tb'))
1136 self.assertEqual(('user', 'a\rb'),urllib.parse.splitpasswd('user:a\rb'))
1137 self.assertEqual(('user', 'a\fb'),urllib.parse.splitpasswd('user:a\fb'))
1138 self.assertEqual(('user', 'a\vb'),urllib.parse.splitpasswd('user:a\vb'))
1139 self.assertEqual(('user', 'a:b'),urllib.parse.splitpasswd('user:a:b'))
Senthil Kumaranc5c5a142012-01-14 19:09:04 +08001140 self.assertEqual(('user', 'a b'),urllib.parse.splitpasswd('user:a b'))
1141 self.assertEqual(('user 2', 'ab'),urllib.parse.splitpasswd('user 2:ab'))
1142 self.assertEqual(('user+1', 'a+b'),urllib.parse.splitpasswd('user+1:a+b'))
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001143
Senthil Kumaran1b7da512011-10-06 00:32:02 +08001144 def test_thishost(self):
1145 """Test the urllib.request.thishost utility function returns a tuple"""
1146 self.assertIsInstance(urllib.request.thishost(), tuple)
1147
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001148
1149class URLopener_Tests(unittest.TestCase):
1150 """Testcase to test the open method of URLopener class."""
1151
1152 def test_quoted_open(self):
1153 class DummyURLopener(urllib.request.URLopener):
1154 def open_spam(self, url):
1155 return url
1156
1157 self.assertEqual(DummyURLopener().open(
1158 'spam://example/ /'),'//example/%20/')
1159
Senthil Kumaran734f0592010-02-20 22:19:04 +00001160 # test the safe characters are not quoted by urlopen
1161 self.assertEqual(DummyURLopener().open(
1162 "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"),
1163 "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/")
1164
Guido van Rossume7ba4952007-06-06 23:52:48 +00001165# Just commented them out.
1166# Can't really tell why keep failing in windows and sparc.
Ezio Melotti13925002011-03-16 11:05:33 +02001167# Everywhere else they work ok, but on those machines, sometimes
Guido van Rossume7ba4952007-06-06 23:52:48 +00001168# fail in one of the tests, sometimes in other. I have a linux, and
1169# the tests go ok.
1170# If anybody has one of the problematic enviroments, please help!
1171# . Facundo
1172#
1173# def server(evt):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001174# import socket, time
Guido van Rossume7ba4952007-06-06 23:52:48 +00001175# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1176# serv.settimeout(3)
1177# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1178# serv.bind(("", 9093))
1179# serv.listen(5)
1180# try:
1181# conn, addr = serv.accept()
1182# conn.send("1 Hola mundo\n")
1183# cantdata = 0
1184# while cantdata < 13:
1185# data = conn.recv(13-cantdata)
1186# cantdata += len(data)
1187# time.sleep(.3)
1188# conn.send("2 No more lines\n")
1189# conn.close()
1190# except socket.timeout:
1191# pass
1192# finally:
1193# serv.close()
1194# evt.set()
1195#
1196# class FTPWrapperTests(unittest.TestCase):
1197#
1198# def setUp(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001199# import ftplib, time, threading
Guido van Rossume7ba4952007-06-06 23:52:48 +00001200# ftplib.FTP.port = 9093
1201# self.evt = threading.Event()
1202# threading.Thread(target=server, args=(self.evt,)).start()
1203# time.sleep(.1)
1204#
1205# def tearDown(self):
1206# self.evt.wait()
1207#
1208# def testBasic(self):
1209# # connects
1210# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
Georg Brandlf78e02b2008-06-10 17:40:04 +00001211# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001212#
1213# def testTimeoutNone(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001214# # global default timeout is ignored
1215# import socket
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001216# self.assertTrue(socket.getdefaulttimeout() is None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001217# socket.setdefaulttimeout(30)
1218# try:
1219# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1220# finally:
Georg Brandlf78e02b2008-06-10 17:40:04 +00001221# socket.setdefaulttimeout(None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001222# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
Georg Brandlf78e02b2008-06-10 17:40:04 +00001223# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001224#
Georg Brandlf78e02b2008-06-10 17:40:04 +00001225# def testTimeoutDefault(self):
1226# # global default timeout is used
1227# import socket
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001228# self.assertTrue(socket.getdefaulttimeout() is None)
Georg Brandlf78e02b2008-06-10 17:40:04 +00001229# socket.setdefaulttimeout(30)
1230# try:
1231# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1232# finally:
1233# socket.setdefaulttimeout(None)
1234# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1235# ftp.close()
1236#
1237# def testTimeoutValue(self):
1238# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
1239# timeout=30)
1240# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1241# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001242
Senthil Kumarande49d642011-10-16 23:54:44 +08001243class RequestTests(unittest.TestCase):
1244 """Unit tests for urllib.request.Request."""
1245
1246 def test_default_values(self):
1247 Request = urllib.request.Request
1248 request = Request("http://www.python.org")
1249 self.assertEqual(request.get_method(), 'GET')
1250 request = Request("http://www.python.org", {})
1251 self.assertEqual(request.get_method(), 'POST')
1252
1253 def test_with_method_arg(self):
1254 Request = urllib.request.Request
1255 request = Request("http://www.python.org", method='HEAD')
1256 self.assertEqual(request.method, 'HEAD')
1257 self.assertEqual(request.get_method(), 'HEAD')
1258 request = Request("http://www.python.org", {}, method='HEAD')
1259 self.assertEqual(request.method, 'HEAD')
1260 self.assertEqual(request.get_method(), 'HEAD')
1261 request = Request("http://www.python.org", method='GET')
1262 self.assertEqual(request.get_method(), 'GET')
1263 request.method = 'HEAD'
1264 self.assertEqual(request.get_method(), 'HEAD')
Skip Montanaro080c9972001-01-28 21:12:22 +00001265
1266
Brett Cannon74bfd702003-04-25 09:39:47 +00001267def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001268 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +00001269 urlopen_FileTests,
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001270 urlopen_HttpTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001271 urlretrieve_FileTests,
Senthil Kumarance260142011-11-01 01:35:17 +08001272 urlretrieve_HttpTests,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001273 ProxyTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001274 QuotingTests,
1275 UnquotingTests,
1276 urlencode_Tests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001277 Pathname_Tests,
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001278 Utility_Tests,
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001279 URLopener_Tests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001280 #FTPWrapperTests,
Senthil Kumarande49d642011-10-16 23:54:44 +08001281 RequestTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001282 )
Brett Cannon74bfd702003-04-25 09:39:47 +00001283
1284
1285
1286if __name__ == '__main__':
1287 test_main()