blob: 7a34a05d05851ea18ecb2d8b4407e6eda2cbc7c1 [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
Senthil Kumaran277e9092013-04-10 20:51:19 -070014from nturl2path import url2pathname, pathname2url
Jeremy Hylton6102e292000-08-31 15:48:10 +000015
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080016from base64 import b64encode
Georg Brandl2daf6ae2012-02-20 19:54:16 +010017import collections
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080018
Brett Cannon74bfd702003-04-25 09:39:47 +000019def hexescape(char):
20 """Escape char as RFC 2396 specifies"""
21 hex_repr = hex(ord(char))[2:].upper()
22 if len(hex_repr) == 1:
23 hex_repr = "0%s" % hex_repr
24 return "%" + hex_repr
Jeremy Hylton6102e292000-08-31 15:48:10 +000025
Jeremy Hylton1afc1692008-06-18 20:49:58 +000026# Shortcut for testing FancyURLopener
27_urlopener = None
Senthil Kumaran277e9092013-04-10 20:51:19 -070028
29
Jeremy Hylton1afc1692008-06-18 20:49:58 +000030def urlopen(url, data=None, proxies=None):
31 """urlopen(url [, data]) -> open file-like object"""
32 global _urlopener
33 if proxies is not None:
34 opener = urllib.request.FancyURLopener(proxies=proxies)
35 elif not _urlopener:
Ezio Melotti79b99db2013-02-21 02:41:42 +020036 with support.check_warnings(
37 ('FancyURLopener style of invoking requests is deprecated.',
38 DeprecationWarning)):
39 opener = urllib.request.FancyURLopener()
Jeremy Hylton1afc1692008-06-18 20:49:58 +000040 _urlopener = opener
41 else:
42 opener = _urlopener
43 if data is None:
44 return opener.open(url)
45 else:
46 return opener.open(url, data)
47
Senthil Kumarance260142011-11-01 01:35:17 +080048
49class FakeHTTPMixin(object):
50 def fakehttp(self, fakedata):
51 class FakeSocket(io.BytesIO):
52 io_refs = 1
53
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080054 def sendall(self, data):
55 FakeHTTPConnection.buf = data
Senthil Kumarance260142011-11-01 01:35:17 +080056
57 def makefile(self, *args, **kwds):
58 self.io_refs += 1
59 return self
60
61 def read(self, amt=None):
62 if self.closed:
63 return b""
64 return io.BytesIO.read(self, amt)
65
66 def readline(self, length=None):
67 if self.closed:
68 return b""
69 return io.BytesIO.readline(self, length)
70
71 def close(self):
72 self.io_refs -= 1
73 if self.io_refs == 0:
74 io.BytesIO.close(self)
75
76 class FakeHTTPConnection(http.client.HTTPConnection):
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080077
78 # buffer to store data for verification in urlopen tests.
79 buf = None
80
Senthil Kumarance260142011-11-01 01:35:17 +080081 def connect(self):
82 self.sock = FakeSocket(fakedata)
Senthil Kumaranc5c5a142012-01-14 19:09:04 +080083
Senthil Kumarance260142011-11-01 01:35:17 +080084 self._connection_class = http.client.HTTPConnection
85 http.client.HTTPConnection = FakeHTTPConnection
86
87 def unfakehttp(self):
88 http.client.HTTPConnection = self._connection_class
89
90
Brett Cannon74bfd702003-04-25 09:39:47 +000091class urlopen_FileTests(unittest.TestCase):
92 """Test urlopen() opening a temporary file.
Jeremy Hylton6102e292000-08-31 15:48:10 +000093
Brett Cannon74bfd702003-04-25 09:39:47 +000094 Try to test as much functionality as possible so as to cut down on reliance
Andrew M. Kuchlingf1a2f9e2004-06-29 13:07:53 +000095 on connecting to the Net for testing.
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000096
Brett Cannon74bfd702003-04-25 09:39:47 +000097 """
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000098
Brett Cannon74bfd702003-04-25 09:39:47 +000099 def setUp(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000100 # Create a temp file to use for testing
101 self.text = bytes("test_urllib: %s\n" % self.__class__.__name__,
102 "ascii")
103 f = open(support.TESTFN, 'wb')
Brett Cannon74bfd702003-04-25 09:39:47 +0000104 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000105 f.write(self.text)
Brett Cannon74bfd702003-04-25 09:39:47 +0000106 finally:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000107 f.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000108 self.pathname = support.TESTFN
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000109 self.returned_obj = urlopen("file:%s" % self.pathname)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +0000110
Brett Cannon74bfd702003-04-25 09:39:47 +0000111 def tearDown(self):
112 """Shut down the open object"""
113 self.returned_obj.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000114 os.remove(support.TESTFN)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +0000115
Brett Cannon74bfd702003-04-25 09:39:47 +0000116 def test_interface(self):
117 # Make sure object returned by urlopen() has the specified methods
118 for attr in ("read", "readline", "readlines", "fileno",
Christian Heimes9bd667a2008-01-20 15:14:11 +0000119 "close", "info", "geturl", "getcode", "__iter__"):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000120 self.assertTrue(hasattr(self.returned_obj, attr),
Brett Cannon74bfd702003-04-25 09:39:47 +0000121 "object returned by urlopen() lacks %s attribute" %
122 attr)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000123
Brett Cannon74bfd702003-04-25 09:39:47 +0000124 def test_read(self):
125 self.assertEqual(self.text, self.returned_obj.read())
Skip Montanaro080c9972001-01-28 21:12:22 +0000126
Brett Cannon74bfd702003-04-25 09:39:47 +0000127 def test_readline(self):
128 self.assertEqual(self.text, self.returned_obj.readline())
Guido van Rossuma0982942007-07-10 08:30:03 +0000129 self.assertEqual(b'', self.returned_obj.readline(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000130 "calling readline() after exhausting the file did not"
131 " return an empty string")
Skip Montanaro080c9972001-01-28 21:12:22 +0000132
Brett Cannon74bfd702003-04-25 09:39:47 +0000133 def test_readlines(self):
134 lines_list = self.returned_obj.readlines()
135 self.assertEqual(len(lines_list), 1,
136 "readlines() returned the wrong number of lines")
137 self.assertEqual(lines_list[0], self.text,
138 "readlines() returned improper text")
Skip Montanaro080c9972001-01-28 21:12:22 +0000139
Brett Cannon74bfd702003-04-25 09:39:47 +0000140 def test_fileno(self):
141 file_num = self.returned_obj.fileno()
Ezio Melottie9615932010-01-24 19:26:24 +0000142 self.assertIsInstance(file_num, int, "fileno() did not return an int")
Brett Cannon74bfd702003-04-25 09:39:47 +0000143 self.assertEqual(os.read(file_num, len(self.text)), self.text,
144 "Reading on the file descriptor returned by fileno() "
145 "did not return the expected text")
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000146
Brett Cannon74bfd702003-04-25 09:39:47 +0000147 def test_close(self):
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800148 # Test close() by calling it here and then having it be called again
Brett Cannon74bfd702003-04-25 09:39:47 +0000149 # by the tearDown() method for the test
150 self.returned_obj.close()
Skip Montanaro080c9972001-01-28 21:12:22 +0000151
Brett Cannon74bfd702003-04-25 09:39:47 +0000152 def test_info(self):
Ezio Melottie9615932010-01-24 19:26:24 +0000153 self.assertIsInstance(self.returned_obj.info(), email.message.Message)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000154
Brett Cannon74bfd702003-04-25 09:39:47 +0000155 def test_geturl(self):
156 self.assertEqual(self.returned_obj.geturl(), self.pathname)
Skip Montanaro080c9972001-01-28 21:12:22 +0000157
Christian Heimes9bd667a2008-01-20 15:14:11 +0000158 def test_getcode(self):
Florent Xicluna419e3842010-08-08 16:16:07 +0000159 self.assertIsNone(self.returned_obj.getcode())
Christian Heimes9bd667a2008-01-20 15:14:11 +0000160
Brett Cannon74bfd702003-04-25 09:39:47 +0000161 def test_iter(self):
162 # Test iterator
163 # Don't need to count number of iterations since test would fail the
164 # instant it returned anything beyond the first line from the
Raymond Hettinger038018a2011-06-26 14:29:35 +0200165 # comparison.
166 # Use the iterator in the usual implicit way to test for ticket #4608.
167 for line in self.returned_obj:
Brett Cannon74bfd702003-04-25 09:39:47 +0000168 self.assertEqual(line, self.text)
Skip Montanaro080c9972001-01-28 21:12:22 +0000169
Senthil Kumaran3800ea92012-01-21 11:52:48 +0800170 def test_relativelocalfile(self):
171 self.assertRaises(ValueError,urllib.request.urlopen,'./' + self.pathname)
172
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000173class ProxyTests(unittest.TestCase):
174
175 def setUp(self):
Walter Dörwaldb525e182009-04-26 21:39:21 +0000176 # Records changes to env vars
177 self.env = support.EnvironmentVarGuard()
Benjamin Peterson46a99002010-01-09 18:45:30 +0000178 # Delete all proxy related env vars
Antoine Pitroub3a88b52010-10-14 18:31:39 +0000179 for k in list(os.environ):
Antoine Pitrou8c8f1ac2010-10-14 18:32:54 +0000180 if 'proxy' in k.lower():
Benjamin Peterson46a99002010-01-09 18:45:30 +0000181 self.env.unset(k)
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000182
183 def tearDown(self):
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000184 # Restore all proxy related env vars
Walter Dörwaldb525e182009-04-26 21:39:21 +0000185 self.env.__exit__()
186 del self.env
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000187
188 def test_getproxies_environment_keep_no_proxies(self):
Walter Dörwaldb525e182009-04-26 21:39:21 +0000189 self.env.set('NO_PROXY', 'localhost')
190 proxies = urllib.request.getproxies_environment()
191 # getproxies_environment use lowered case truncated (no '_proxy') keys
Florent Xicluna419e3842010-08-08 16:16:07 +0000192 self.assertEqual('localhost', proxies['no'])
Senthil Kumaran89976f12011-08-06 12:27:40 +0800193 # List of no_proxies with space.
194 self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
195 self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com'))
Benjamin Peterson9bc93512008-09-22 22:10:59 +0000196
Senthil Kumarance260142011-11-01 01:35:17 +0800197class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin):
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000198 """Test urlopen() opening a fake http connection."""
199
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000200 def check_read(self, ver):
201 self.fakehttp(b"HTTP/" + ver + b" 200 OK\r\n\r\nHello!")
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000202 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000203 fp = urlopen("http://python.org/")
Jeremy Hylton66dc8c52007-08-04 03:42:26 +0000204 self.assertEqual(fp.readline(), b"Hello!")
205 self.assertEqual(fp.readline(), b"")
Christian Heimes9bd667a2008-01-20 15:14:11 +0000206 self.assertEqual(fp.geturl(), 'http://python.org/')
207 self.assertEqual(fp.getcode(), 200)
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000208 finally:
209 self.unfakehttp()
210
Senthil Kumaran26430412011-04-13 07:01:19 +0800211 def test_url_fragment(self):
212 # Issue #11703: geturl() omits fragments in the original URL.
213 url = 'http://docs.python.org/library/urllib.html#OK'
Senthil Kumaranb17abb12011-04-13 07:22:29 +0800214 self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
Senthil Kumaran26430412011-04-13 07:01:19 +0800215 try:
216 fp = urllib.request.urlopen(url)
217 self.assertEqual(fp.geturl(), url)
218 finally:
219 self.unfakehttp()
220
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800221 def test_willclose(self):
222 self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!")
Senthil Kumaranacbaa922011-03-20 05:30:16 +0800223 try:
224 resp = urlopen("http://www.python.org")
225 self.assertTrue(resp.fp.will_close)
226 finally:
227 self.unfakehttp()
Senthil Kumarand91ffca2011-03-19 17:25:27 +0800228
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000229 def test_read_0_9(self):
230 # "0.9" response accepted (but not "simple responses" without
231 # a status line)
232 self.check_read(b"0.9")
233
234 def test_read_1_0(self):
235 self.check_read(b"1.0")
236
237 def test_read_1_1(self):
238 self.check_read(b"1.1")
239
Christian Heimes57dddfb2008-01-02 18:30:52 +0000240 def test_read_bogus(self):
241 # urlopen() should raise IOError for many error codes.
242 self.fakehttp(b'''HTTP/1.1 401 Authentication Required
243Date: Wed, 02 Jan 2008 03:03:54 GMT
244Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
245Connection: close
246Content-Type: text/html; charset=iso-8859-1
247''')
248 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000249 self.assertRaises(IOError, urlopen, "http://python.org/")
Christian Heimes57dddfb2008-01-02 18:30:52 +0000250 finally:
251 self.unfakehttp()
252
guido@google.coma119df92011-03-29 11:41:02 -0700253 def test_invalid_redirect(self):
254 # urlopen() should raise IOError for many error codes.
255 self.fakehttp(b'''HTTP/1.1 302 Found
256Date: Wed, 02 Jan 2008 03:03:54 GMT
257Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
258Location: file://guidocomputer.athome.com:/python/license
259Connection: close
260Content-Type: text/html; charset=iso-8859-1
261''')
262 try:
263 self.assertRaises(urllib.error.HTTPError, urlopen,
264 "http://python.org/")
265 finally:
266 self.unfakehttp()
267
Guido van Rossumd8faa362007-04-27 19:54:29 +0000268 def test_empty_socket(self):
Jeremy Hylton66dc8c52007-08-04 03:42:26 +0000269 # urlopen() raises IOError if the underlying socket does not send any
270 # data. (#1680230)
Christian Heimes57dddfb2008-01-02 18:30:52 +0000271 self.fakehttp(b'')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000272 try:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000273 self.assertRaises(IOError, urlopen, "http://something")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000274 finally:
275 self.unfakehttp()
276
Senthil Kumarancad7b312012-10-27 02:26:46 -0700277 def test_missing_localfile(self):
278 # Test for #10836
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700279 # 3.3 - URLError is not captured, explicit IOError is raised.
280 with self.assertRaises(IOError):
Senthil Kumarancad7b312012-10-27 02:26:46 -0700281 urlopen('file://localhost/a/file/which/doesnot/exists.py')
Senthil Kumarancad7b312012-10-27 02:26:46 -0700282
283 def test_file_notexists(self):
284 fd, tmp_file = tempfile.mkstemp()
285 tmp_fileurl = 'file://localhost/' + tmp_file.replace(os.path.sep, '/')
286 try:
287 self.assertTrue(os.path.exists(tmp_file))
288 with urlopen(tmp_fileurl) as fobj:
289 self.assertTrue(fobj)
290 finally:
291 os.close(fd)
292 os.unlink(tmp_file)
293 self.assertFalse(os.path.exists(tmp_file))
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700294 # 3.3 - IOError instead of URLError
295 with self.assertRaises(IOError):
Senthil Kumarancad7b312012-10-27 02:26:46 -0700296 urlopen(tmp_fileurl)
297
298 def test_ftp_nohost(self):
299 test_ftp_url = 'ftp:///path'
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700300 # 3.3 - IOError instead of URLError
301 with self.assertRaises(IOError):
Senthil Kumarancad7b312012-10-27 02:26:46 -0700302 urlopen(test_ftp_url)
Senthil Kumarancad7b312012-10-27 02:26:46 -0700303
304 def test_ftp_nonexisting(self):
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700305 # 3.3 - IOError instead of URLError
306 with self.assertRaises(IOError):
Senthil Kumarancad7b312012-10-27 02:26:46 -0700307 urlopen('ftp://localhost/a/file/which/doesnot/exists.py')
Senthil Kumarancad7b312012-10-27 02:26:46 -0700308
309
Senthil Kumarande0eb242010-08-01 17:53:37 +0000310 def test_userpass_inurl(self):
Antoine Pitrou988dbd72010-12-17 17:35:56 +0000311 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
Senthil Kumarande0eb242010-08-01 17:53:37 +0000312 try:
313 fp = urlopen("http://user:pass@python.org/")
314 self.assertEqual(fp.readline(), b"Hello!")
315 self.assertEqual(fp.readline(), b"")
316 self.assertEqual(fp.geturl(), 'http://user:pass@python.org/')
317 self.assertEqual(fp.getcode(), 200)
318 finally:
319 self.unfakehttp()
320
Senthil Kumaranc5c5a142012-01-14 19:09:04 +0800321 def test_userpass_inurl_w_spaces(self):
322 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
323 try:
324 userpass = "a b:c d"
325 url = "http://{}@python.org/".format(userpass)
326 fakehttp_wrapper = http.client.HTTPConnection
327 authorization = ("Authorization: Basic %s\r\n" %
328 b64encode(userpass.encode("ASCII")).decode("ASCII"))
329 fp = urlopen(url)
330 # The authorization header must be in place
331 self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8"))
332 self.assertEqual(fp.readline(), b"Hello!")
333 self.assertEqual(fp.readline(), b"")
334 # the spaces are quoted in URL so no match
335 self.assertNotEqual(fp.geturl(), url)
336 self.assertEqual(fp.getcode(), 200)
337 finally:
338 self.unfakehttp()
339
Senthil Kumaran38b968b92012-03-14 13:43:53 -0700340 def test_URLopener_deprecation(self):
341 with support.check_warnings(('',DeprecationWarning)):
Senthil Kumarancc2f0422012-10-27 02:48:21 -0700342 urllib.request.URLopener()
Senthil Kumaran38b968b92012-03-14 13:43:53 -0700343
Brett Cannon19691362003-04-29 05:08:06 +0000344class urlretrieve_FileTests(unittest.TestCase):
Brett Cannon74bfd702003-04-25 09:39:47 +0000345 """Test urllib.urlretrieve() on local files"""
Skip Montanaro080c9972001-01-28 21:12:22 +0000346
Brett Cannon19691362003-04-29 05:08:06 +0000347 def setUp(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000348 # Create a list of temporary files. Each item in the list is a file
349 # name (absolute path or relative to the current working directory).
350 # All files in this list will be deleted in the tearDown method. Note,
351 # this only helps to makes sure temporary files get deleted, but it
352 # does nothing about trying to close files that may still be open. It
353 # is the responsibility of the developer to properly close files even
354 # when exceptional conditions occur.
355 self.tempFiles = []
356
Brett Cannon19691362003-04-29 05:08:06 +0000357 # Create a temporary file.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000358 self.registerFileForCleanUp(support.TESTFN)
Guido van Rossuma0982942007-07-10 08:30:03 +0000359 self.text = b'testing urllib.urlretrieve'
Georg Brandl5a650a22005-08-26 08:51:34 +0000360 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000361 FILE = open(support.TESTFN, 'wb')
Georg Brandl5a650a22005-08-26 08:51:34 +0000362 FILE.write(self.text)
363 FILE.close()
364 finally:
365 try: FILE.close()
366 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000367
368 def tearDown(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000369 # Delete the temporary files.
370 for each in self.tempFiles:
371 try: os.remove(each)
372 except: pass
373
374 def constructLocalFileUrl(self, filePath):
Victor Stinner6c6f8512010-08-07 10:09:35 +0000375 filePath = os.path.abspath(filePath)
376 try:
Marc-André Lemburg8f36af72011-02-25 15:42:01 +0000377 filePath.encode("utf-8")
Victor Stinner6c6f8512010-08-07 10:09:35 +0000378 except UnicodeEncodeError:
379 raise unittest.SkipTest("filePath is not encodable to utf8")
380 return "file://%s" % urllib.request.pathname2url(filePath)
Georg Brandl5a650a22005-08-26 08:51:34 +0000381
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000382 def createNewTempFile(self, data=b""):
Georg Brandl5a650a22005-08-26 08:51:34 +0000383 """Creates a new temporary file containing the specified data,
384 registers the file for deletion during the test fixture tear down, and
385 returns the absolute path of the file."""
386
387 newFd, newFilePath = tempfile.mkstemp()
388 try:
389 self.registerFileForCleanUp(newFilePath)
390 newFile = os.fdopen(newFd, "wb")
391 newFile.write(data)
392 newFile.close()
393 finally:
394 try: newFile.close()
395 except: pass
396 return newFilePath
397
398 def registerFileForCleanUp(self, fileName):
399 self.tempFiles.append(fileName)
Brett Cannon19691362003-04-29 05:08:06 +0000400
401 def test_basic(self):
402 # Make sure that a local file just gets its own location returned and
403 # a headers value is returned.
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000404 result = urllib.request.urlretrieve("file:%s" % support.TESTFN)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000405 self.assertEqual(result[0], support.TESTFN)
Ezio Melottie9615932010-01-24 19:26:24 +0000406 self.assertIsInstance(result[1], email.message.Message,
407 "did not get a email.message.Message instance "
408 "as second returned value")
Brett Cannon19691362003-04-29 05:08:06 +0000409
410 def test_copy(self):
411 # Test that setting the filename argument works.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000412 second_temp = "%s.2" % support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000413 self.registerFileForCleanUp(second_temp)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000414 result = urllib.request.urlretrieve(self.constructLocalFileUrl(
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000415 support.TESTFN), second_temp)
Brett Cannon19691362003-04-29 05:08:06 +0000416 self.assertEqual(second_temp, result[0])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000417 self.assertTrue(os.path.exists(second_temp), "copy of the file was not "
Brett Cannon19691362003-04-29 05:08:06 +0000418 "made")
Alex Martelli01c77c62006-08-24 02:58:11 +0000419 FILE = open(second_temp, 'rb')
Brett Cannon19691362003-04-29 05:08:06 +0000420 try:
421 text = FILE.read()
Brett Cannon19691362003-04-29 05:08:06 +0000422 FILE.close()
Georg Brandl5a650a22005-08-26 08:51:34 +0000423 finally:
424 try: FILE.close()
425 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000426 self.assertEqual(self.text, text)
427
428 def test_reporthook(self):
429 # Make sure that the reporthook works.
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700430 def hooktester(block_count, block_read_size, file_size, count_holder=[0]):
431 self.assertIsInstance(block_count, int)
432 self.assertIsInstance(block_read_size, int)
433 self.assertIsInstance(file_size, int)
434 self.assertEqual(block_count, count_holder[0])
Brett Cannon19691362003-04-29 05:08:06 +0000435 count_holder[0] = count_holder[0] + 1
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000436 second_temp = "%s.2" % support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000437 self.registerFileForCleanUp(second_temp)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000438 urllib.request.urlretrieve(
439 self.constructLocalFileUrl(support.TESTFN),
Georg Brandl5a650a22005-08-26 08:51:34 +0000440 second_temp, hooktester)
441
442 def test_reporthook_0_bytes(self):
443 # Test on zero length file. Should call reporthook only 1 time.
444 report = []
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700445 def hooktester(block_count, block_read_size, file_size, _report=report):
446 _report.append((block_count, block_read_size, file_size))
Georg Brandl5a650a22005-08-26 08:51:34 +0000447 srcFileName = self.createNewTempFile()
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000448 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000449 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000450 self.assertEqual(len(report), 1)
451 self.assertEqual(report[0][2], 0)
452
453 def test_reporthook_5_bytes(self):
454 # Test on 5 byte file. Should call reporthook only 2 times (once when
455 # the "network connection" is established and once when the block is
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700456 # read).
Georg Brandl5a650a22005-08-26 08:51:34 +0000457 report = []
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700458 def hooktester(block_count, block_read_size, file_size, _report=report):
459 _report.append((block_count, block_read_size, file_size))
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000460 srcFileName = self.createNewTempFile(b"x" * 5)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000461 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000462 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000463 self.assertEqual(len(report), 2)
Gregory P. Smith6d9388f2012-11-10 15:12:55 -0800464 self.assertEqual(report[0][2], 5)
465 self.assertEqual(report[1][2], 5)
Georg Brandl5a650a22005-08-26 08:51:34 +0000466
467 def test_reporthook_8193_bytes(self):
468 # Test on 8193 byte file. Should call reporthook only 3 times (once
469 # when the "network connection" is established, once for the next 8192
470 # bytes, and once for the last byte).
471 report = []
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700472 def hooktester(block_count, block_read_size, file_size, _report=report):
473 _report.append((block_count, block_read_size, file_size))
Guido van Rossum70d0dda2007-08-29 01:53:26 +0000474 srcFileName = self.createNewTempFile(b"x" * 8193)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000475 urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000476 support.TESTFN, hooktester)
Georg Brandl5a650a22005-08-26 08:51:34 +0000477 self.assertEqual(len(report), 3)
Gregory P. Smith6d9388f2012-11-10 15:12:55 -0800478 self.assertEqual(report[0][2], 8193)
479 self.assertEqual(report[0][1], 8192)
Senthil Kumarane24f96a2012-03-13 19:29:33 -0700480 self.assertEqual(report[1][1], 8192)
Gregory P. Smith6d9388f2012-11-10 15:12:55 -0800481 self.assertEqual(report[2][1], 8192)
Skip Montanaro080c9972001-01-28 21:12:22 +0000482
Senthil Kumarance260142011-11-01 01:35:17 +0800483
484class urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin):
485 """Test urllib.urlretrieve() using fake http connections"""
486
487 def test_short_content_raises_ContentTooShortError(self):
488 self.fakehttp(b'''HTTP/1.1 200 OK
489Date: Wed, 02 Jan 2008 03:03:54 GMT
490Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
491Connection: close
492Content-Length: 100
493Content-Type: text/html; charset=iso-8859-1
494
495FF
496''')
497
498 def _reporthook(par1, par2, par3):
499 pass
500
501 with self.assertRaises(urllib.error.ContentTooShortError):
502 try:
503 urllib.request.urlretrieve('http://example.com/',
504 reporthook=_reporthook)
505 finally:
506 self.unfakehttp()
507
508 def test_short_content_raises_ContentTooShortError_without_reporthook(self):
509 self.fakehttp(b'''HTTP/1.1 200 OK
510Date: Wed, 02 Jan 2008 03:03:54 GMT
511Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
512Connection: close
513Content-Length: 100
514Content-Type: text/html; charset=iso-8859-1
515
516FF
517''')
518 with self.assertRaises(urllib.error.ContentTooShortError):
519 try:
520 urllib.request.urlretrieve('http://example.com/')
521 finally:
522 self.unfakehttp()
523
524
Brett Cannon74bfd702003-04-25 09:39:47 +0000525class QuotingTests(unittest.TestCase):
526 """Tests for urllib.quote() and urllib.quote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000527
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000528 According to RFC 2396 (Uniform Resource Identifiers), to escape a
529 character you write it as '%' + <2 character US-ASCII hex value>.
530 The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a
531 character properly. Case does not matter on the hex letters.
Brett Cannon74bfd702003-04-25 09:39:47 +0000532
533 The various character sets specified are:
Tim Petersc2659cf2003-05-12 20:19:37 +0000534
Brett Cannon74bfd702003-04-25 09:39:47 +0000535 Reserved characters : ";/?:@&=+$,"
536 Have special meaning in URIs and must be escaped if not being used for
537 their special meaning
538 Data characters : letters, digits, and "-_.!~*'()"
539 Unreserved and do not need to be escaped; can be, though, if desired
540 Control characters : 0x00 - 0x1F, 0x7F
541 Have no use in URIs so must be escaped
542 space : 0x20
543 Must be escaped
544 Delimiters : '<>#%"'
545 Must be escaped
546 Unwise : "{}|\^[]`"
547 Must be escaped
Tim Petersc2659cf2003-05-12 20:19:37 +0000548
Brett Cannon74bfd702003-04-25 09:39:47 +0000549 """
550
551 def test_never_quote(self):
552 # Make sure quote() does not quote letters, digits, and "_,.-"
553 do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
554 "abcdefghijklmnopqrstuvwxyz",
555 "0123456789",
556 "_.-"])
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000557 result = urllib.parse.quote(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(): %r != %r" % (do_not_quote, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000560 result = urllib.parse.quote_plus(do_not_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000561 self.assertEqual(do_not_quote, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000562 "using quote_plus(): %r != %r" % (do_not_quote, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000563
564 def test_default_safe(self):
565 # Test '/' is default value for 'safe' parameter
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000566 self.assertEqual(urllib.parse.quote.__defaults__[0], '/')
Brett Cannon74bfd702003-04-25 09:39:47 +0000567
568 def test_safe(self):
569 # Test setting 'safe' parameter does what it should do
570 quote_by_default = "<>"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000571 result = urllib.parse.quote(quote_by_default, safe=quote_by_default)
Brett Cannon74bfd702003-04-25 09:39:47 +0000572 self.assertEqual(quote_by_default, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000573 "using quote(): %r != %r" % (quote_by_default, result))
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000574 result = urllib.parse.quote_plus(quote_by_default,
575 safe=quote_by_default)
Brett Cannon74bfd702003-04-25 09:39:47 +0000576 self.assertEqual(quote_by_default, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000577 "using quote_plus(): %r != %r" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000578 (quote_by_default, result))
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000579 # Safe expressed as bytes rather than str
580 result = urllib.parse.quote(quote_by_default, safe=b"<>")
581 self.assertEqual(quote_by_default, result,
582 "using quote(): %r != %r" % (quote_by_default, result))
583 # "Safe" non-ASCII characters should have no effect
584 # (Since URIs are not allowed to have non-ASCII characters)
585 result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="\xfc")
586 expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="")
587 self.assertEqual(expect, result,
588 "using quote(): %r != %r" %
589 (expect, result))
590 # Same as above, but using a bytes rather than str
591 result = urllib.parse.quote("a\xfcb", encoding="latin-1", safe=b"\xfc")
592 expect = urllib.parse.quote("a\xfcb", encoding="latin-1", safe="")
593 self.assertEqual(expect, result,
594 "using quote(): %r != %r" %
595 (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000596
597 def test_default_quoting(self):
598 # Make sure all characters that should be quoted are by default sans
599 # space (separate test for that).
600 should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
601 should_quote.append('<>#%"{}|\^[]`')
602 should_quote.append(chr(127)) # For 0x7F
603 should_quote = ''.join(should_quote)
604 for char in should_quote:
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000605 result = urllib.parse.quote(char)
Brett Cannon74bfd702003-04-25 09:39:47 +0000606 self.assertEqual(hexescape(char), result,
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000607 "using quote(): "
608 "%s should be escaped to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000609 (char, hexescape(char), result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000610 result = urllib.parse.quote_plus(char)
Brett Cannon74bfd702003-04-25 09:39:47 +0000611 self.assertEqual(hexescape(char), result,
612 "using quote_plus(): "
Tim Petersc2659cf2003-05-12 20:19:37 +0000613 "%s should be escapes to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000614 (char, hexescape(char), result))
615 del should_quote
616 partial_quote = "ab[]cd"
617 expected = "ab%5B%5Dcd"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000618 result = urllib.parse.quote(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(): %r != %r" % (expected, result))
Senthil Kumaran305a68e2011-09-13 06:40:27 +0800621 result = urllib.parse.quote_plus(partial_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000622 self.assertEqual(expected, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000623 "using quote_plus(): %r != %r" % (expected, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000624
625 def test_quoting_space(self):
626 # Make sure quote() and quote_plus() handle spaces as specified in
627 # their unique way
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000628 result = urllib.parse.quote(' ')
Brett Cannon74bfd702003-04-25 09:39:47 +0000629 self.assertEqual(result, hexescape(' '),
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000630 "using quote(): %r != %r" % (result, hexescape(' ')))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000631 result = urllib.parse.quote_plus(' ')
Brett Cannon74bfd702003-04-25 09:39:47 +0000632 self.assertEqual(result, '+',
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000633 "using quote_plus(): %r != +" % result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000634 given = "a b cd e f"
635 expect = given.replace(' ', hexescape(' '))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000636 result = urllib.parse.quote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000637 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000638 "using quote(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000639 expect = given.replace(' ', '+')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000640 result = urllib.parse.quote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000641 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000642 "using quote_plus(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000643
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000644 def test_quoting_plus(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000645 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma'),
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000646 'alpha%2Bbeta+gamma')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000647 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', '+'),
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000648 'alpha+beta+gamma')
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000649 # Test with bytes
650 self.assertEqual(urllib.parse.quote_plus(b'alpha+beta gamma'),
651 'alpha%2Bbeta+gamma')
652 # Test with safe bytes
653 self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', b'+'),
654 'alpha+beta+gamma')
655
656 def test_quote_bytes(self):
657 # Bytes should quote directly to percent-encoded values
658 given = b"\xa2\xd8ab\xff"
659 expect = "%A2%D8ab%FF"
660 result = urllib.parse.quote(given)
661 self.assertEqual(expect, result,
662 "using quote(): %r != %r" % (expect, result))
663 # Encoding argument should raise type error on bytes input
664 self.assertRaises(TypeError, urllib.parse.quote, given,
665 encoding="latin-1")
666 # quote_from_bytes should work the same
667 result = urllib.parse.quote_from_bytes(given)
668 self.assertEqual(expect, result,
669 "using quote_from_bytes(): %r != %r"
670 % (expect, result))
671
672 def test_quote_with_unicode(self):
673 # Characters in Latin-1 range, encoded by default in UTF-8
674 given = "\xa2\xd8ab\xff"
675 expect = "%C2%A2%C3%98ab%C3%BF"
676 result = urllib.parse.quote(given)
677 self.assertEqual(expect, result,
678 "using quote(): %r != %r" % (expect, result))
679 # Characters in Latin-1 range, encoded by with None (default)
680 result = urllib.parse.quote(given, encoding=None, errors=None)
681 self.assertEqual(expect, result,
682 "using quote(): %r != %r" % (expect, result))
683 # Characters in Latin-1 range, encoded with Latin-1
684 given = "\xa2\xd8ab\xff"
685 expect = "%A2%D8ab%FF"
686 result = urllib.parse.quote(given, encoding="latin-1")
687 self.assertEqual(expect, result,
688 "using quote(): %r != %r" % (expect, result))
689 # Characters in BMP, encoded by default in UTF-8
690 given = "\u6f22\u5b57" # "Kanji"
691 expect = "%E6%BC%A2%E5%AD%97"
692 result = urllib.parse.quote(given)
693 self.assertEqual(expect, result,
694 "using quote(): %r != %r" % (expect, result))
695 # Characters in BMP, encoded with Latin-1
696 given = "\u6f22\u5b57"
697 self.assertRaises(UnicodeEncodeError, urllib.parse.quote, given,
698 encoding="latin-1")
699 # Characters in BMP, encoded with Latin-1, with replace error handling
700 given = "\u6f22\u5b57"
701 expect = "%3F%3F" # "??"
702 result = urllib.parse.quote(given, encoding="latin-1",
703 errors="replace")
704 self.assertEqual(expect, result,
705 "using quote(): %r != %r" % (expect, result))
706 # Characters in BMP, Latin-1, with xmlcharref error handling
707 given = "\u6f22\u5b57"
708 expect = "%26%2328450%3B%26%2323383%3B" # "&#28450;&#23383;"
709 result = urllib.parse.quote(given, encoding="latin-1",
710 errors="xmlcharrefreplace")
711 self.assertEqual(expect, result,
712 "using quote(): %r != %r" % (expect, result))
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000713
Georg Brandlfaf41492009-05-26 18:31:11 +0000714 def test_quote_plus_with_unicode(self):
715 # Encoding (latin-1) test for quote_plus
716 given = "\xa2\xd8 \xff"
717 expect = "%A2%D8+%FF"
718 result = urllib.parse.quote_plus(given, encoding="latin-1")
719 self.assertEqual(expect, result,
720 "using quote_plus(): %r != %r" % (expect, result))
721 # Errors test for quote_plus
722 given = "ab\u6f22\u5b57 cd"
723 expect = "ab%3F%3F+cd"
724 result = urllib.parse.quote_plus(given, encoding="latin-1",
725 errors="replace")
726 self.assertEqual(expect, result,
727 "using quote_plus(): %r != %r" % (expect, result))
728
Senthil Kumarand496c4c2010-07-30 19:34:36 +0000729
Brett Cannon74bfd702003-04-25 09:39:47 +0000730class UnquotingTests(unittest.TestCase):
731 """Tests for unquote() and unquote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000732
Brett Cannon74bfd702003-04-25 09:39:47 +0000733 See the doc string for quoting_Tests for details on quoting and such.
734
735 """
736
737 def test_unquoting(self):
738 # Make sure unquoting of all ASCII values works
739 escape_list = []
740 for num in range(128):
741 given = hexescape(chr(num))
742 expect = chr(num)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000743 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000744 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000745 "using unquote(): %r != %r" % (expect, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000746 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000747 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000748 "using unquote_plus(): %r != %r" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000749 (expect, result))
750 escape_list.append(given)
751 escape_string = ''.join(escape_list)
752 del escape_list
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000753 result = urllib.parse.unquote(escape_string)
Brett Cannon74bfd702003-04-25 09:39:47 +0000754 self.assertEqual(result.count('%'), 1,
Brett Cannon74bfd702003-04-25 09:39:47 +0000755 "using unquote(): not all characters escaped: "
756 "%s" % result)
Georg Brandl604ef372010-07-31 08:20:02 +0000757 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None)
758 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ())
Florent Xicluna62829dc2010-08-14 20:51:58 +0000759 with support.check_warnings(('', BytesWarning), quiet=True):
760 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, b'')
Brett Cannon74bfd702003-04-25 09:39:47 +0000761
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000762 def test_unquoting_badpercent(self):
763 # Test unquoting on bad percent-escapes
764 given = '%xab'
765 expect = given
766 result = urllib.parse.unquote(given)
767 self.assertEqual(expect, result, "using unquote(): %r != %r"
768 % (expect, result))
769 given = '%x'
770 expect = given
771 result = urllib.parse.unquote(given)
772 self.assertEqual(expect, result, "using unquote(): %r != %r"
773 % (expect, result))
774 given = '%'
775 expect = given
776 result = urllib.parse.unquote(given)
777 self.assertEqual(expect, result, "using unquote(): %r != %r"
778 % (expect, result))
779 # unquote_to_bytes
780 given = '%xab'
781 expect = bytes(given, 'ascii')
782 result = urllib.parse.unquote_to_bytes(given)
783 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
784 % (expect, result))
785 given = '%x'
786 expect = bytes(given, 'ascii')
787 result = urllib.parse.unquote_to_bytes(given)
788 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
789 % (expect, result))
790 given = '%'
791 expect = bytes(given, 'ascii')
792 result = urllib.parse.unquote_to_bytes(given)
793 self.assertEqual(expect, result, "using unquote_to_bytes(): %r != %r"
794 % (expect, result))
Georg Brandl604ef372010-07-31 08:20:02 +0000795 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, None)
796 self.assertRaises((TypeError, AttributeError), urllib.parse.unquote_to_bytes, ())
Senthil Kumaran79e17f62010-07-19 18:17:19 +0000797
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000798 def test_unquoting_mixed_case(self):
799 # Test unquoting on mixed-case hex digits in the percent-escapes
800 given = '%Ab%eA'
801 expect = b'\xab\xea'
802 result = urllib.parse.unquote_to_bytes(given)
803 self.assertEqual(expect, result,
804 "using unquote_to_bytes(): %r != %r"
805 % (expect, result))
806
Brett Cannon74bfd702003-04-25 09:39:47 +0000807 def test_unquoting_parts(self):
808 # Make sure unquoting works when have non-quoted characters
809 # interspersed
810 given = 'ab%sd' % hexescape('c')
811 expect = "abcd"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000812 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000813 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000814 "using quote(): %r != %r" % (expect, result))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000815 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000816 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000817 "using unquote_plus(): %r != %r" % (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +0000818
Brett Cannon74bfd702003-04-25 09:39:47 +0000819 def test_unquoting_plus(self):
820 # Test difference between unquote() and unquote_plus()
821 given = "are+there+spaces..."
822 expect = given
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000823 result = urllib.parse.unquote(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000824 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000825 "using unquote(): %r != %r" % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000826 expect = given.replace('+', ' ')
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000827 result = urllib.parse.unquote_plus(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000828 self.assertEqual(expect, result,
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000829 "using unquote_plus(): %r != %r" % (expect, result))
830
831 def test_unquote_to_bytes(self):
832 given = 'br%C3%BCckner_sapporo_20050930.doc'
833 expect = b'br\xc3\xbcckner_sapporo_20050930.doc'
834 result = urllib.parse.unquote_to_bytes(given)
835 self.assertEqual(expect, result,
836 "using unquote_to_bytes(): %r != %r"
837 % (expect, result))
838 # Test on a string with unescaped non-ASCII characters
839 # (Technically an invalid URI; expect those characters to be UTF-8
840 # encoded).
841 result = urllib.parse.unquote_to_bytes("\u6f22%C3%BC")
842 expect = b'\xe6\xbc\xa2\xc3\xbc' # UTF-8 for "\u6f22\u00fc"
843 self.assertEqual(expect, result,
844 "using unquote_to_bytes(): %r != %r"
845 % (expect, result))
846 # Test with a bytes as input
847 given = b'%A2%D8ab%FF'
848 expect = b'\xa2\xd8ab\xff'
849 result = urllib.parse.unquote_to_bytes(given)
850 self.assertEqual(expect, result,
851 "using unquote_to_bytes(): %r != %r"
852 % (expect, result))
853 # Test with a bytes as input, with unescaped non-ASCII bytes
854 # (Technically an invalid URI; expect those bytes to be preserved)
855 given = b'%A2\xd8ab%FF'
856 expect = b'\xa2\xd8ab\xff'
857 result = urllib.parse.unquote_to_bytes(given)
858 self.assertEqual(expect, result,
859 "using unquote_to_bytes(): %r != %r"
860 % (expect, result))
Brett Cannon74bfd702003-04-25 09:39:47 +0000861
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000862 def test_unquote_with_unicode(self):
Guido van Rossum52dbbb92008-08-18 21:44:30 +0000863 # Characters in the Latin-1 range, encoded with UTF-8
864 given = 'br%C3%BCckner_sapporo_20050930.doc'
865 expect = 'br\u00fcckner_sapporo_20050930.doc'
866 result = urllib.parse.unquote(given)
867 self.assertEqual(expect, result,
868 "using unquote(): %r != %r" % (expect, result))
869 # Characters in the Latin-1 range, encoded with None (default)
870 result = urllib.parse.unquote(given, encoding=None, errors=None)
871 self.assertEqual(expect, result,
872 "using unquote(): %r != %r" % (expect, result))
873
874 # Characters in the Latin-1 range, encoded with Latin-1
875 result = urllib.parse.unquote('br%FCckner_sapporo_20050930.doc',
876 encoding="latin-1")
877 expect = 'br\u00fcckner_sapporo_20050930.doc'
878 self.assertEqual(expect, result,
879 "using unquote(): %r != %r" % (expect, result))
880
881 # Characters in BMP, encoded with UTF-8
882 given = "%E6%BC%A2%E5%AD%97"
883 expect = "\u6f22\u5b57" # "Kanji"
884 result = urllib.parse.unquote(given)
885 self.assertEqual(expect, result,
886 "using unquote(): %r != %r" % (expect, result))
887
888 # Decode with UTF-8, invalid sequence
889 given = "%F3%B1"
890 expect = "\ufffd" # Replacement character
891 result = urllib.parse.unquote(given)
892 self.assertEqual(expect, result,
893 "using unquote(): %r != %r" % (expect, result))
894
895 # Decode with UTF-8, invalid sequence, replace errors
896 result = urllib.parse.unquote(given, errors="replace")
897 self.assertEqual(expect, result,
898 "using unquote(): %r != %r" % (expect, result))
899
900 # Decode with UTF-8, invalid sequence, ignoring errors
901 given = "%F3%B1"
902 expect = ""
903 result = urllib.parse.unquote(given, errors="ignore")
904 self.assertEqual(expect, result,
905 "using unquote(): %r != %r" % (expect, result))
906
907 # A mix of non-ASCII and percent-encoded characters, UTF-8
908 result = urllib.parse.unquote("\u6f22%C3%BC")
909 expect = '\u6f22\u00fc'
910 self.assertEqual(expect, result,
911 "using unquote(): %r != %r" % (expect, result))
912
913 # A mix of non-ASCII and percent-encoded characters, Latin-1
914 # (Note, the string contains non-Latin-1-representable characters)
915 result = urllib.parse.unquote("\u6f22%FC", encoding="latin-1")
916 expect = '\u6f22\u00fc'
917 self.assertEqual(expect, result,
918 "using unquote(): %r != %r" % (expect, result))
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000919
Brett Cannon74bfd702003-04-25 09:39:47 +0000920class urlencode_Tests(unittest.TestCase):
921 """Tests for urlencode()"""
922
923 def help_inputtype(self, given, test_type):
924 """Helper method for testing different input types.
Tim Petersc2659cf2003-05-12 20:19:37 +0000925
Brett Cannon74bfd702003-04-25 09:39:47 +0000926 'given' must lead to only the pairs:
927 * 1st, 1
928 * 2nd, 2
929 * 3rd, 3
Tim Petersc2659cf2003-05-12 20:19:37 +0000930
Brett Cannon74bfd702003-04-25 09:39:47 +0000931 Test cannot assume anything about order. Docs make no guarantee and
932 have possible dictionary input.
Tim Petersc2659cf2003-05-12 20:19:37 +0000933
Brett Cannon74bfd702003-04-25 09:39:47 +0000934 """
935 expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000936 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000937 for expected in expect_somewhere:
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000938 self.assertIn(expected, result,
Brett Cannon74bfd702003-04-25 09:39:47 +0000939 "testing %s: %s not found in %s" %
940 (test_type, expected, result))
941 self.assertEqual(result.count('&'), 2,
942 "testing %s: expected 2 '&'s; got %s" %
943 (test_type, result.count('&')))
944 amp_location = result.index('&')
945 on_amp_left = result[amp_location - 1]
946 on_amp_right = result[amp_location + 1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000947 self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000948 "testing %s: '&' not located in proper place in %s" %
949 (test_type, result))
950 self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
951 "testing %s: "
952 "unexpected number of characters: %s != %s" %
953 (test_type, len(result), (5 * 3) + 2))
954
955 def test_using_mapping(self):
956 # Test passing in a mapping object as an argument.
957 self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
958 "using dict as input type")
959
960 def test_using_sequence(self):
961 # Test passing in a sequence of two-item sequences as an argument.
962 self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
963 "using sequence of two-item tuples as input")
964
965 def test_quoting(self):
966 # Make sure keys and values are quoted using quote_plus()
967 given = {"&":"="}
968 expect = "%s=%s" % (hexescape('&'), hexescape('='))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000969 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000970 self.assertEqual(expect, result)
971 given = {"key name":"A bunch of pluses"}
972 expect = "key+name=A+bunch+of+pluses"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000973 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000974 self.assertEqual(expect, result)
975
976 def test_doseq(self):
977 # Test that passing True for 'doseq' parameter works correctly
978 given = {'sequence':['1', '2', '3']}
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000979 expect = "sequence=%s" % urllib.parse.quote_plus(str(['1', '2', '3']))
980 result = urllib.parse.urlencode(given)
Brett Cannon74bfd702003-04-25 09:39:47 +0000981 self.assertEqual(expect, result)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000982 result = urllib.parse.urlencode(given, True)
Brett Cannon74bfd702003-04-25 09:39:47 +0000983 for value in given["sequence"]:
984 expect = "sequence=%s" % value
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000985 self.assertIn(expect, result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000986 self.assertEqual(result.count('&'), 2,
987 "Expected 2 '&'s, got %s" % result.count('&'))
988
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +0000989 def test_empty_sequence(self):
990 self.assertEqual("", urllib.parse.urlencode({}))
991 self.assertEqual("", urllib.parse.urlencode([]))
992
993 def test_nonstring_values(self):
994 self.assertEqual("a=1", urllib.parse.urlencode({"a": 1}))
995 self.assertEqual("a=None", urllib.parse.urlencode({"a": None}))
996
997 def test_nonstring_seq_values(self):
998 self.assertEqual("a=1&a=2", urllib.parse.urlencode({"a": [1, 2]}, True))
999 self.assertEqual("a=None&a=a",
1000 urllib.parse.urlencode({"a": [None, "a"]}, True))
Georg Brandl2daf6ae2012-02-20 19:54:16 +01001001 data = collections.OrderedDict([("a", 1), ("b", 1)])
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +00001002 self.assertEqual("a=a&a=b",
Georg Brandl2daf6ae2012-02-20 19:54:16 +01001003 urllib.parse.urlencode({"a": data}, True))
Jeremy Hylton1ef7c6b2009-03-26 16:57:30 +00001004
Senthil Kumarandf022da2010-07-03 17:48:22 +00001005 def test_urlencode_encoding(self):
1006 # ASCII encoding. Expect %3F with errors="replace'
1007 given = (('\u00a0', '\u00c1'),)
1008 expect = '%3F=%3F'
1009 result = urllib.parse.urlencode(given, encoding="ASCII", errors="replace")
1010 self.assertEqual(expect, result)
1011
1012 # Default is UTF-8 encoding.
1013 given = (('\u00a0', '\u00c1'),)
1014 expect = '%C2%A0=%C3%81'
1015 result = urllib.parse.urlencode(given)
1016 self.assertEqual(expect, result)
1017
1018 # Latin-1 encoding.
1019 given = (('\u00a0', '\u00c1'),)
1020 expect = '%A0=%C1'
1021 result = urllib.parse.urlencode(given, encoding="latin-1")
1022 self.assertEqual(expect, result)
1023
1024 def test_urlencode_encoding_doseq(self):
1025 # ASCII Encoding. Expect %3F with errors="replace'
1026 given = (('\u00a0', '\u00c1'),)
1027 expect = '%3F=%3F'
1028 result = urllib.parse.urlencode(given, doseq=True,
1029 encoding="ASCII", errors="replace")
1030 self.assertEqual(expect, result)
1031
1032 # ASCII Encoding. On a sequence of values.
1033 given = (("\u00a0", (1, "\u00c1")),)
1034 expect = '%3F=1&%3F=%3F'
1035 result = urllib.parse.urlencode(given, True,
1036 encoding="ASCII", errors="replace")
1037 self.assertEqual(expect, result)
1038
1039 # Utf-8
1040 given = (("\u00a0", "\u00c1"),)
1041 expect = '%C2%A0=%C3%81'
1042 result = urllib.parse.urlencode(given, True)
1043 self.assertEqual(expect, result)
1044
1045 given = (("\u00a0", (42, "\u00c1")),)
1046 expect = '%C2%A0=42&%C2%A0=%C3%81'
1047 result = urllib.parse.urlencode(given, True)
1048 self.assertEqual(expect, result)
1049
1050 # latin-1
1051 given = (("\u00a0", "\u00c1"),)
1052 expect = '%A0=%C1'
1053 result = urllib.parse.urlencode(given, True, encoding="latin-1")
1054 self.assertEqual(expect, result)
1055
1056 given = (("\u00a0", (42, "\u00c1")),)
1057 expect = '%A0=42&%A0=%C1'
1058 result = urllib.parse.urlencode(given, True, encoding="latin-1")
1059 self.assertEqual(expect, result)
1060
1061 def test_urlencode_bytes(self):
1062 given = ((b'\xa0\x24', b'\xc1\x24'),)
1063 expect = '%A0%24=%C1%24'
1064 result = urllib.parse.urlencode(given)
1065 self.assertEqual(expect, result)
1066 result = urllib.parse.urlencode(given, True)
1067 self.assertEqual(expect, result)
1068
1069 # Sequence of values
1070 given = ((b'\xa0\x24', (42, b'\xc1\x24')),)
1071 expect = '%A0%24=42&%A0%24=%C1%24'
1072 result = urllib.parse.urlencode(given, True)
1073 self.assertEqual(expect, result)
1074
1075 def test_urlencode_encoding_safe_parameter(self):
1076
1077 # Send '$' (\x24) as safe character
1078 # Default utf-8 encoding
1079
1080 given = ((b'\xa0\x24', b'\xc1\x24'),)
1081 result = urllib.parse.urlencode(given, safe=":$")
1082 expect = '%A0$=%C1$'
1083 self.assertEqual(expect, result)
1084
1085 given = ((b'\xa0\x24', b'\xc1\x24'),)
1086 result = urllib.parse.urlencode(given, doseq=True, safe=":$")
1087 expect = '%A0$=%C1$'
1088 self.assertEqual(expect, result)
1089
1090 # Safe parameter in sequence
1091 given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
1092 expect = '%A0$=%C1$&%A0$=13&%A0$=42'
1093 result = urllib.parse.urlencode(given, True, safe=":$")
1094 self.assertEqual(expect, result)
1095
1096 # Test all above in latin-1 encoding
1097
1098 given = ((b'\xa0\x24', b'\xc1\x24'),)
1099 result = urllib.parse.urlencode(given, safe=":$",
1100 encoding="latin-1")
1101 expect = '%A0$=%C1$'
1102 self.assertEqual(expect, result)
1103
1104 given = ((b'\xa0\x24', b'\xc1\x24'),)
1105 expect = '%A0$=%C1$'
1106 result = urllib.parse.urlencode(given, doseq=True, safe=":$",
1107 encoding="latin-1")
1108
1109 given = ((b'\xa0\x24', (b'\xc1\x24', 0xd, 42)),)
1110 expect = '%A0$=%C1$&%A0$=13&%A0$=42'
1111 result = urllib.parse.urlencode(given, True, safe=":$",
1112 encoding="latin-1")
1113 self.assertEqual(expect, result)
1114
Brett Cannon74bfd702003-04-25 09:39:47 +00001115class Pathname_Tests(unittest.TestCase):
1116 """Test pathname2url() and url2pathname()"""
1117
1118 def test_basic(self):
1119 # Make sure simple tests pass
1120 expected_path = os.path.join("parts", "of", "a", "path")
1121 expected_url = "parts/of/a/path"
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001122 result = urllib.request.pathname2url(expected_path)
Brett Cannon74bfd702003-04-25 09:39:47 +00001123 self.assertEqual(expected_url, result,
1124 "pathname2url() failed; %s != %s" %
1125 (result, expected_url))
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001126 result = urllib.request.url2pathname(expected_url)
Brett Cannon74bfd702003-04-25 09:39:47 +00001127 self.assertEqual(expected_path, result,
1128 "url2pathame() failed; %s != %s" %
1129 (result, expected_path))
1130
1131 def test_quoting(self):
1132 # Test automatic quoting and unquoting works for pathnam2url() and
1133 # url2pathname() respectively
1134 given = os.path.join("needs", "quot=ing", "here")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001135 expect = "needs/%s/here" % urllib.parse.quote("quot=ing")
1136 result = urllib.request.pathname2url(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001137 self.assertEqual(expect, result,
1138 "pathname2url() failed; %s != %s" %
1139 (expect, result))
1140 expect = given
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001141 result = urllib.request.url2pathname(result)
Brett Cannon74bfd702003-04-25 09:39:47 +00001142 self.assertEqual(expect, result,
1143 "url2pathname() failed; %s != %s" %
1144 (expect, result))
1145 given = os.path.join("make sure", "using_quote")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001146 expect = "%s/using_quote" % urllib.parse.quote("make sure")
1147 result = urllib.request.pathname2url(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001148 self.assertEqual(expect, result,
1149 "pathname2url() failed; %s != %s" %
1150 (expect, result))
1151 given = "make+sure/using_unquote"
1152 expect = os.path.join("make+sure", "using_unquote")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001153 result = urllib.request.url2pathname(given)
Brett Cannon74bfd702003-04-25 09:39:47 +00001154 self.assertEqual(expect, result,
1155 "url2pathname() failed; %s != %s" %
1156 (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +00001157
Senthil Kumaran2d2ea1b2011-04-14 13:16:30 +08001158 @unittest.skipUnless(sys.platform == 'win32',
1159 'test specific to the urllib.url2path function.')
1160 def test_ntpath(self):
1161 given = ('/C:/', '///C:/', '/C|//')
1162 expect = 'C:\\'
1163 for url in given:
1164 result = urllib.request.url2pathname(url)
1165 self.assertEqual(expect, result,
1166 'urllib.request..url2pathname() failed; %s != %s' %
1167 (expect, result))
1168 given = '///C|/path'
1169 expect = 'C:\\path'
1170 result = urllib.request.url2pathname(given)
1171 self.assertEqual(expect, result,
1172 'urllib.request.url2pathname() failed; %s != %s' %
1173 (expect, result))
1174
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001175class Utility_Tests(unittest.TestCase):
1176 """Testcase to test the various utility functions in the urllib."""
1177
1178 def test_splitpasswd(self):
1179 """Some of password examples are not sensible, but it is added to
1180 confirming to RFC2617 and addressing issue4675.
1181 """
1182 self.assertEqual(('user', 'ab'),urllib.parse.splitpasswd('user:ab'))
1183 self.assertEqual(('user', 'a\nb'),urllib.parse.splitpasswd('user:a\nb'))
1184 self.assertEqual(('user', 'a\tb'),urllib.parse.splitpasswd('user:a\tb'))
1185 self.assertEqual(('user', 'a\rb'),urllib.parse.splitpasswd('user:a\rb'))
1186 self.assertEqual(('user', 'a\fb'),urllib.parse.splitpasswd('user:a\fb'))
1187 self.assertEqual(('user', 'a\vb'),urllib.parse.splitpasswd('user:a\vb'))
1188 self.assertEqual(('user', 'a:b'),urllib.parse.splitpasswd('user:a:b'))
Senthil Kumaranc5c5a142012-01-14 19:09:04 +08001189 self.assertEqual(('user', 'a b'),urllib.parse.splitpasswd('user:a b'))
1190 self.assertEqual(('user 2', 'ab'),urllib.parse.splitpasswd('user 2:ab'))
1191 self.assertEqual(('user+1', 'a+b'),urllib.parse.splitpasswd('user+1:a+b'))
Senthil Kumaraneaaec272009-03-30 21:54:41 +00001192
Senthil Kumaran1b7da512011-10-06 00:32:02 +08001193 def test_thishost(self):
1194 """Test the urllib.request.thishost utility function returns a tuple"""
1195 self.assertIsInstance(urllib.request.thishost(), tuple)
1196
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001197
1198class URLopener_Tests(unittest.TestCase):
1199 """Testcase to test the open method of URLopener class."""
1200
1201 def test_quoted_open(self):
1202 class DummyURLopener(urllib.request.URLopener):
1203 def open_spam(self, url):
1204 return url
Ezio Melotti79b99db2013-02-21 02:41:42 +02001205 with support.check_warnings(
1206 ('DummyURLopener style of invoking requests is deprecated.',
1207 DeprecationWarning)):
1208 self.assertEqual(DummyURLopener().open(
1209 'spam://example/ /'),'//example/%20/')
Senthil Kumaran690ce9b2009-05-05 18:41:13 +00001210
Ezio Melotti79b99db2013-02-21 02:41:42 +02001211 # test the safe characters are not quoted by urlopen
1212 self.assertEqual(DummyURLopener().open(
1213 "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"),
1214 "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/")
Senthil Kumaran734f0592010-02-20 22:19:04 +00001215
Guido van Rossume7ba4952007-06-06 23:52:48 +00001216# Just commented them out.
1217# Can't really tell why keep failing in windows and sparc.
Ezio Melotti13925002011-03-16 11:05:33 +02001218# Everywhere else they work ok, but on those machines, sometimes
Guido van Rossume7ba4952007-06-06 23:52:48 +00001219# fail in one of the tests, sometimes in other. I have a linux, and
1220# the tests go ok.
Ezio Melotti85a86292013-08-17 16:57:41 +03001221# If anybody has one of the problematic environments, please help!
Guido van Rossume7ba4952007-06-06 23:52:48 +00001222# . Facundo
1223#
1224# def server(evt):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001225# import socket, time
Guido van Rossume7ba4952007-06-06 23:52:48 +00001226# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1227# serv.settimeout(3)
1228# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1229# serv.bind(("", 9093))
1230# serv.listen(5)
1231# try:
1232# conn, addr = serv.accept()
1233# conn.send("1 Hola mundo\n")
1234# cantdata = 0
1235# while cantdata < 13:
1236# data = conn.recv(13-cantdata)
1237# cantdata += len(data)
1238# time.sleep(.3)
1239# conn.send("2 No more lines\n")
1240# conn.close()
1241# except socket.timeout:
1242# pass
1243# finally:
1244# serv.close()
1245# evt.set()
1246#
1247# class FTPWrapperTests(unittest.TestCase):
1248#
1249# def setUp(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001250# import ftplib, time, threading
Guido van Rossume7ba4952007-06-06 23:52:48 +00001251# ftplib.FTP.port = 9093
1252# self.evt = threading.Event()
1253# threading.Thread(target=server, args=(self.evt,)).start()
1254# time.sleep(.1)
1255#
1256# def tearDown(self):
1257# self.evt.wait()
1258#
1259# def testBasic(self):
1260# # connects
1261# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
Georg Brandlf78e02b2008-06-10 17:40:04 +00001262# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001263#
1264# def testTimeoutNone(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +00001265# # global default timeout is ignored
1266# import socket
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001267# self.assertTrue(socket.getdefaulttimeout() is None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001268# socket.setdefaulttimeout(30)
1269# try:
1270# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1271# finally:
Georg Brandlf78e02b2008-06-10 17:40:04 +00001272# socket.setdefaulttimeout(None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001273# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
Georg Brandlf78e02b2008-06-10 17:40:04 +00001274# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001275#
Georg Brandlf78e02b2008-06-10 17:40:04 +00001276# def testTimeoutDefault(self):
1277# # global default timeout is used
1278# import socket
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001279# self.assertTrue(socket.getdefaulttimeout() is None)
Georg Brandlf78e02b2008-06-10 17:40:04 +00001280# socket.setdefaulttimeout(30)
1281# try:
1282# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1283# finally:
1284# socket.setdefaulttimeout(None)
1285# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1286# ftp.close()
1287#
1288# def testTimeoutValue(self):
1289# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
1290# timeout=30)
1291# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1292# ftp.close()
Guido van Rossume7ba4952007-06-06 23:52:48 +00001293
Senthil Kumarande49d642011-10-16 23:54:44 +08001294class RequestTests(unittest.TestCase):
1295 """Unit tests for urllib.request.Request."""
1296
1297 def test_default_values(self):
1298 Request = urllib.request.Request
1299 request = Request("http://www.python.org")
1300 self.assertEqual(request.get_method(), 'GET')
1301 request = Request("http://www.python.org", {})
1302 self.assertEqual(request.get_method(), 'POST')
1303
1304 def test_with_method_arg(self):
1305 Request = urllib.request.Request
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='HEAD')
1310 self.assertEqual(request.method, 'HEAD')
1311 self.assertEqual(request.get_method(), 'HEAD')
1312 request = Request("http://www.python.org", method='GET')
1313 self.assertEqual(request.get_method(), 'GET')
1314 request.method = 'HEAD'
1315 self.assertEqual(request.get_method(), 'HEAD')
Skip Montanaro080c9972001-01-28 21:12:22 +00001316
1317
Senthil Kumaran277e9092013-04-10 20:51:19 -07001318class URL2PathNameTests(unittest.TestCase):
Brett Cannon74bfd702003-04-25 09:39:47 +00001319
Senthil Kumaran277e9092013-04-10 20:51:19 -07001320 def test_converting_drive_letter(self):
1321 self.assertEqual(url2pathname("///C|"), 'C:')
1322 self.assertEqual(url2pathname("///C:"), 'C:')
1323 self.assertEqual(url2pathname("///C|/"), 'C:\\')
Brett Cannon74bfd702003-04-25 09:39:47 +00001324
Senthil Kumaran277e9092013-04-10 20:51:19 -07001325 def test_converting_when_no_drive_letter(self):
1326 # cannot end a raw string in \
1327 self.assertEqual(url2pathname("///C/test/"), r'\\\C\test' '\\')
1328 self.assertEqual(url2pathname("////C/test/"), r'\\C\test' '\\')
1329
1330 def test_simple_compare(self):
1331 self.assertEqual(url2pathname("///C|/foo/bar/spam.foo"),
1332 r'C:\foo\bar\spam.foo')
1333
1334 def test_non_ascii_drive_letter(self):
1335 self.assertRaises(IOError, url2pathname, "///\u00e8|/")
1336
1337 def test_roundtrip_url2pathname(self):
1338 list_of_paths = ['C:',
1339 r'\\\C\test\\',
1340 r'C:\foo\bar\spam.foo'
1341 ]
1342 for path in list_of_paths:
Senthil Kumaranf49581c2013-04-10 20:55:58 -07001343 self.assertEqual(url2pathname(pathname2url(path)), path)
Senthil Kumaran277e9092013-04-10 20:51:19 -07001344
1345class PathName2URLTests(unittest.TestCase):
1346
1347 def test_converting_drive_letter(self):
1348 self.assertEqual(pathname2url("C:"), '///C:')
1349 self.assertEqual(pathname2url("C:\\"), '///C:')
1350
1351 def test_converting_when_no_drive_letter(self):
1352 self.assertEqual(pathname2url(r"\\\folder\test" "\\"),
1353 '/////folder/test/')
1354 self.assertEqual(pathname2url(r"\\folder\test" "\\"),
1355 '////folder/test/')
1356 self.assertEqual(pathname2url(r"\folder\test" "\\"),
1357 '/folder/test/')
1358
1359 def test_simple_compare(self):
1360 self.assertEqual(pathname2url(r'C:\foo\bar\spam.foo'),
1361 "///C:/foo/bar/spam.foo" )
1362
1363 def test_long_drive_letter(self):
1364 self.assertRaises(IOError, pathname2url, "XX:\\")
1365
1366 def test_roundtrip_pathname2url(self):
1367 list_of_paths = ['///C:',
1368 '/////folder/test/',
1369 '///C:/foo/bar/spam.foo']
1370 for path in list_of_paths:
Senthil Kumaranf49581c2013-04-10 20:55:58 -07001371 self.assertEqual(pathname2url(url2pathname(path)), path)
Brett Cannon74bfd702003-04-25 09:39:47 +00001372
1373if __name__ == '__main__':
Senthil Kumaran277e9092013-04-10 20:51:19 -07001374 unittest.main()