blob: 4f71b24a0877dfcaffc71cc30ea2f48020ffb189 [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:
Ezio Melotti79b99db2013-02-21 02:41:42 +020033 with support.check_warnings(
34 ('FancyURLopener style of invoking requests is deprecated.',
35 DeprecationWarning)):
36 opener = urllib.request.FancyURLopener()
Jeremy Hylton1afc1692008-06-18 20:49:58 +000037 _urlopener = opener
38 else:
39 opener = _urlopener
40 if data is None:
41 return opener.open(url)
42 else:
43 return opener.open(url, data)
44
Senthil Kumarance260142011-11-01 01:35:17 +080045
46class FakeHTTPMixin(object):
47 def fakehttp(self, fakedata):
48 class FakeSocket(io.BytesIO):
49 io_refs = 1
50
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080051 def sendall(self, data):
52 FakeHTTPConnection.buf = data
Senthil Kumarance260142011-11-01 01:35:17 +080053
54 def makefile(self, *args, **kwds):
55 self.io_refs += 1
56 return self
57
58 def read(self, amt=None):
59 if self.closed:
60 return b""
61 return io.BytesIO.read(self, amt)
62
63 def readline(self, length=None):
64 if self.closed:
65 return b""
66 return io.BytesIO.readline(self, length)
67
68 def close(self):
69 self.io_refs -= 1
70 if self.io_refs == 0:
71 io.BytesIO.close(self)
72
73 class FakeHTTPConnection(http.client.HTTPConnection):
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080074
75 # buffer to store data for verification in urlopen tests.
76 buf = None
77
Senthil Kumarance260142011-11-01 01:35:17 +080078 def connect(self):
79 self.sock = FakeSocket(fakedata)
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080080
Senthil Kumarance260142011-11-01 01:35:17 +080081 self._connection_class = http.client.HTTPConnection
82 http.client.HTTPConnection = FakeHTTPConnection
83
84 def unfakehttp(self):
85 http.client.HTTPConnection = self._connection_class
86
87
Brett Cannon74bfd702003-04-25 09:39:47 +000088class urlopen_FileTests(unittest.TestCase):
89 """Test urlopen() opening a temporary file.
Jeremy Hylton6102e292000-08-31 15:48:10 +000090
Brett Cannon74bfd702003-04-25 09:39:47 +000091 Try to test as much functionality as possible so as to cut down on reliance
Andrew M. Kuchlingf1a2f9e2004-06-29 13:07:53 +000092 on connecting to the Net for testing.
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000093
Brett Cannon74bfd702003-04-25 09:39:47 +000094 """
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000095
Brett Cannon74bfd702003-04-25 09:39:47 +000096 def setUp(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +000097 # Create a temp file to use for testing
98 self.text = bytes("test_urllib: %s\n" % self.__class__.__name__,
99 "ascii")
100 f = open(support.TESTFN, 'wb')
Brett Cannon74bfd702003-04-25 09:39:47 +0000101 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000102 f.write(self.text)
Brett Cannon74bfd702003-04-25 09:39:47 +0000103 finally:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000104 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000105 self.pathname = support.TESTFN
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000106 self.returned_obj = urlopen("file:%s" % self.pathname)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +0000107
Brett Cannon74bfd702003-04-25 09:39:47 +0000108 def tearDown(self):
109 """Shut down the open object"""
110 self.returned_obj.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000111 os.remove(support.TESTFN)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +0000112
Brett Cannon74bfd702003-04-25 09:39:47 +0000113 def test_interface(self):
114 # Make sure object returned by urlopen() has the specified methods
115 for attr in ("read", "readline", "readlines", "fileno",
Christian Heimes9bd667a2008-01-20 15:14:11 +0000116 "close", "info", "geturl", "getcode", "__iter__"):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000117 self.assertTrue(hasattr(self.returned_obj, attr),
Brett Cannon74bfd702003-04-25 09:39:47 +0000118 "object returned by urlopen() lacks %s attribute" %
119 attr)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000120
Brett Cannon74bfd702003-04-25 09:39:47 +0000121 def test_read(self):
122 self.assertEqual(self.text, self.returned_obj.read())
Skip Montanaro080c9972001-01-28 21:12:22 +0000123
Brett Cannon74bfd702003-04-25 09:39:47 +0000124 def test_readline(self):
125 self.assertEqual(self.text, self.returned_obj.readline())
Guido van Rossuma0982942007-07-10 08:30:03 +0000126 self.assertEqual(b'', self.returned_obj.readline(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000127 "calling readline() after exhausting the file did not"
128 " return an empty string")
Skip Montanaro080c9972001-01-28 21:12:22 +0000129
Brett Cannon74bfd702003-04-25 09:39:47 +0000130 def test_readlines(self):
131 lines_list = self.returned_obj.readlines()
132 self.assertEqual(len(lines_list), 1,
133 "readlines() returned the wrong number of lines")
134 self.assertEqual(lines_list[0], self.text,
135 "readlines() returned improper text")
Skip Montanaro080c9972001-01-28 21:12:22 +0000136
Brett Cannon74bfd702003-04-25 09:39:47 +0000137 def test_fileno(self):
138 file_num = self.returned_obj.fileno()
Ezio Melottie9615932010-01-24 19:26:24 +0000139 self.assertIsInstance(file_num, int, "fileno() did not return an int")
Brett Cannon74bfd702003-04-25 09:39:47 +0000140 self.assertEqual(os.read(file_num, len(self.text)), self.text,
141 "Reading on the file descriptor returned by fileno() "
142 "did not return the expected text")
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000143
Brett Cannon74bfd702003-04-25 09:39:47 +0000144 def test_close(self):
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800145 # Test close() by calling it here and then having it be called again
Brett Cannon74bfd702003-04-25 09:39:47 +0000146 # by the tearDown() method for the test
147 self.returned_obj.close()
Skip Montanaro080c9972001-01-28 21:12:22 +0000148
Brett Cannon74bfd702003-04-25 09:39:47 +0000149 def test_info(self):
Ezio Melottie9615932010-01-24 19:26:24 +0000150 self.assertIsInstance(self.returned_obj.info(), email.message.Message)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000151
Brett Cannon74bfd702003-04-25 09:39:47 +0000152 def test_geturl(self):
153 self.assertEqual(self.returned_obj.geturl(), self.pathname)
Skip Montanaro080c9972001-01-28 21:12:22 +0000154
Christian Heimes9bd667a2008-01-20 15:14:11 +0000155 def test_getcode(self):
Florent Xicluna419e3842010-08-08 16:16:07 +0000156 self.assertIsNone(self.returned_obj.getcode())
Christian Heimes9bd667a2008-01-20 15:14:11 +0000157
Brett Cannon74bfd702003-04-25 09:39:47 +0000158 def test_iter(self):
159 # Test iterator
160 # Don't need to count number of iterations since test would fail the
161 # instant it returned anything beyond the first line from the
Raymond Hettinger038018a2011-06-26 14:29:35 +0200162 # comparison.
163 # Use the iterator in the usual implicit way to test for ticket #4608.
164 for line in self.returned_obj:
Brett Cannon74bfd702003-04-25 09:39:47 +0000165 self.assertEqual(line, self.text)
Skip Montanaro080c9972001-01-28 21:12:22 +0000166
Senthil Kumaran3800ea92012-01-21 11:52:48 +0800167 def test_relativelocalfile(self):
168 self.assertRaises(ValueError,urllib.request.urlopen,'./' + self.pathname)
169
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000170class ProxyTests(unittest.TestCase):
171
172 def setUp(self):
Walter Dörwaldb525e182009-04-26 21:39:21 +0000173 # Records changes to env vars
174 self.env = support.EnvironmentVarGuard()
Benjamin Peterson46a99002010-01-09 18:45:30 +0000175 # Delete all proxy related env vars
Antoine Pitroub3a88b52010-10-14 18:31:39 +0000176 for k in list(os.environ):
Antoine Pitrou8c8f1ac2010-10-14 18:32:54 +0000177 if 'proxy' in k.lower():
Benjamin Peterson46a99002010-01-09 18:45:30 +0000178 self.env.unset(k)
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000179
180 def tearDown(self):
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000181 # Restore all proxy related env vars
Walter Dörwaldb525e182009-04-26 21:39:21 +0000182 self.env.__exit__()
183 del self.env
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000184
185 def test_getproxies_environment_keep_no_proxies(self):
Walter Dörwaldb525e182009-04-26 21:39:21 +0000186 self.env.set('NO_PROXY', 'localhost')
187 proxies = urllib.request.getproxies_environment()
188 # getproxies_environment use lowered case truncated (no '_proxy') keys
Florent Xicluna419e3842010-08-08 16:16:07 +0000189 self.assertEqual('localhost', proxies['no'])
Senthil Kumaran89976f12011-08-06 12:27:40 +0800190 # List of no_proxies with space.
191 self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
192 self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com'))
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000193
Senthil Kumarance260142011-11-01 01:35:17 +0800194class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin):
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000195 """Test urlopen() opening a fake http connection."""
196
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000197 def check_read(self, ver):
198 self.fakehttp(b"HTTP/" + ver + b" 200 OK\r\n\r\nHello!")
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000199 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000200 fp = urlopen("http://python.org/")
Jeremy Hylton66dc8c52007-08-04 03:42:26 +0000201 self.assertEqual(fp.readline(), b"Hello!")
202 self.assertEqual(fp.readline(), b"")
Christian Heimes9bd667a2008-01-20 15:14:11 +0000203 self.assertEqual(fp.geturl(), 'http://python.org/')
204 self.assertEqual(fp.getcode(), 200)
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000205 finally:
206 self.unfakehttp()
207
Senthil Kumaran26430412011-04-13 07:01:19 +0800208 def test_url_fragment(self):
209 # Issue #11703: geturl() omits fragments in the original URL.
210 url = 'http://docs.python.org/library/urllib.html#OK'
Senthil Kumaranb17abb12011-04-13 07:22:29 +0800211 self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
Senthil Kumaran26430412011-04-13 07:01:19 +0800212 try:
213 fp = urllib.request.urlopen(url)
214 self.assertEqual(fp.geturl(), url)
215 finally:
216 self.unfakehttp()
217
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800218 def test_willclose(self):
219 self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
Senthil Kumaranacbaa922011-03-20 05:30:16 +0800220 try:
221 resp = urlopen("http://www.python.org")
222 self.assertTrue(resp.fp.will_close)
223 finally:
224 self.unfakehttp()
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800225
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000226 def test_read_0_9(self):
227 # "0.9" response accepted (but not "simple responses" without
228 # a status line)
229 self.check_read(b"0.9")
230
231 def test_read_1_0(self):
232 self.check_read(b"1.0")
233
234 def test_read_1_1(self):
235 self.check_read(b"1.1")
236
Christian Heimes57dddfb2008-01-02 18:30:52 +0000237 def test_read_bogus(self):
238 # urlopen() should raise IOError for many error codes.
239 self.fakehttp(b'''HTTP/1.1 401 Authentication Required
240Date: Wed, 02 Jan 2008 03:03:54 GMT
241Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
242Connection: close
243Content-Type: text/html; charset=iso-8859-1
244''')
245 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000246 self.assertRaises(IOError, urlopen, "http://python.org/")
Christian Heimes57dddfb2008-01-02 18:30:52 +0000247 finally:
248 self.unfakehttp()
249
guido@google.coma119df92011-03-29 11:41:02 -0700250 def test_invalid_redirect(self):
251 # urlopen() should raise IOError for many error codes.
252 self.fakehttp(b'''HTTP/1.1 302 Found
253Date: Wed, 02 Jan 2008 03:03:54 GMT
254Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
255Location: file://guidocomputer.athome.com:/python/license
256Connection: close
257Content-Type: text/html; charset=iso-8859-1
258''')
259 try:
260 self.assertRaises(urllib.error.HTTPError, urlopen,
261 "http://python.org/")
262 finally:
263 self.unfakehttp()
264
Guido van Rossumd8faa362007-04-27 19:54:29 +0000265 def test_empty_socket(self):
Jeremy Hylton66dc8c52007-08-04 03:42:26 +0000266 # urlopen() raises IOError if the underlying socket does not send any
267 # data. (#1680230)
Christian Heimes57dddfb2008-01-02 18:30:52 +0000268 self.fakehttp(b'')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000269 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000270 self.assertRaises(IOError, urlopen, "http://something")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000271 finally:
272 self.unfakehttp()
273
Senthil Kumarancad7b312012-10-27 02:26:46 -0700274 def test_missing_localfile(self):
275 # Test for #10836
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700276 # 3.3 - URLError is not captured, explicit IOError is raised.
277 with self.assertRaises(IOError):
Senthil Kumarancad7b312012-10-27 02:26:46 -0700278 urlopen('file://localhost/a/file/which/doesnot/exists.py')
Senthil Kumarancad7b312012-10-27 02:26:46 -0700279
280 def test_file_notexists(self):
281 fd, tmp_file = tempfile.mkstemp()
282 tmp_fileurl = 'file://localhost/' + tmp_file.replace(os.path.sep, '/')
283 try:
284 self.assertTrue(os.path.exists(tmp_file))
285 with urlopen(tmp_fileurl) as fobj:
286 self.assertTrue(fobj)
287 finally:
288 os.close(fd)
289 os.unlink(tmp_file)
290 self.assertFalse(os.path.exists(tmp_file))
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700291 # 3.3 - IOError instead of URLError
292 with self.assertRaises(IOError):
Senthil Kumarancad7b312012-10-27 02:26:46 -0700293 urlopen(tmp_fileurl)
294
295 def test_ftp_nohost(self):
296 test_ftp_url = 'ftp:///path'
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700297 # 3.3 - IOError instead of URLError
298 with self.assertRaises(IOError):
Senthil Kumarancad7b312012-10-27 02:26:46 -0700299 urlopen(test_ftp_url)
Senthil Kumarancad7b312012-10-27 02:26:46 -0700300
301 def test_ftp_nonexisting(self):
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700302 # 3.3 - IOError instead of URLError
303 with self.assertRaises(IOError):
Senthil Kumarancad7b312012-10-27 02:26:46 -0700304 urlopen('ftp://localhost/a/file/which/doesnot/exists.py')
Senthil Kumarancad7b312012-10-27 02:26:46 -0700305
306
Senthil Kumarande0eb242010-08-01 17:53:37 +0000307 def test_userpass_inurl(self):
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000308 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
Senthil Kumarande0eb242010-08-01 17:53:37 +0000309 try:
310 fp = urlopen("http://user:pass@python.org/")
311 self.assertEqual(fp.readline(), b"Hello!")
312 self.assertEqual(fp.readline(), b"")
313 self.assertEqual(fp.geturl(), 'http://user:pass@python.org/')
314 self.assertEqual(fp.getcode(), 200)
315 finally:
316 self.unfakehttp()
317
Senthil Kumaranc5c5a142012-01-14 19:09:04 +0800318 def test_userpass_inurl_w_spaces(self):
319 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
320 try:
321 userpass = "a b:c d"
322 url = "http://{}@python.org/".format(userpass)
323 fakehttp_wrapper = http.client.HTTPConnection
324 authorization = ("Authorization: Basic %s\r\n" %
325 b64encode(userpass.encode("ASCII")).decode("ASCII"))
326 fp = urlopen(url)
327 # The authorization header must be in place
328 self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8"))
329 self.assertEqual(fp.readline(), b"Hello!")
330 self.assertEqual(fp.readline(), b"")
331 # the spaces are quoted in URL so no match
332 self.assertNotEqual(fp.geturl(), url)
333 self.assertEqual(fp.getcode(), 200)
334 finally:
335 self.unfakehttp()
336
Senthil Kumaran38b968b92012-03-14 13:43:53 -0700337 def test_URLopener_deprecation(self):
338 with support.check_warnings(('',DeprecationWarning)):
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700339 urllib.request.URLopener()
Senthil Kumaran38b968b92012-03-14 13:43:53 -0700340
Brett Cannon19691362003-04-29 05:08:06 +0000341class urlretrieve_FileTests(unittest.TestCase):
Brett Cannon74bfd702003-04-25 09:39:47 +0000342 """Test urllib.urlretrieve() on local files"""
Skip Montanaro080c9972001-01-28 21:12:22 +0000343
Brett Cannon19691362003-04-29 05:08:06 +0000344 def setUp(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000345 # Create a list of temporary files. Each item in the list is a file
346 # name (absolute path or relative to the current working directory).
347 # All files in this list will be deleted in the tearDown method. Note,
348 # this only helps to makes sure temporary files get deleted, but it
349 # does nothing about trying to close files that may still be open. It
350 # is the responsibility of the developer to properly close files even
351 # when exceptional conditions occur.
352 self.tempFiles = []
353
Brett Cannon19691362003-04-29 05:08:06 +0000354 # Create a temporary file.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000355 self.registerFileForCleanUp(support.TESTFN)
Guido van Rossuma0982942007-07-10 08:30:03 +0000356 self.text = b'testing urllib.urlretrieve'
Georg Brandl5a650a22005-08-26 08:51:34 +0000357 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000358 FILE = open(support.TESTFN, 'wb')
Georg Brandl5a650a22005-08-26 08:51:34 +0000359 FILE.write(self.text)
360 FILE.close()
361 finally:
362 try: FILE.close()
363 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000364
365 def tearDown(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000366 # Delete the temporary files.
367 for each in self.tempFiles:
368 try: os.remove(each)
369 except: pass
370
371 def constructLocalFileUrl(self, filePath):
Victor Stinner6c6f8512010-08-07 10:09:35 +0000372 filePath = os.path.abspath(filePath)
373 try:
Marc-André Lemburg8f36af72011-02-25 15:42:01 +0000374 filePath.encode("utf-8")
Victor Stinner6c6f8512010-08-07 10:09:35 +0000375 except UnicodeEncodeError:
376 raise unittest.SkipTest("filePath is not encodable to utf8")
377 return "file://%s" % urllib.request.pathname2url(filePath)
Georg Brandl5a650a22005-08-26 08:51:34 +0000378
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000379 def createNewTempFile(self, data=b""):
Georg Brandl5a650a22005-08-26 08:51:34 +0000380 """Creates a new temporary file containing the specified data,
381 registers the file for deletion during the test fixture tear down, and
382 returns the absolute path of the file."""
383
384 newFd, newFilePath = tempfile.mkstemp()
385 try:
386 self.registerFileForCleanUp(newFilePath)
387 newFile = os.fdopen(newFd, "wb")
388 newFile.write(data)
389 newFile.close()
390 finally:
391 try: newFile.close()
392 except: pass
393 return newFilePath
394
395 def registerFileForCleanUp(self, fileName):
396 self.tempFiles.append(fileName)
Brett Cannon19691362003-04-29 05:08:06 +0000397
398 def test_basic(self):
399 # Make sure that a local file just gets its own location returned and
400 # a headers value is returned.
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000401 result = urllib.request.urlretrieve("file:%s" % support.TESTFN)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000402 self.assertEqual(result[0], support.TESTFN)
Ezio Melottie9615932010-01-24 19:26:24 +0000403 self.assertIsInstance(result[1], email.message.Message,
404 "did not get a email.message.Message instance "
405 "as second returned value")
Brett Cannon19691362003-04-29 05:08:06 +0000406
407 def test_copy(self):
408 # Test that setting the filename argument works.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000409 second_temp = "%s.2" % support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000410 self.registerFileForCleanUp(second_temp)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000411 result = urllib.request.urlretrieve(self.constructLocalFileUrl(
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000412 support.TESTFN), second_temp)
Brett Cannon19691362003-04-29 05:08:06 +0000413 self.assertEqual(second_temp, result[0])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000414 self.assertTrue(os.path.exists(second_temp), "copy of the file was not "
Brett Cannon19691362003-04-29 05:08:06 +0000415 "made")
Alex Martelli01c77c62006-08-24 02:58:11 +0000416 FILE = open(second_temp, 'rb')
Brett Cannon19691362003-04-29 05:08:06 +0000417 try:
418 text = FILE.read()
Brett Cannon19691362003-04-29 05:08:06 +0000419 FILE.close()
Georg Brandl5a650a22005-08-26 08:51:34 +0000420 finally:
421 try: FILE.close()
422 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000423 self.assertEqual(self.text, text)
424
425 def test_reporthook(self):
426 # Make sure that the reporthook works.
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700427 def hooktester(block_count, block_read_size, file_size, count_holder=[0]):
428 self.assertIsInstance(block_count, int)
429 self.assertIsInstance(block_read_size, int)
430 self.assertIsInstance(file_size, int)
431 self.assertEqual(block_count, count_holder[0])
Brett Cannon19691362003-04-29 05:08:06 +0000432 count_holder[0] = count_holder[0] + 1
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000433 second_temp = "%s.2" % support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000434 self.registerFileForCleanUp(second_temp)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000435 urllib.request.urlretrieve(
436 self.constructLocalFileUrl(support.TESTFN),
Georg Brandl5a650a22005-08-26 08:51:34 +0000437 second_temp, hooktester)
438
439 def test_reporthook_0_bytes(self):
440 # Test on zero length file. Should call reporthook only 1 time.
441 report = []
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700442 def hooktester(block_count, block_read_size, file_size, _report=report):
443 _report.append((block_count, block_read_size, file_size))
Georg Brandl5a650a22005-08-26 08:51:34 +0000444 srcFileName = self.createNewTempFile()
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000445 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000446 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000447 self.assertEqual(len(report), 1)
448 self.assertEqual(report[0][2], 0)
449
450 def test_reporthook_5_bytes(self):
451 # Test on 5 byte file. Should call reporthook only 2 times (once when
452 # the "network connection" is established and once when the block is
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700453 # read).
Georg Brandl5a650a22005-08-26 08:51:34 +0000454 report = []
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700455 def hooktester(block_count, block_read_size, file_size, _report=report):
456 _report.append((block_count, block_read_size, file_size))
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000457 srcFileName = self.createNewTempFile(b"x" * 5)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000458 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000459 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000460 self.assertEqual(len(report), 2)
Gregory P. Smith6d9388f2012-11-10 15:12:55 -0800461 self.assertEqual(report[0][2], 5)
462 self.assertEqual(report[1][2], 5)
Georg Brandl5a650a22005-08-26 08:51:34 +0000463
464 def test_reporthook_8193_bytes(self):
465 # Test on 8193 byte file. Should call reporthook only 3 times (once
466 # when the "network connection" is established, once for the next 8192
467 # bytes, and once for the last byte).
468 report = []
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700469 def hooktester(block_count, block_read_size, file_size, _report=report):
470 _report.append((block_count, block_read_size, file_size))
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000471 srcFileName = self.createNewTempFile(b"x" * 8193)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000472 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000473 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000474 self.assertEqual(len(report), 3)
Gregory P. Smith6d9388f2012-11-10 15:12:55 -0800475 self.assertEqual(report[0][2], 8193)
476 self.assertEqual(report[0][1], 8192)
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700477 self.assertEqual(report[1][1], 8192)
Gregory P. Smith6d9388f2012-11-10 15:12:55 -0800478 self.assertEqual(report[2][1], 8192)
Skip Montanaro080c9972001-01-28 21:12:22 +0000479
Senthil Kumarance260142011-11-01 01:35:17 +0800480
481class urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin):
482 """Test urllib.urlretrieve() using fake http connections"""
483
484 def test_short_content_raises_ContentTooShortError(self):
485 self.fakehttp(b'''HTTP/1.1 200 OK
486Date: Wed, 02 Jan 2008 03:03:54 GMT
487Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
488Connection: close
489Content-Length: 100
490Content-Type: text/html; charset=iso-8859-1
491
492FF
493''')
494
495 def _reporthook(par1, par2, par3):
496 pass
497
498 with self.assertRaises(urllib.error.ContentTooShortError):
499 try:
500 urllib.request.urlretrieve('http://example.com/',
501 reporthook=_reporthook)
502 finally:
503 self.unfakehttp()
504
505 def test_short_content_raises_ContentTooShortError_without_reporthook(self):
506 self.fakehttp(b'''HTTP/1.1 200 OK
507Date: Wed, 02 Jan 2008 03:03:54 GMT
508Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
509Connection: close
510Content-Length: 100
511Content-Type: text/html; charset=iso-8859-1
512
513FF
514''')
515 with self.assertRaises(urllib.error.ContentTooShortError):
516 try:
517 urllib.request.urlretrieve('http://example.com/')
518 finally:
519 self.unfakehttp()
520
521
Brett Cannon74bfd702003-04-25 09:39:47 +0000522class QuotingTests(unittest.TestCase):
523 """Tests for urllib.quote() and urllib.quote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000524
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000525 According to RFC 2396 (Uniform Resource Identifiers), to escape a
526 character you write it as '%' + <2 character US-ASCII hex value>.
527 The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a
528 character properly. Case does not matter on the hex letters.
Brett Cannon74bfd702003-04-25 09:39:47 +0000529
530 The various character sets specified are:
Tim Petersc2659cf2003-05-12 20:19:37 +0000531
Brett Cannon74bfd702003-04-25 09:39:47 +0000532 Reserved characters : ";/?:@&=+$,"
533 Have special meaning in URIs and must be escaped if not being used for
534 their special meaning
535 Data characters : letters, digits, and "-_.!~*'()"
536 Unreserved and do not need to be escaped; can be, though, if desired
537 Control characters : 0x00 - 0x1F, 0x7F
538 Have no use in URIs so must be escaped
539 space : 0x20
540 Must be escaped
541 Delimiters : '<>#%"'
542 Must be escaped
543 Unwise : "{}|\^[]`"
544 Must be escaped
Tim Petersc2659cf2003-05-12 20:19:37 +0000545
Brett Cannon74bfd702003-04-25 09:39:47 +0000546 """
547
548 def test_never_quote(self):
549 # Make sure quote() does not quote letters, digits, and "_,.-"
550 do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
551 "abcdefghijklmnopqrstuvwxyz",
552 "0123456789",
553 "_.-"])
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000554 result = urllib.parse.quote(do_not_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000555 self.assertEqual(do_not_quote, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000556 "using quote(): %r != %r" % (do_not_quote, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000557 result = urllib.parse.quote_plus(do_not_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000558 self.assertEqual(do_not_quote, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000559 "using quote_plus(): %r != %r" % (do_not_quote, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000560
561 def test_default_safe(self):
562 # Test '/' is default value for 'safe' parameter
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000563 self.assertEqual(urllib.parse.quote.__defaults__[0], '/')
Brett Cannon74bfd702003-04-25 09:39:47 +0000564
565 def test_safe(self):
566 # Test setting 'safe' parameter does what it should do
567 quote_by_default = "<>"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000568 result = urllib.parse.quote(quote_by_default, safe=quote_by_default)
Brett Cannon74bfd702003-04-25 09:39:47 +0000569 self.assertEqual(quote_by_default, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000570 "using quote(): %r != %r" % (quote_by_default, result))
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000571 result = urllib.parse.quote_plus(quote_by_default,
572 safe=quote_by_default)
Brett Cannon74bfd702003-04-25 09:39:47 +0000573 self.assertEqual(quote_by_default, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000574 "using quote_plus(): %r != %r" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000575 (quote_by_default, result))
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000576 # Safe expressed as bytes rather than str
577 result = urllib.parse.quote(quote_by_default, safe=b"<>")
578 self.assertEqual(quote_by_default, result,
579 "using quote(): %r != %r" % (quote_by_default, result))
580 # "Safe" non-ASCII characters should have no effect
581 # (Since URIs are not allowed to have non-ASCII characters)
582 result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="\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))
587 # Same as above, but using a bytes rather than str
588 result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe=b"\xfc")
589 expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="")
590 self.assertEqual(expect, result,
591 "using quote(): %r != %r" %
592 (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000593
594 def test_default_quoting(self):
595 # Make sure all characters that should be quoted are by default sans
596 # space (separate test for that).
597 should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
598 should_quote.append('<>#%"{}|\^[]`')
599 should_quote.append(chr(127)) # For 0x7F
600 should_quote = ''.join(should_quote)
601 for char in should_quote:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000602 result = urllib.parse.quote(char)
Brett Cannon74bfd702003-04-25 09:39:47 +0000603 self.assertEqual(hexescape(char), result,
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000604 "using quote(): "
605 "%s should be escaped to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000606 (char, hexescape(char), result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000607 result = urllib.parse.quote_plus(char)
Brett Cannon74bfd702003-04-25 09:39:47 +0000608 self.assertEqual(hexescape(char), result,
609 "using quote_plus(): "
Tim Petersc2659cf2003-05-12 20:19:37 +0000610 "%s should be escapes to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000611 (char, hexescape(char), result))
612 del should_quote
613 partial_quote = "ab[]cd"
614 expected = "ab%5B%5Dcd"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000615 result = urllib.parse.quote(partial_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000616 self.assertEqual(expected, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000617 "using quote(): %r != %r" % (expected, result))
Senthil Kumaran305a68e2011-09-13 06:40:27 +0800618 result = urllib.parse.quote_plus(partial_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000619 self.assertEqual(expected, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000620 "using quote_plus(): %r != %r" % (expected, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000621
622 def test_quoting_space(self):
623 # Make sure quote() and quote_plus() handle spaces as specified in
624 # their unique way
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000625 result = urllib.parse.quote(' ')
Brett Cannon74bfd702003-04-25 09:39:47 +0000626 self.assertEqual(result, hexescape(' '),
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000627 "using quote(): %r != %r" % (result, hexescape(' ')))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000628 result = urllib.parse.quote_plus(' ')
Brett Cannon74bfd702003-04-25 09:39:47 +0000629 self.assertEqual(result, '+',
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000630 "using quote_plus(): %r != +" % result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000631 given = "a b cd e f"
632 expect = given.replace(' ', hexescape(' '))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000633 result = urllib.parse.quote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000634 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000635 "using quote(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000636 expect = given.replace(' ', '+')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000637 result = urllib.parse.quote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000638 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000639 "using quote_plus(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000640
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000641 def test_quoting_plus(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000642 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma'),
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000643 'alpha%2Bbeta+gamma')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000644 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', '+'),
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000645 'alpha+beta+gamma')
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000646 # Test with bytes
647 self.assertEqual(urllib.parse.quote_plus(b'alpha+beta gamma'),
648 'alpha%2Bbeta+gamma')
649 # Test with safe bytes
650 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', b'+'),
651 'alpha+beta+gamma')
652
653 def test_quote_bytes(self):
654 # Bytes should quote directly to percent-encoded values
655 given = b"\xa2\xd8ab\xff"
656 expect = "%A2%D8ab%FF"
657 result = urllib.parse.quote(given)
658 self.assertEqual(expect, result,
659 "using quote(): %r != %r" % (expect, result))
660 # Encoding argument should raise type error on bytes input
661 self.assertRaises(TypeError, urllib.parse.quote, given,
662 encoding="latin-1")
663 # quote_from_bytes should work the same
664 result = urllib.parse.quote_from_bytes(given)
665 self.assertEqual(expect, result,
666 "using quote_from_bytes(): %r != %r"
667 % (expect, result))
668
669 def test_quote_with_unicode(self):
670 # Characters in Latin-1 range, encoded by default in UTF-8
671 given = "\xa2\xd8ab\xff"
672 expect = "%C2%A2%C3%98ab%C3%BF"
673 result = urllib.parse.quote(given)
674 self.assertEqual(expect, result,
675 "using quote(): %r != %r" % (expect, result))
676 # Characters in Latin-1 range, encoded by with None (default)
677 result = urllib.parse.quote(given, encoding=None, errors=None)
678 self.assertEqual(expect, result,
679 "using quote(): %r != %r" % (expect, result))
680 # Characters in Latin-1 range, encoded with Latin-1
681 given = "\xa2\xd8ab\xff"
682 expect = "%A2%D8ab%FF"
683 result = urllib.parse.quote(given, encoding="latin-1")
684 self.assertEqual(expect, result,
685 "using quote(): %r != %r" % (expect, result))
686 # Characters in BMP, encoded by default in UTF-8
687 given = "\u6f22\u5b57" # "Kanji"
688 expect = "%E6%BC%A2%E5%AD%97"
689 result = urllib.parse.quote(given)
690 self.assertEqual(expect, result,
691 "using quote(): %r != %r" % (expect, result))
692 # Characters in BMP, encoded with Latin-1
693 given = "\u6f22\u5b57"
694 self.assertRaises(UnicodeEncodeError, urllib.parse.quote, given,
695 encoding="latin-1")
696 # Characters in BMP, encoded with Latin-1, with replace error handling
697 given = "\u6f22\u5b57"
698 expect = "%3F%3F" # "??"
699 result = urllib.parse.quote(given, encoding="latin-1",
700 errors="replace")
701 self.assertEqual(expect, result,
702 "using quote(): %r != %r" % (expect, result))
703 # Characters in BMP, Latin-1, with xmlcharref error handling
704 given = "\u6f22\u5b57"
705 expect = "%26%2328450%3B%26%2323383%3B" # "&#28450;&#23383;"
706 result = urllib.parse.quote(given, encoding="latin-1",
707 errors="xmlcharrefreplace")
708 self.assertEqual(expect, result,
709 "using quote(): %r != %r" % (expect, result))
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000710
Georg Brandlfaf41492009-05-26 18:31:11 +0000711 def test_quote_plus_with_unicode(self):
712 # Encoding (latin-1) test for quote_plus
713 given = "\xa2\xd8 \xff"
714 expect = "%A2%D8+%FF"
715 result = urllib.parse.quote_plus(given, encoding="latin-1")
716 self.assertEqual(expect, result,
717 "using quote_plus(): %r != %r" % (expect, result))
718 # Errors test for quote_plus
719 given = "ab\u6f22\u5b57 cd"
720 expect = "ab%3F%3F+cd"
721 result = urllib.parse.quote_plus(given, encoding="latin-1",
722 errors="replace")
723 self.assertEqual(expect, result,
724 "using quote_plus(): %r != %r" % (expect, result))
725
Senthil Kumarand496c4c2010-07-30 19:34:36 +0000726
Brett Cannon74bfd702003-04-25 09:39:47 +0000727class UnquotingTests(unittest.TestCase):
728 """Tests for unquote() and unquote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000729
Brett Cannon74bfd702003-04-25 09:39:47 +0000730 See the doc string for quoting_Tests for details on quoting and such.
731
732 """
733
734 def test_unquoting(self):
735 # Make sure unquoting of all ASCII values works
736 escape_list = []
737 for num in range(128):
738 given = hexescape(chr(num))
739 expect = chr(num)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000740 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000741 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000742 "using unquote(): %r != %r" % (expect, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000743 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000744 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000745 "using unquote_plus(): %r != %r" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000746 (expect, result))
747 escape_list.append(given)
748 escape_string = ''.join(escape_list)
749 del escape_list
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000750 result = urllib.parse.unquote(escape_string)
Brett Cannon74bfd702003-04-25 09:39:47 +0000751 self.assertEqual(result.count('%'), 1,
Brett Cannon74bfd702003-04-25 09:39:47 +0000752 "using unquote(): not all characters escaped: "
753 "%s" % result)
Georg Brandl604ef372010-07-31 08:20:02 +0000754 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None)
755 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ())
Florent Xicluna62829dc2010-08-14 20:51:58 +0000756 with support.check_warnings(('', BytesWarning), quiet=True):
757 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, b'')
Brett Cannon74bfd702003-04-25 09:39:47 +0000758
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000759 def test_unquoting_badpercent(self):
760 # Test unquoting on bad percent-escapes
761 given = '%xab'
762 expect = given
763 result = urllib.parse.unquote(given)
764 self.assertEqual(expect, result, "using unquote(): %r != %r"
765 % (expect, result))
766 given = '%x'
767 expect = given
768 result = urllib.parse.unquote(given)
769 self.assertEqual(expect, result, "using unquote(): %r != %r"
770 % (expect, result))
771 given = '%'
772 expect = given
773 result = urllib.parse.unquote(given)
774 self.assertEqual(expect, result, "using unquote(): %r != %r"
775 % (expect, result))
776 # unquote_to_bytes
777 given = '%xab'
778 expect = bytes(given, 'ascii')
779 result = urllib.parse.unquote_to_bytes(given)
780 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
781 % (expect, result))
782 given = '%x'
783 expect = bytes(given, 'ascii')
784 result = urllib.parse.unquote_to_bytes(given)
785 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
786 % (expect, result))
787 given = '%'
788 expect = bytes(given, 'ascii')
789 result = urllib.parse.unquote_to_bytes(given)
790 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
791 % (expect, result))
Georg Brandl604ef372010-07-31 08:20:02 +0000792 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, None)
793 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, ())
Senthil Kumaran79e17f62010-07-19 18:17:19 +0000794
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000795 def test_unquoting_mixed_case(self):
796 # Test unquoting on mixed-case hex digits in the percent-escapes
797 given = '%Ab%eA'
798 expect = b'\xab\xea'
799 result = urllib.parse.unquote_to_bytes(given)
800 self.assertEqual(expect, result,
801 "using unquote_to_bytes(): %r != %r"
802 % (expect, result))
803
Brett Cannon74bfd702003-04-25 09:39:47 +0000804 def test_unquoting_parts(self):
805 # Make sure unquoting works when have non-quoted characters
806 # interspersed
807 given = 'ab%sd' % hexescape('c')
808 expect = "abcd"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000809 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000810 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000811 "using quote(): %r != %r" % (expect, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000812 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000813 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000814 "using unquote_plus(): %r != %r" % (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +0000815
Brett Cannon74bfd702003-04-25 09:39:47 +0000816 def test_unquoting_plus(self):
817 # Test difference between unquote() and unquote_plus()
818 given = "are+there+spaces..."
819 expect = given
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000820 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000821 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000822 "using unquote(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000823 expect = given.replace('+', ' ')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000824 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000825 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000826 "using unquote_plus(): %r != %r" % (expect, result))
827
828 def test_unquote_to_bytes(self):
829 given = 'br%C3%BCckner_sapporo_20050930.doc'
830 expect = b'br\xc3\xbcckner_sapporo_20050930.doc'
831 result = urllib.parse.unquote_to_bytes(given)
832 self.assertEqual(expect, result,
833 "using unquote_to_bytes(): %r != %r"
834 % (expect, result))
835 # Test on a string with unescaped non-ASCII characters
836 # (Technically an invalid URI; expect those characters to be UTF-8
837 # encoded).
838 result = urllib.parse.unquote_to_bytes("\u6f22%C3%BC")
839 expect = b'\xe6\xbc\xa2\xc3\xbc' # UTF-8 for "\u6f22\u00fc"
840 self.assertEqual(expect, result,
841 "using unquote_to_bytes(): %r != %r"
842 % (expect, result))
843 # Test with a bytes as input
844 given = b'%A2%D8ab%FF'
845 expect = b'\xa2\xd8ab\xff'
846 result = urllib.parse.unquote_to_bytes(given)
847 self.assertEqual(expect, result,
848 "using unquote_to_bytes(): %r != %r"
849 % (expect, result))
850 # Test with a bytes as input, with unescaped non-ASCII bytes
851 # (Technically an invalid URI; expect those bytes to be preserved)
852 given = b'%A2\xd8ab%FF'
853 expect = b'\xa2\xd8ab\xff'
854 result = urllib.parse.unquote_to_bytes(given)
855 self.assertEqual(expect, result,
856 "using unquote_to_bytes(): %r != %r"
857 % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000858
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000859 def test_unquote_with_unicode(self):
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000860 # Characters in the Latin-1 range, encoded with UTF-8
861 given = 'br%C3%BCckner_sapporo_20050930.doc'
862 expect = 'br\u00fcckner_sapporo_20050930.doc'
863 result = urllib.parse.unquote(given)
864 self.assertEqual(expect, result,
865 "using unquote(): %r != %r" % (expect, result))
866 # Characters in the Latin-1 range, encoded with None (default)
867 result = urllib.parse.unquote(given, encoding=None, errors=None)
868 self.assertEqual(expect, result,
869 "using unquote(): %r != %r" % (expect, result))
870
871 # Characters in the Latin-1 range, encoded with Latin-1
872 result = urllib.parse.unquote('br%FCckner_sapporo_20050930.doc',
873 encoding="latin-1")
874 expect = 'br\u00fcckner_sapporo_20050930.doc'
875 self.assertEqual(expect, result,
876 "using unquote(): %r != %r" % (expect, result))
877
878 # Characters in BMP, encoded with UTF-8
879 given = "%E6%BC%A2%E5%AD%97"
880 expect = "\u6f22\u5b57" # "Kanji"
881 result = urllib.parse.unquote(given)
882 self.assertEqual(expect, result,
883 "using unquote(): %r != %r" % (expect, result))
884
885 # Decode with UTF-8, invalid sequence
886 given = "%F3%B1"
887 expect = "\ufffd" # Replacement character
888 result = urllib.parse.unquote(given)
889 self.assertEqual(expect, result,
890 "using unquote(): %r != %r" % (expect, result))
891
892 # Decode with UTF-8, invalid sequence, replace errors
893 result = urllib.parse.unquote(given, errors="replace")
894 self.assertEqual(expect, result,
895 "using unquote(): %r != %r" % (expect, result))
896
897 # Decode with UTF-8, invalid sequence, ignoring errors
898 given = "%F3%B1"
899 expect = ""
900 result = urllib.parse.unquote(given, errors="ignore")
901 self.assertEqual(expect, result,
902 "using unquote(): %r != %r" % (expect, result))
903
904 # A mix of non-ASCII and percent-encoded characters, UTF-8
905 result = urllib.parse.unquote("\u6f22%C3%BC")
906 expect = '\u6f22\u00fc'
907 self.assertEqual(expect, result,
908 "using unquote(): %r != %r" % (expect, result))
909
910 # A mix of non-ASCII and percent-encoded characters, Latin-1
911 # (Note, the string contains non-Latin-1-representable characters)
912 result = urllib.parse.unquote("\u6f22%FC", encoding="latin-1")
913 expect = '\u6f22\u00fc'
914 self.assertEqual(expect, result,
915 "using unquote(): %r != %r" % (expect, result))
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000916
Brett Cannon74bfd702003-04-25 09:39:47 +0000917class urlencode_Tests(unittest.TestCase):
918 """Tests for urlencode()"""
919
920 def help_inputtype(self, given, test_type):
921 """Helper method for testing different input types.
Tim Petersc2659cf2003-05-12 20:19:37 +0000922
Brett Cannon74bfd702003-04-25 09:39:47 +0000923 'given' must lead to only the pairs:
924 * 1st, 1
925 * 2nd, 2
926 * 3rd, 3
Tim Petersc2659cf2003-05-12 20:19:37 +0000927
Brett Cannon74bfd702003-04-25 09:39:47 +0000928 Test cannot assume anything about order. Docs make no guarantee and
929 have possible dictionary input.
Tim Petersc2659cf2003-05-12 20:19:37 +0000930
Brett Cannon74bfd702003-04-25 09:39:47 +0000931 """
932 expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000933 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000934 for expected in expect_somewhere:
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000935 self.assertIn(expected, result,
Brett Cannon74bfd702003-04-25 09:39:47 +0000936 "testing %s: %s not found in %s" %
937 (test_type, expected, result))
938 self.assertEqual(result.count('&'), 2,
939 "testing %s: expected 2 '&'s; got %s" %
940 (test_type, result.count('&')))
941 amp_location = result.index('&')
942 on_amp_left = result[amp_location - 1]
943 on_amp_right = result[amp_location + 1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000944 self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000945 "testing %s: '&' not located in proper place in %s" %
946 (test_type, result))
947 self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
948 "testing %s: "
949 "unexpected number of characters: %s != %s" %
950 (test_type, len(result), (5 * 3) + 2))
951
952 def test_using_mapping(self):
953 # Test passing in a mapping object as an argument.
954 self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
955 "using dict as input type")
956
957 def test_using_sequence(self):
958 # Test passing in a sequence of two-item sequences as an argument.
959 self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
960 "using sequence of two-item tuples as input")
961
962 def test_quoting(self):
963 # Make sure keys and values are quoted using quote_plus()
964 given = {"&":"="}
965 expect = "%s=%s" % (hexescape('&'), hexescape('='))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000966 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000967 self.assertEqual(expect, result)
968 given = {"key name":"A bunch of pluses"}
969 expect = "key+name=A+bunch+of+pluses"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000970 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000971 self.assertEqual(expect, result)
972
973 def test_doseq(self):
974 # Test that passing True for 'doseq' parameter works correctly
975 given = {'sequence':['1', '2', '3']}
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000976 expect = "sequence=%s" % urllib.parse.quote_plus(str(['1', '2', '3']))
977 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000978 self.assertEqual(expect, result)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000979 result = urllib.parse.urlencode(given, True)
Brett Cannon74bfd702003-04-25 09:39:47 +0000980 for value in given["sequence"]:
981 expect = "sequence=%s" % value
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000982 self.assertIn(expect, result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000983 self.assertEqual(result.count('&'), 2,
984 "Expected 2 '&'s, got %s" % result.count('&'))
985
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000986 def test_empty_sequence(self):
987 self.assertEqual("", urllib.parse.urlencode({}))
988 self.assertEqual("", urllib.parse.urlencode([]))
989
990 def test_nonstring_values(self):
991 self.assertEqual("a=1", urllib.parse.urlencode({"a": 1}))
992 self.assertEqual("a=None", urllib.parse.urlencode({"a": None}))
993
994 def test_nonstring_seq_values(self):
995 self.assertEqual("a=1&a=2", urllib.parse.urlencode({"a": [1, 2]}, True))
996 self.assertEqual("a=None&a=a",
997 urllib.parse.urlencode({"a": [None, "a"]}, True))
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100998 data = collections.OrderedDict([("a", 1), ("b", 1)])
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000999 self.assertEqual("a=a&a=b",
Georg Brandl2daf6ae2012-02-20 19:54:16 +01001000 urllib.parse.urlencode({"a": data}, True))
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +00001001
Senthil Kumarandf022da2010-07-03 17:48:22 +00001002 def test_urlencode_encoding(self):
1003 # ASCII encoding. Expect %3F with errors="replace'
1004 given = (('\u00a0', '\u00c1'),)
1005 expect = '%3F=%3F'
1006 result = urllib.parse.urlencode(given, encoding="ASCII", errors="replace")
1007 self.assertEqual(expect, result)
1008
1009 # Default is UTF-8 encoding.
1010 given = (('\u00a0', '\u00c1'),)
1011 expect = '%C2%A0=%C3%81'
1012 result = urllib.parse.urlencode(given)
1013 self.assertEqual(expect, result)
1014
1015 # Latin-1 encoding.
1016 given = (('\u00a0', '\u00c1'),)
1017 expect = '%A0=%C1'
1018 result = urllib.parse.urlencode(given, encoding="latin-1")
1019 self.assertEqual(expect, result)
1020
1021 def test_urlencode_encoding_doseq(self):
1022 # ASCII Encoding. Expect %3F with errors="replace'
1023 given = (('\u00a0', '\u00c1'),)
1024 expect = '%3F=%3F'
1025 result = urllib.parse.urlencode(given, doseq=True,
1026 encoding="ASCII", errors="replace")
1027 self.assertEqual(expect, result)
1028
1029 # ASCII Encoding. On a sequence of values.
1030 given = (("\u00a0", (1, "\u00c1")),)
1031 expect = '%3F=1&%3F=%3F'
1032 result = urllib.parse.urlencode(given, True,
1033 encoding="ASCII", errors="replace")
1034 self.assertEqual(expect, result)
1035
1036 # Utf-8
1037 given = (("\u00a0", "\u00c1"),)
1038 expect = '%C2%A0=%C3%81'
1039 result = urllib.parse.urlencode(given, True)
1040 self.assertEqual(expect, result)
1041
1042 given = (("\u00a0", (42, "\u00c1")),)
1043 expect = '%C2%A0=42&%C2%A0=%C3%81'
1044 result = urllib.parse.urlencode(given, True)
1045 self.assertEqual(expect, result)
1046
1047 # latin-1
1048 given = (("\u00a0", "\u00c1"),)
1049 expect = '%A0=%C1'
1050 result = urllib.parse.urlencode(given, True, encoding="latin-1")
1051 self.assertEqual(expect, result)
1052
1053 given = (("\u00a0", (42, "\u00c1")),)
1054 expect = '%A0=42&%A0=%C1'
1055 result = urllib.parse.urlencode(given, True, encoding="latin-1")
1056 self.assertEqual(expect, result)
1057
1058 def test_urlencode_bytes(self):
1059 given = ((b'\xa0\x24', b'\xc1\x24'),)
1060 expect = '%A0%24=%C1%24'
1061 result = urllib.parse.urlencode(given)
1062 self.assertEqual(expect, result)
1063 result = urllib.parse.urlencode(given, True)
1064 self.assertEqual(expect, result)
1065
1066 # Sequence of values
1067 given = ((b'\xa0\x24', (42, b'\xc1\x24')),)
1068 expect = '%A0%24=42&%A0%24=%C1%24'
1069 result = urllib.parse.urlencode(given, True)
1070 self.assertEqual(expect, result)
1071
1072 def test_urlencode_encoding_safe_parameter(self):
1073
1074 # Send '$' (\x24) as safe character
1075 # Default utf-8 encoding
1076
1077 given = ((b'\xa0\x24', b'\xc1\x24'),)
1078 result = urllib.parse.urlencode(given, safe=":$")
1079 expect = '%A0$=%C1$'
1080 self.assertEqual(expect, result)
1081
1082 given = ((b'\xa0\x24', b'\xc1\x24'),)
1083 result = urllib.parse.urlencode(given, doseq=True, safe=":$")
1084 expect = '%A0$=%C1$'
1085 self.assertEqual(expect, result)
1086
1087 # Safe parameter in sequence
1088 given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
1089 expect = '%A0$=%C1$&%A0$=13&%A0$=42'
1090 result = urllib.parse.urlencode(given, True, safe=":$")
1091 self.assertEqual(expect, result)
1092
1093 # Test all above in latin-1 encoding
1094
1095 given = ((b'\xa0\x24', b'\xc1\x24'),)
1096 result = urllib.parse.urlencode(given, safe=":$",
1097 encoding="latin-1")
1098 expect = '%A0$=%C1$'
1099 self.assertEqual(expect, result)
1100
1101 given = ((b'\xa0\x24', b'\xc1\x24'),)
1102 expect = '%A0$=%C1$'
1103 result = urllib.parse.urlencode(given, doseq=True, safe=":$",
1104 encoding="latin-1")
1105
1106 given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
1107 expect = '%A0$=%C1$&%A0$=13&%A0$=42'
1108 result = urllib.parse.urlencode(given, True, safe=":$",
1109 encoding="latin-1")
1110 self.assertEqual(expect, result)
1111
Brett Cannon74bfd702003-04-25 09:39:47 +00001112class Pathname_Tests(unittest.TestCase):
1113 """Test pathname2url() and url2pathname()"""
1114
1115 def test_basic(self):
1116 # Make sure simple tests pass
1117 expected_path = os.path.join("parts", "of", "a", "path")
1118 expected_url = "parts/of/a/path"
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001119 result = urllib.request.pathname2url(expected_path)
Brett Cannon74bfd702003-04-25 09:39:47 +00001120 self.assertEqual(expected_url, result,
1121 "pathname2url() failed; %s != %s" %
1122 (result, expected_url))
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001123 result = urllib.request.url2pathname(expected_url)
Brett Cannon74bfd702003-04-25 09:39:47 +00001124 self.assertEqual(expected_path, result,
1125 "url2pathame() failed; %s != %s" %
1126 (result, expected_path))
1127
1128 def test_quoting(self):
1129 # Test automatic quoting and unquoting works for pathnam2url() and
1130 # url2pathname() respectively
1131 given = os.path.join("needs", "quot=ing", "here")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001132 expect = "needs/%s/here" % urllib.parse.quote("quot=ing")
1133 result = urllib.request.pathname2url(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001134 self.assertEqual(expect, result,
1135 "pathname2url() failed; %s != %s" %
1136 (expect, result))
1137 expect = given
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001138 result = urllib.request.url2pathname(result)
Brett Cannon74bfd702003-04-25 09:39:47 +00001139 self.assertEqual(expect, result,
1140 "url2pathname() failed; %s != %s" %
1141 (expect, result))
1142 given = os.path.join("make sure", "using_quote")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001143 expect = "%s/using_quote" % urllib.parse.quote("make sure")
1144 result = urllib.request.pathname2url(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001145 self.assertEqual(expect, result,
1146 "pathname2url() failed; %s != %s" %
1147 (expect, result))
1148 given = "make+sure/using_unquote"
1149 expect = os.path.join("make+sure", "using_unquote")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001150 result = urllib.request.url2pathname(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001151 self.assertEqual(expect, result,
1152 "url2pathname() failed; %s != %s" %
1153 (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +00001154
Senthil Kumaran2d2ea1b2011-04-14 13:16:30 +08001155 @unittest.skipUnless(sys.platform == 'win32',
1156 'test specific to the urllib.url2path function.')
1157 def test_ntpath(self):
1158 given = ('/C:/', '///C:/', '/C|//')
1159 expect = 'C:\\'
1160 for url in given:
1161 result = urllib.request.url2pathname(url)
1162 self.assertEqual(expect, result,
1163 'urllib.request..url2pathname() failed; %s != %s' %
1164 (expect, result))
1165 given = '///C|/path'
1166 expect = 'C:\\path'
1167 result = urllib.request.url2pathname(given)
1168 self.assertEqual(expect, result,
1169 'urllib.request.url2pathname() failed; %s != %s' %
1170 (expect, result))
1171
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001172class Utility_Tests(unittest.TestCase):
1173 """Testcase to test the various utility functions in the urllib."""
1174
1175 def test_splitpasswd(self):
1176 """Some of password examples are not sensible, but it is added to
1177 confirming to RFC2617 and addressing issue4675.
1178 """
1179 self.assertEqual(('user', 'ab'),urllib.parse.splitpasswd('user:ab'))
1180 self.assertEqual(('user', 'a\nb'),urllib.parse.splitpasswd('user:a\nb'))
1181 self.assertEqual(('user', 'a\tb'),urllib.parse.splitpasswd('user:a\tb'))
1182 self.assertEqual(('user', 'a\rb'),urllib.parse.splitpasswd('user:a\rb'))
1183 self.assertEqual(('user', 'a\fb'),urllib.parse.splitpasswd('user:a\fb'))
1184 self.assertEqual(('user', 'a\vb'),urllib.parse.splitpasswd('user:a\vb'))
1185 self.assertEqual(('user', 'a:b'),urllib.parse.splitpasswd('user:a:b'))
Senthil Kumaranc5c5a142012-01-14 19:09:04 +08001186 self.assertEqual(('user', 'a b'),urllib.parse.splitpasswd('user:a b'))
1187 self.assertEqual(('user 2', 'ab'),urllib.parse.splitpasswd('user 2:ab'))
1188 self.assertEqual(('user+1', 'a+b'),urllib.parse.splitpasswd('user+1:a+b'))
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001189
Senthil Kumaran1b7da512011-10-06 00:32:02 +08001190 def test_thishost(self):
1191 """Test the urllib.request.thishost utility function returns a tuple"""
1192 self.assertIsInstance(urllib.request.thishost(), tuple)
1193
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001194
1195class URLopener_Tests(unittest.TestCase):
1196 """Testcase to test the open method of URLopener class."""
1197
1198 def test_quoted_open(self):
1199 class DummyURLopener(urllib.request.URLopener):
1200 def open_spam(self, url):
1201 return url
Ezio Melotti79b99db2013-02-21 02:41:42 +02001202 with support.check_warnings(
1203 ('DummyURLopener style of invoking requests is deprecated.',
1204 DeprecationWarning)):
1205 self.assertEqual(DummyURLopener().open(
1206 'spam://example/ /'),'//example/%20/')
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001207
Ezio Melotti79b99db2013-02-21 02:41:42 +02001208 # test the safe characters are not quoted by urlopen
1209 self.assertEqual(DummyURLopener().open(
1210 "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"),
1211 "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/")
Senthil Kumaran734f0592010-02-20 22:19:04 +00001212
Guido van Rossume7ba4952007-06-06 23:52:48 +00001213# Just commented them out.
1214# Can't really tell why keep failing in windows and sparc.
Ezio Melotti13925002011-03-16 11:05:33 +02001215# Everywhere else they work ok, but on those machines, sometimes
Guido van Rossume7ba4952007-06-06 23:52:48 +00001216# fail in one of the tests, sometimes in other. I have a linux, and
1217# the tests go ok.
1218# If anybody has one of the problematic enviroments, please help!
1219# . Facundo
1220#
1221# def server(evt):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001222# import socket, time
Guido van Rossume7ba4952007-06-06 23:52:48 +00001223# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1224# serv.settimeout(3)
1225# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1226# serv.bind(("", 9093))
1227# serv.listen(5)
1228# try:
1229# conn, addr = serv.accept()
1230# conn.send("1 Hola mundo\n")
1231# cantdata = 0
1232# while cantdata < 13:
1233# data = conn.recv(13-cantdata)
1234# cantdata += len(data)
1235# time.sleep(.3)
1236# conn.send("2 No more lines\n")
1237# conn.close()
1238# except socket.timeout:
1239# pass
1240# finally:
1241# serv.close()
1242# evt.set()
1243#
1244# class FTPWrapperTests(unittest.TestCase):
1245#
1246# def setUp(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001247# import ftplib, time, threading
Guido van Rossume7ba4952007-06-06 23:52:48 +00001248# ftplib.FTP.port = 9093
1249# self.evt = threading.Event()
1250# threading.Thread(target=server, args=(self.evt,)).start()
1251# time.sleep(.1)
1252#
1253# def tearDown(self):
1254# self.evt.wait()
1255#
1256# def testBasic(self):
1257# # connects
1258# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
Georg Brandlf78e02b2008-06-10 17:40:04 +00001259# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001260#
1261# def testTimeoutNone(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001262# # global default timeout is ignored
1263# import socket
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001264# self.assertTrue(socket.getdefaulttimeout() is None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001265# socket.setdefaulttimeout(30)
1266# try:
1267# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1268# finally:
Georg Brandlf78e02b2008-06-10 17:40:04 +00001269# socket.setdefaulttimeout(None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001270# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
Georg Brandlf78e02b2008-06-10 17:40:04 +00001271# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001272#
Georg Brandlf78e02b2008-06-10 17:40:04 +00001273# def testTimeoutDefault(self):
1274# # global default timeout is used
1275# import socket
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001276# self.assertTrue(socket.getdefaulttimeout() is None)
Georg Brandlf78e02b2008-06-10 17:40:04 +00001277# socket.setdefaulttimeout(30)
1278# try:
1279# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1280# finally:
1281# socket.setdefaulttimeout(None)
1282# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1283# ftp.close()
1284#
1285# def testTimeoutValue(self):
1286# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
1287# timeout=30)
1288# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1289# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001290
Senthil Kumarande49d642011-10-16 23:54:44 +08001291class RequestTests(unittest.TestCase):
1292 """Unit tests for urllib.request.Request."""
1293
1294 def test_default_values(self):
1295 Request = urllib.request.Request
1296 request = Request("http://www.python.org")
1297 self.assertEqual(request.get_method(), 'GET')
1298 request = Request("http://www.python.org", {})
1299 self.assertEqual(request.get_method(), 'POST')
1300
1301 def test_with_method_arg(self):
1302 Request = urllib.request.Request
1303 request = Request("http://www.python.org", method='HEAD')
1304 self.assertEqual(request.method, 'HEAD')
1305 self.assertEqual(request.get_method(), 'HEAD')
1306 request = Request("http://www.python.org", {}, method='HEAD')
1307 self.assertEqual(request.method, 'HEAD')
1308 self.assertEqual(request.get_method(), 'HEAD')
1309 request = Request("http://www.python.org", method='GET')
1310 self.assertEqual(request.get_method(), 'GET')
1311 request.method = 'HEAD'
1312 self.assertEqual(request.get_method(), 'HEAD')
Skip Montanaro080c9972001-01-28 21:12:22 +00001313
1314
Brett Cannon74bfd702003-04-25 09:39:47 +00001315def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001316 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +00001317 urlopen_FileTests,
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001318 urlopen_HttpTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001319 urlretrieve_FileTests,
Senthil Kumarance260142011-11-01 01:35:17 +08001320 urlretrieve_HttpTests,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001321 ProxyTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001322 QuotingTests,
1323 UnquotingTests,
1324 urlencode_Tests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001325 Pathname_Tests,
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001326 Utility_Tests,
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001327 URLopener_Tests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001328 #FTPWrapperTests,
Senthil Kumarande49d642011-10-16 23:54:44 +08001329 RequestTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001330 )
Brett Cannon74bfd702003-04-25 09:39:47 +00001331
1332
1333
1334if __name__ == '__main__':
1335 test_main()