blob: e14cccca167d6e89df022e80eaada4fd19f840df [file] [log] [blame]
Brett Cannon74bfd702003-04-25 09:39:47 +00001"""Regresssion tests for urllib"""
2
Jeremy Hylton6102e292000-08-31 15:48:10 +00003import urllib
Hye-Shik Chang39aef792004-06-05 13:30:56 +00004import httplib
Brett Cannon74bfd702003-04-25 09:39:47 +00005import unittest
Brett Cannon74bfd702003-04-25 09:39:47 +00006import os
Senthil Kumarana99b7612011-04-14 12:54:35 +08007import sys
Brett Cannon74bfd702003-04-25 09:39:47 +00008import mimetools
Georg Brandl5a650a22005-08-26 08:51:34 +00009import tempfile
Hye-Shik Chang39aef792004-06-05 13:30:56 +000010import StringIO
Jeremy Hylton6102e292000-08-31 15:48:10 +000011
Senthil Kumaranbcd833f2012-01-11 00:09:24 +080012from test import test_support
13from base64 import b64encode
14
15
Brett Cannon74bfd702003-04-25 09:39:47 +000016def hexescape(char):
17 """Escape char as RFC 2396 specifies"""
18 hex_repr = hex(ord(char))[2:].upper()
19 if len(hex_repr) == 1:
20 hex_repr = "0%s" % hex_repr
21 return "%" + hex_repr
Jeremy Hylton6102e292000-08-31 15:48:10 +000022
Senthil Kumaran87e58552011-11-01 02:44:45 +080023
24class FakeHTTPMixin(object):
25 def fakehttp(self, fakedata):
26 class FakeSocket(StringIO.StringIO):
27
Senthil Kumaranbcd833f2012-01-11 00:09:24 +080028 def sendall(self, data):
29 FakeHTTPConnection.buf = data
30
Senthil Kumaran87e58552011-11-01 02:44:45 +080031 def makefile(self, *args, **kwds):
32 return self
33
34 def read(self, amt=None):
35 if self.closed:
36 return ""
37 return StringIO.StringIO.read(self, amt)
38
39 def readline(self, length=None):
40 if self.closed:
41 return ""
42 return StringIO.StringIO.readline(self, length)
43
44 class FakeHTTPConnection(httplib.HTTPConnection):
Senthil Kumaranbcd833f2012-01-11 00:09:24 +080045
46 # buffer to store data for verification in urlopen tests.
47 buf = ""
48
Senthil Kumaran87e58552011-11-01 02:44:45 +080049 def connect(self):
50 self.sock = FakeSocket(fakedata)
Senthil Kumaranbcd833f2012-01-11 00:09:24 +080051
Senthil Kumaran87e58552011-11-01 02:44:45 +080052 assert httplib.HTTP._connection_class == httplib.HTTPConnection
Senthil Kumaranbcd833f2012-01-11 00:09:24 +080053
Senthil Kumaran87e58552011-11-01 02:44:45 +080054 httplib.HTTP._connection_class = FakeHTTPConnection
55
56 def unfakehttp(self):
57 httplib.HTTP._connection_class = httplib.HTTPConnection
58
59
Brett Cannon74bfd702003-04-25 09:39:47 +000060class urlopen_FileTests(unittest.TestCase):
61 """Test urlopen() opening a temporary file.
Jeremy Hylton6102e292000-08-31 15:48:10 +000062
Brett Cannon74bfd702003-04-25 09:39:47 +000063 Try to test as much functionality as possible so as to cut down on reliance
Andrew M. Kuchlingf1a2f9e2004-06-29 13:07:53 +000064 on connecting to the Net for testing.
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000065
Brett Cannon74bfd702003-04-25 09:39:47 +000066 """
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000067
Brett Cannon74bfd702003-04-25 09:39:47 +000068 def setUp(self):
69 """Setup of a temp file to use for testing"""
70 self.text = "test_urllib: %s\n" % self.__class__.__name__
Guido van Rossum51735b02003-04-25 15:01:05 +000071 FILE = file(test_support.TESTFN, 'wb')
Brett Cannon74bfd702003-04-25 09:39:47 +000072 try:
73 FILE.write(self.text)
74 finally:
75 FILE.close()
76 self.pathname = test_support.TESTFN
77 self.returned_obj = urllib.urlopen("file:%s" % self.pathname)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000078
Brett Cannon74bfd702003-04-25 09:39:47 +000079 def tearDown(self):
80 """Shut down the open object"""
81 self.returned_obj.close()
Brett Cannon19691362003-04-29 05:08:06 +000082 os.remove(test_support.TESTFN)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000083
Brett Cannon74bfd702003-04-25 09:39:47 +000084 def test_interface(self):
85 # Make sure object returned by urlopen() has the specified methods
86 for attr in ("read", "readline", "readlines", "fileno",
Georg Brandl9b0d46d2008-01-20 11:43:03 +000087 "close", "info", "geturl", "getcode", "__iter__"):
Benjamin Peterson5c8da862009-06-30 22:57:08 +000088 self.assertTrue(hasattr(self.returned_obj, attr),
Brett Cannon74bfd702003-04-25 09:39:47 +000089 "object returned by urlopen() lacks %s attribute" %
90 attr)
Skip Montanaroe78b92a2001-01-20 20:22:30 +000091
Brett Cannon74bfd702003-04-25 09:39:47 +000092 def test_read(self):
93 self.assertEqual(self.text, self.returned_obj.read())
Skip Montanaro080c9972001-01-28 21:12:22 +000094
Brett Cannon74bfd702003-04-25 09:39:47 +000095 def test_readline(self):
96 self.assertEqual(self.text, self.returned_obj.readline())
97 self.assertEqual('', self.returned_obj.readline(),
98 "calling readline() after exhausting the file did not"
99 " return an empty string")
Skip Montanaro080c9972001-01-28 21:12:22 +0000100
Brett Cannon74bfd702003-04-25 09:39:47 +0000101 def test_readlines(self):
102 lines_list = self.returned_obj.readlines()
103 self.assertEqual(len(lines_list), 1,
104 "readlines() returned the wrong number of lines")
105 self.assertEqual(lines_list[0], self.text,
106 "readlines() returned improper text")
Skip Montanaro080c9972001-01-28 21:12:22 +0000107
Brett Cannon74bfd702003-04-25 09:39:47 +0000108 def test_fileno(self):
109 file_num = self.returned_obj.fileno()
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000110 self.assertIsInstance(file_num, int, "fileno() did not return an int")
Brett Cannon74bfd702003-04-25 09:39:47 +0000111 self.assertEqual(os.read(file_num, len(self.text)), self.text,
112 "Reading on the file descriptor returned by fileno() "
113 "did not return the expected text")
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000114
Brett Cannon74bfd702003-04-25 09:39:47 +0000115 def test_close(self):
116 # Test close() by calling it hear and then having it be called again
117 # by the tearDown() method for the test
118 self.returned_obj.close()
Skip Montanaro080c9972001-01-28 21:12:22 +0000119
Brett Cannon74bfd702003-04-25 09:39:47 +0000120 def test_info(self):
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000121 self.assertIsInstance(self.returned_obj.info(), mimetools.Message)
Skip Montanaroe78b92a2001-01-20 20:22:30 +0000122
Brett Cannon74bfd702003-04-25 09:39:47 +0000123 def test_geturl(self):
124 self.assertEqual(self.returned_obj.geturl(), self.pathname)
Skip Montanaro080c9972001-01-28 21:12:22 +0000125
Georg Brandl9b0d46d2008-01-20 11:43:03 +0000126 def test_getcode(self):
127 self.assertEqual(self.returned_obj.getcode(), None)
128
Brett Cannon74bfd702003-04-25 09:39:47 +0000129 def test_iter(self):
130 # Test iterator
131 # Don't need to count number of iterations since test would fail the
132 # instant it returned anything beyond the first line from the
133 # comparison
134 for line in self.returned_obj.__iter__():
135 self.assertEqual(line, self.text)
Skip Montanaro080c9972001-01-28 21:12:22 +0000136
Senthil Kumaran58c60622012-01-21 11:43:02 +0800137 def test_relativelocalfile(self):
138 self.assertRaises(ValueError,urllib.urlopen,'./' + self.pathname)
139
Benjamin Peterson2c7470d2008-09-21 21:27:51 +0000140class ProxyTests(unittest.TestCase):
141
142 def setUp(self):
Walter Dörwald4b965f62009-04-26 20:51:44 +0000143 # Records changes to env vars
144 self.env = test_support.EnvironmentVarGuard()
Benjamin Peterson2c7470d2008-09-21 21:27:51 +0000145 # Delete all proxy related env vars
Senthil Kumaran7a2ee0b2010-01-08 19:20:25 +0000146 for k in os.environ.keys():
Walter Dörwald4b965f62009-04-26 20:51:44 +0000147 if 'proxy' in k.lower():
Senthil Kumarandc61ec32009-10-01 01:50:13 +0000148 self.env.unset(k)
Benjamin Peterson2c7470d2008-09-21 21:27:51 +0000149
150 def tearDown(self):
Benjamin Peterson2c7470d2008-09-21 21:27:51 +0000151 # Restore all proxy related env vars
Walter Dörwald4b965f62009-04-26 20:51:44 +0000152 self.env.__exit__()
153 del self.env
Benjamin Peterson2c7470d2008-09-21 21:27:51 +0000154
155 def test_getproxies_environment_keep_no_proxies(self):
Walter Dörwald4b965f62009-04-26 20:51:44 +0000156 self.env.set('NO_PROXY', 'localhost')
Benjamin Peterson2c7470d2008-09-21 21:27:51 +0000157 proxies = urllib.getproxies_environment()
158 # getproxies_environment use lowered case truncated (no '_proxy') keys
Ezio Melotti2623a372010-11-21 13:34:58 +0000159 self.assertEqual('localhost', proxies['no'])
Senthil Kumaranb5bd4c82011-08-06 12:24:33 +0800160 # List of no_proxies with space.
161 self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
162 self.assertTrue(urllib.proxy_bypass_environment('anotherdomain.com'))
Benjamin Peterson2c7470d2008-09-21 21:27:51 +0000163
164
Senthil Kumaran87e58552011-11-01 02:44:45 +0800165class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin):
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000166 """Test urlopen() opening a fake http connection."""
167
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000168 def test_read(self):
169 self.fakehttp('Hello!')
170 try:
171 fp = urllib.urlopen("http://python.org/")
172 self.assertEqual(fp.readline(), 'Hello!')
173 self.assertEqual(fp.readline(), '')
Georg Brandl9b0d46d2008-01-20 11:43:03 +0000174 self.assertEqual(fp.geturl(), 'http://python.org/')
175 self.assertEqual(fp.getcode(), 200)
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000176 finally:
177 self.unfakehttp()
178
Senthil Kumaran49c44082011-04-13 07:31:45 +0800179 def test_url_fragment(self):
180 # Issue #11703: geturl() omits fragments in the original URL.
181 url = 'http://docs.python.org/library/urllib.html#OK'
182 self.fakehttp('Hello!')
183 try:
184 fp = urllib.urlopen(url)
185 self.assertEqual(fp.geturl(), url)
186 finally:
187 self.unfakehttp()
188
Kurt B. Kaiser0f7c25d2008-01-02 04:11:28 +0000189 def test_read_bogus(self):
Kurt B. Kaiser0a112322008-01-02 05:23:38 +0000190 # urlopen() should raise IOError for many error codes.
Kurt B. Kaiser0f7c25d2008-01-02 04:11:28 +0000191 self.fakehttp('''HTTP/1.1 401 Authentication Required
192Date: Wed, 02 Jan 2008 03:03:54 GMT
193Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
194Connection: close
195Content-Type: text/html; charset=iso-8859-1
196''')
197 try:
198 self.assertRaises(IOError, urllib.urlopen, "http://python.org/")
199 finally:
200 self.unfakehttp()
201
guido@google.comf1509302011-03-28 13:47:01 -0700202 def test_invalid_redirect(self):
203 # urlopen() should raise IOError for many error codes.
204 self.fakehttp("""HTTP/1.1 302 Found
205Date: Wed, 02 Jan 2008 03:03:54 GMT
206Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
207Location: file:README
208Connection: close
209Content-Type: text/html; charset=iso-8859-1
210""")
211 try:
Martin Panterade40972016-02-04 06:01:35 +0000212 msg = "Redirection to url 'file:"
213 with self.assertRaisesRegexp(IOError, msg):
214 urllib.urlopen("http://python.org/")
guido@google.comf1509302011-03-28 13:47:01 -0700215 finally:
216 self.unfakehttp()
217
Martin Panterade40972016-02-04 06:01:35 +0000218 def test_redirect_limit_independent(self):
219 # Ticket #12923: make sure independent requests each use their
220 # own retry limit.
221 for i in range(urllib.FancyURLopener().maxtries):
222 self.fakehttp(b'''HTTP/1.1 302 Found
223Location: file://guidocomputer.athome.com:/python/license
224Connection: close
225''')
226 try:
227 self.assertRaises(IOError, urllib.urlopen,
228 "http://something")
229 finally:
230 self.unfakehttp()
231
Georg Brandlf66b6032007-03-14 08:27:52 +0000232 def test_empty_socket(self):
Kurt B. Kaiser0a112322008-01-02 05:23:38 +0000233 # urlopen() raises IOError if the underlying socket does not send any
234 # data. (#1680230)
Georg Brandlf66b6032007-03-14 08:27:52 +0000235 self.fakehttp('')
236 try:
237 self.assertRaises(IOError, urllib.urlopen, 'http://something')
238 finally:
239 self.unfakehttp()
240
Senthil Kumaranf8d370e2012-10-27 03:48:40 -0700241 def test_missing_localfile(self):
242 self.assertRaises(IOError, urllib.urlopen,
243 'file://localhost/a/missing/file.py')
244 fd, tmp_file = tempfile.mkstemp()
245 tmp_fileurl = 'file://localhost/' + tmp_file.replace(os.path.sep, '/')
Senthil Kumarana085f002013-06-01 07:59:10 -0700246 self.assertTrue(os.path.exists(tmp_file))
Senthil Kumaranf8d370e2012-10-27 03:48:40 -0700247 try:
Senthil Kumaranf8d370e2012-10-27 03:48:40 -0700248 fp = urllib.urlopen(tmp_fileurl)
Senthil Kumarana085f002013-06-01 07:59:10 -0700249 fp.close()
Senthil Kumaranf8d370e2012-10-27 03:48:40 -0700250 finally:
251 os.close(fd)
Senthil Kumarana085f002013-06-01 07:59:10 -0700252 os.unlink(tmp_file)
Senthil Kumaranf8d370e2012-10-27 03:48:40 -0700253
254 self.assertFalse(os.path.exists(tmp_file))
255 self.assertRaises(IOError, urllib.urlopen, tmp_fileurl)
256
257 def test_ftp_nonexisting(self):
258 self.assertRaises(IOError, urllib.urlopen,
259 'ftp://localhost/not/existing/file.py')
260
261
Senthil Kumaranbcd833f2012-01-11 00:09:24 +0800262 def test_userpass_inurl(self):
263 self.fakehttp('Hello!')
264 try:
265 fakehttp_wrapper = httplib.HTTP._connection_class
266 fp = urllib.urlopen("http://user:pass@python.org/")
267 authorization = ("Authorization: Basic %s\r\n" %
268 b64encode('user:pass'))
269 # The authorization header must be in place
270 self.assertIn(authorization, fakehttp_wrapper.buf)
271 self.assertEqual(fp.readline(), "Hello!")
272 self.assertEqual(fp.readline(), "")
273 self.assertEqual(fp.geturl(), 'http://user:pass@python.org/')
274 self.assertEqual(fp.getcode(), 200)
275 finally:
276 self.unfakehttp()
277
278 def test_userpass_with_spaces_inurl(self):
279 self.fakehttp('Hello!')
280 try:
281 url = "http://a b:c d@python.org/"
282 fakehttp_wrapper = httplib.HTTP._connection_class
283 authorization = ("Authorization: Basic %s\r\n" %
284 b64encode('a b:c d'))
285 fp = urllib.urlopen(url)
286 # The authorization header must be in place
287 self.assertIn(authorization, fakehttp_wrapper.buf)
288 self.assertEqual(fp.readline(), "Hello!")
289 self.assertEqual(fp.readline(), "")
290 # the spaces are quoted in URL so no match
291 self.assertNotEqual(fp.geturl(), url)
292 self.assertEqual(fp.getcode(), 200)
293 finally:
294 self.unfakehttp()
295
296
Brett Cannon19691362003-04-29 05:08:06 +0000297class urlretrieve_FileTests(unittest.TestCase):
Brett Cannon74bfd702003-04-25 09:39:47 +0000298 """Test urllib.urlretrieve() on local files"""
Skip Montanaro080c9972001-01-28 21:12:22 +0000299
Brett Cannon19691362003-04-29 05:08:06 +0000300 def setUp(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000301 # Create a list of temporary files. Each item in the list is a file
302 # name (absolute path or relative to the current working directory).
303 # All files in this list will be deleted in the tearDown method. Note,
304 # this only helps to makes sure temporary files get deleted, but it
305 # does nothing about trying to close files that may still be open. It
306 # is the responsibility of the developer to properly close files even
307 # when exceptional conditions occur.
308 self.tempFiles = []
309
Brett Cannon19691362003-04-29 05:08:06 +0000310 # Create a temporary file.
Georg Brandl5a650a22005-08-26 08:51:34 +0000311 self.registerFileForCleanUp(test_support.TESTFN)
Brett Cannon19691362003-04-29 05:08:06 +0000312 self.text = 'testing urllib.urlretrieve'
Georg Brandl5a650a22005-08-26 08:51:34 +0000313 try:
314 FILE = file(test_support.TESTFN, 'wb')
315 FILE.write(self.text)
316 FILE.close()
317 finally:
318 try: FILE.close()
319 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000320
321 def tearDown(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000322 # Delete the temporary files.
323 for each in self.tempFiles:
324 try: os.remove(each)
325 except: pass
326
327 def constructLocalFileUrl(self, filePath):
328 return "file://%s" % urllib.pathname2url(os.path.abspath(filePath))
329
330 def createNewTempFile(self, data=""):
331 """Creates a new temporary file containing the specified data,
332 registers the file for deletion during the test fixture tear down, and
333 returns the absolute path of the file."""
334
335 newFd, newFilePath = tempfile.mkstemp()
336 try:
337 self.registerFileForCleanUp(newFilePath)
338 newFile = os.fdopen(newFd, "wb")
339 newFile.write(data)
340 newFile.close()
341 finally:
342 try: newFile.close()
343 except: pass
344 return newFilePath
345
346 def registerFileForCleanUp(self, fileName):
347 self.tempFiles.append(fileName)
Brett Cannon19691362003-04-29 05:08:06 +0000348
349 def test_basic(self):
350 # Make sure that a local file just gets its own location returned and
351 # a headers value is returned.
352 result = urllib.urlretrieve("file:%s" % test_support.TESTFN)
353 self.assertEqual(result[0], test_support.TESTFN)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000354 self.assertIsInstance(result[1], mimetools.Message,
355 "did not get a mimetools.Message instance as "
356 "second returned value")
Brett Cannon19691362003-04-29 05:08:06 +0000357
358 def test_copy(self):
359 # Test that setting the filename argument works.
360 second_temp = "%s.2" % test_support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000361 self.registerFileForCleanUp(second_temp)
362 result = urllib.urlretrieve(self.constructLocalFileUrl(
363 test_support.TESTFN), second_temp)
Brett Cannon19691362003-04-29 05:08:06 +0000364 self.assertEqual(second_temp, result[0])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000365 self.assertTrue(os.path.exists(second_temp), "copy of the file was not "
Brett Cannon19691362003-04-29 05:08:06 +0000366 "made")
367 FILE = file(second_temp, 'rb')
368 try:
369 text = FILE.read()
Brett Cannon19691362003-04-29 05:08:06 +0000370 FILE.close()
Georg Brandl5a650a22005-08-26 08:51:34 +0000371 finally:
372 try: FILE.close()
373 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000374 self.assertEqual(self.text, text)
375
376 def test_reporthook(self):
377 # Make sure that the reporthook works.
378 def hooktester(count, block_size, total_size, count_holder=[0]):
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000379 self.assertIsInstance(count, int)
380 self.assertIsInstance(block_size, int)
381 self.assertIsInstance(total_size, int)
Brett Cannon19691362003-04-29 05:08:06 +0000382 self.assertEqual(count, count_holder[0])
383 count_holder[0] = count_holder[0] + 1
384 second_temp = "%s.2" % test_support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000385 self.registerFileForCleanUp(second_temp)
386 urllib.urlretrieve(self.constructLocalFileUrl(test_support.TESTFN),
387 second_temp, hooktester)
388
389 def test_reporthook_0_bytes(self):
390 # Test on zero length file. Should call reporthook only 1 time.
391 report = []
392 def hooktester(count, block_size, total_size, _report=report):
393 _report.append((count, block_size, total_size))
394 srcFileName = self.createNewTempFile()
395 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
396 test_support.TESTFN, hooktester)
397 self.assertEqual(len(report), 1)
398 self.assertEqual(report[0][2], 0)
399
400 def test_reporthook_5_bytes(self):
401 # Test on 5 byte file. Should call reporthook only 2 times (once when
402 # the "network connection" is established and once when the block is
403 # read). Since the block size is 8192 bytes, only one block read is
404 # required to read the entire file.
405 report = []
406 def hooktester(count, block_size, total_size, _report=report):
407 _report.append((count, block_size, total_size))
408 srcFileName = self.createNewTempFile("x" * 5)
409 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
410 test_support.TESTFN, hooktester)
411 self.assertEqual(len(report), 2)
412 self.assertEqual(report[0][1], 8192)
413 self.assertEqual(report[0][2], 5)
414
415 def test_reporthook_8193_bytes(self):
416 # Test on 8193 byte file. Should call reporthook only 3 times (once
417 # when the "network connection" is established, once for the next 8192
418 # bytes, and once for the last byte).
419 report = []
420 def hooktester(count, block_size, total_size, _report=report):
421 _report.append((count, block_size, total_size))
422 srcFileName = self.createNewTempFile("x" * 8193)
423 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
424 test_support.TESTFN, hooktester)
425 self.assertEqual(len(report), 3)
426 self.assertEqual(report[0][1], 8192)
427 self.assertEqual(report[0][2], 8193)
Skip Montanaro080c9972001-01-28 21:12:22 +0000428
Senthil Kumaran87e58552011-11-01 02:44:45 +0800429
430class urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin):
431 """Test urllib.urlretrieve() using fake http connections"""
432
433 def test_short_content_raises_ContentTooShortError(self):
434 self.fakehttp('''HTTP/1.1 200 OK
435Date: Wed, 02 Jan 2008 03:03:54 GMT
436Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
437Connection: close
438Content-Length: 100
439Content-Type: text/html; charset=iso-8859-1
440
441FF
442''')
443
444 def _reporthook(par1, par2, par3):
445 pass
446
447 try:
448 self.assertRaises(urllib.ContentTooShortError, urllib.urlretrieve,
449 'http://example.com', reporthook=_reporthook)
450 finally:
451 self.unfakehttp()
452
453 def test_short_content_raises_ContentTooShortError_without_reporthook(self):
454 self.fakehttp('''HTTP/1.1 200 OK
455Date: Wed, 02 Jan 2008 03:03:54 GMT
456Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
457Connection: close
458Content-Length: 100
459Content-Type: text/html; charset=iso-8859-1
460
461FF
462''')
463 try:
464 self.assertRaises(urllib.ContentTooShortError, urllib.urlretrieve, 'http://example.com/')
465 finally:
466 self.unfakehttp()
467
Brett Cannon74bfd702003-04-25 09:39:47 +0000468class QuotingTests(unittest.TestCase):
469 """Tests for urllib.quote() and urllib.quote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000470
Brett Cannon74bfd702003-04-25 09:39:47 +0000471 According to RFC 2396 ("Uniform Resource Identifiers), to escape a
472 character you write it as '%' + <2 character US-ASCII hex value>. The Python
473 code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
474 Case does not matter on the hex letters.
475
476 The various character sets specified are:
Tim Petersc2659cf2003-05-12 20:19:37 +0000477
Brett Cannon74bfd702003-04-25 09:39:47 +0000478 Reserved characters : ";/?:@&=+$,"
479 Have special meaning in URIs and must be escaped if not being used for
480 their special meaning
481 Data characters : letters, digits, and "-_.!~*'()"
482 Unreserved and do not need to be escaped; can be, though, if desired
483 Control characters : 0x00 - 0x1F, 0x7F
484 Have no use in URIs so must be escaped
485 space : 0x20
486 Must be escaped
487 Delimiters : '<>#%"'
488 Must be escaped
489 Unwise : "{}|\^[]`"
490 Must be escaped
Tim Petersc2659cf2003-05-12 20:19:37 +0000491
Brett Cannon74bfd702003-04-25 09:39:47 +0000492 """
493
494 def test_never_quote(self):
495 # Make sure quote() does not quote letters, digits, and "_,.-"
496 do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
497 "abcdefghijklmnopqrstuvwxyz",
498 "0123456789",
499 "_.-"])
500 result = urllib.quote(do_not_quote)
501 self.assertEqual(do_not_quote, result,
502 "using quote(): %s != %s" % (do_not_quote, result))
503 result = urllib.quote_plus(do_not_quote)
504 self.assertEqual(do_not_quote, result,
505 "using quote_plus(): %s != %s" % (do_not_quote, result))
506
507 def test_default_safe(self):
508 # Test '/' is default value for 'safe' parameter
509 self.assertEqual(urllib.quote.func_defaults[0], '/')
510
511 def test_safe(self):
512 # Test setting 'safe' parameter does what it should do
513 quote_by_default = "<>"
514 result = urllib.quote(quote_by_default, safe=quote_by_default)
515 self.assertEqual(quote_by_default, result,
516 "using quote(): %s != %s" % (quote_by_default, result))
517 result = urllib.quote_plus(quote_by_default, safe=quote_by_default)
518 self.assertEqual(quote_by_default, result,
519 "using quote_plus(): %s != %s" %
520 (quote_by_default, result))
521
522 def test_default_quoting(self):
523 # Make sure all characters that should be quoted are by default sans
524 # space (separate test for that).
525 should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
526 should_quote.append('<>#%"{}|\^[]`')
527 should_quote.append(chr(127)) # For 0x7F
528 should_quote = ''.join(should_quote)
529 for char in should_quote:
530 result = urllib.quote(char)
531 self.assertEqual(hexescape(char), result,
532 "using quote(): %s should be escaped to %s, not %s" %
533 (char, hexescape(char), result))
534 result = urllib.quote_plus(char)
535 self.assertEqual(hexescape(char), result,
536 "using quote_plus(): "
Tim Petersc2659cf2003-05-12 20:19:37 +0000537 "%s should be escapes to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000538 (char, hexescape(char), result))
539 del should_quote
540 partial_quote = "ab[]cd"
541 expected = "ab%5B%5Dcd"
542 result = urllib.quote(partial_quote)
543 self.assertEqual(expected, result,
544 "using quote(): %s != %s" % (expected, result))
Senthil Kumaran0d4c34c2011-09-13 06:42:21 +0800545 result = urllib.quote_plus(partial_quote)
Brett Cannon74bfd702003-04-25 09:39:47 +0000546 self.assertEqual(expected, result,
547 "using quote_plus(): %s != %s" % (expected, result))
Senthil Kumaranc7743aa2010-07-19 17:35:50 +0000548 self.assertRaises(TypeError, urllib.quote, None)
Brett Cannon74bfd702003-04-25 09:39:47 +0000549
550 def test_quoting_space(self):
551 # Make sure quote() and quote_plus() handle spaces as specified in
552 # their unique way
553 result = urllib.quote(' ')
554 self.assertEqual(result, hexescape(' '),
555 "using quote(): %s != %s" % (result, hexescape(' ')))
556 result = urllib.quote_plus(' ')
557 self.assertEqual(result, '+',
558 "using quote_plus(): %s != +" % result)
559 given = "a b cd e f"
560 expect = given.replace(' ', hexescape(' '))
561 result = urllib.quote(given)
562 self.assertEqual(expect, result,
563 "using quote(): %s != %s" % (expect, result))
564 expect = given.replace(' ', '+')
565 result = urllib.quote_plus(given)
566 self.assertEqual(expect, result,
567 "using quote_plus(): %s != %s" % (expect, result))
568
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000569 def test_quoting_plus(self):
570 self.assertEqual(urllib.quote_plus('alpha+beta gamma'),
571 'alpha%2Bbeta+gamma')
572 self.assertEqual(urllib.quote_plus('alpha+beta gamma', '+'),
573 'alpha+beta+gamma')
574
Brett Cannon74bfd702003-04-25 09:39:47 +0000575class UnquotingTests(unittest.TestCase):
576 """Tests for unquote() and unquote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000577
Brett Cannon74bfd702003-04-25 09:39:47 +0000578 See the doc string for quoting_Tests for details on quoting and such.
579
580 """
581
582 def test_unquoting(self):
583 # Make sure unquoting of all ASCII values works
584 escape_list = []
585 for num in range(128):
586 given = hexescape(chr(num))
587 expect = chr(num)
588 result = urllib.unquote(given)
589 self.assertEqual(expect, result,
590 "using unquote(): %s != %s" % (expect, result))
591 result = urllib.unquote_plus(given)
592 self.assertEqual(expect, result,
593 "using unquote_plus(): %s != %s" %
594 (expect, result))
595 escape_list.append(given)
596 escape_string = ''.join(escape_list)
597 del escape_list
598 result = urllib.unquote(escape_string)
599 self.assertEqual(result.count('%'), 1,
600 "using quote(): not all characters escaped; %s" %
601 result)
602 result = urllib.unquote(escape_string)
603 self.assertEqual(result.count('%'), 1,
604 "using unquote(): not all characters escaped: "
605 "%s" % result)
606
Senthil Kumaranf3e9b2a2010-03-18 12:14:15 +0000607 def test_unquoting_badpercent(self):
608 # Test unquoting on bad percent-escapes
609 given = '%xab'
610 expect = given
611 result = urllib.unquote(given)
612 self.assertEqual(expect, result, "using unquote(): %r != %r"
613 % (expect, result))
614 given = '%x'
615 expect = given
616 result = urllib.unquote(given)
617 self.assertEqual(expect, result, "using unquote(): %r != %r"
618 % (expect, result))
619 given = '%'
620 expect = given
621 result = urllib.unquote(given)
622 self.assertEqual(expect, result, "using unquote(): %r != %r"
623 % (expect, result))
624
625 def test_unquoting_mixed_case(self):
626 # Test unquoting on mixed-case hex digits in the percent-escapes
627 given = '%Ab%eA'
628 expect = '\xab\xea'
629 result = urllib.unquote(given)
630 self.assertEqual(expect, result, "using unquote(): %r != %r"
631 % (expect, result))
632
Brett Cannon74bfd702003-04-25 09:39:47 +0000633 def test_unquoting_parts(self):
634 # Make sure unquoting works when have non-quoted characters
635 # interspersed
636 given = 'ab%sd' % hexescape('c')
637 expect = "abcd"
638 result = urllib.unquote(given)
639 self.assertEqual(expect, result,
640 "using quote(): %s != %s" % (expect, result))
641 result = urllib.unquote_plus(given)
642 self.assertEqual(expect, result,
643 "using unquote_plus(): %s != %s" % (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +0000644
Brett Cannon74bfd702003-04-25 09:39:47 +0000645 def test_unquoting_plus(self):
646 # Test difference between unquote() and unquote_plus()
647 given = "are+there+spaces..."
648 expect = given
649 result = urllib.unquote(given)
650 self.assertEqual(expect, result,
651 "using unquote(): %s != %s" % (expect, result))
652 expect = given.replace('+', ' ')
653 result = urllib.unquote_plus(given)
654 self.assertEqual(expect, result,
655 "using unquote_plus(): %s != %s" % (expect, result))
656
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000657 def test_unquote_with_unicode(self):
658 r = urllib.unquote(u'br%C3%BCckner_sapporo_20050930.doc')
659 self.assertEqual(r, u'br\xc3\xbcckner_sapporo_20050930.doc')
660
Brett Cannon74bfd702003-04-25 09:39:47 +0000661class urlencode_Tests(unittest.TestCase):
662 """Tests for urlencode()"""
663
664 def help_inputtype(self, given, test_type):
665 """Helper method for testing different input types.
Tim Petersc2659cf2003-05-12 20:19:37 +0000666
Brett Cannon74bfd702003-04-25 09:39:47 +0000667 'given' must lead to only the pairs:
668 * 1st, 1
669 * 2nd, 2
670 * 3rd, 3
Tim Petersc2659cf2003-05-12 20:19:37 +0000671
Brett Cannon74bfd702003-04-25 09:39:47 +0000672 Test cannot assume anything about order. Docs make no guarantee and
673 have possible dictionary input.
Tim Petersc2659cf2003-05-12 20:19:37 +0000674
Brett Cannon74bfd702003-04-25 09:39:47 +0000675 """
676 expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
677 result = urllib.urlencode(given)
678 for expected in expect_somewhere:
Ezio Melottiaa980582010-01-23 23:04:36 +0000679 self.assertIn(expected, result,
Brett Cannon74bfd702003-04-25 09:39:47 +0000680 "testing %s: %s not found in %s" %
681 (test_type, expected, result))
682 self.assertEqual(result.count('&'), 2,
683 "testing %s: expected 2 '&'s; got %s" %
684 (test_type, result.count('&')))
685 amp_location = result.index('&')
686 on_amp_left = result[amp_location - 1]
687 on_amp_right = result[amp_location + 1]
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000688 self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(),
Brett Cannon74bfd702003-04-25 09:39:47 +0000689 "testing %s: '&' not located in proper place in %s" %
690 (test_type, result))
691 self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
692 "testing %s: "
693 "unexpected number of characters: %s != %s" %
694 (test_type, len(result), (5 * 3) + 2))
695
696 def test_using_mapping(self):
697 # Test passing in a mapping object as an argument.
698 self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
699 "using dict as input type")
700
701 def test_using_sequence(self):
702 # Test passing in a sequence of two-item sequences as an argument.
703 self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
704 "using sequence of two-item tuples as input")
705
706 def test_quoting(self):
707 # Make sure keys and values are quoted using quote_plus()
708 given = {"&":"="}
709 expect = "%s=%s" % (hexescape('&'), hexescape('='))
710 result = urllib.urlencode(given)
711 self.assertEqual(expect, result)
712 given = {"key name":"A bunch of pluses"}
713 expect = "key+name=A+bunch+of+pluses"
714 result = urllib.urlencode(given)
715 self.assertEqual(expect, result)
716
717 def test_doseq(self):
718 # Test that passing True for 'doseq' parameter works correctly
719 given = {'sequence':['1', '2', '3']}
720 expect = "sequence=%s" % urllib.quote_plus(str(['1', '2', '3']))
721 result = urllib.urlencode(given)
722 self.assertEqual(expect, result)
723 result = urllib.urlencode(given, True)
724 for value in given["sequence"]:
725 expect = "sequence=%s" % value
Ezio Melottiaa980582010-01-23 23:04:36 +0000726 self.assertIn(expect, result)
Brett Cannon74bfd702003-04-25 09:39:47 +0000727 self.assertEqual(result.count('&'), 2,
728 "Expected 2 '&'s, got %s" % result.count('&'))
729
730class Pathname_Tests(unittest.TestCase):
731 """Test pathname2url() and url2pathname()"""
732
733 def test_basic(self):
734 # Make sure simple tests pass
735 expected_path = os.path.join("parts", "of", "a", "path")
736 expected_url = "parts/of/a/path"
737 result = urllib.pathname2url(expected_path)
738 self.assertEqual(expected_url, result,
739 "pathname2url() failed; %s != %s" %
740 (result, expected_url))
741 result = urllib.url2pathname(expected_url)
742 self.assertEqual(expected_path, result,
743 "url2pathame() failed; %s != %s" %
744 (result, expected_path))
745
746 def test_quoting(self):
747 # Test automatic quoting and unquoting works for pathnam2url() and
748 # url2pathname() respectively
749 given = os.path.join("needs", "quot=ing", "here")
750 expect = "needs/%s/here" % urllib.quote("quot=ing")
751 result = urllib.pathname2url(given)
752 self.assertEqual(expect, result,
753 "pathname2url() failed; %s != %s" %
754 (expect, result))
755 expect = given
756 result = urllib.url2pathname(result)
757 self.assertEqual(expect, result,
758 "url2pathname() failed; %s != %s" %
759 (expect, result))
760 given = os.path.join("make sure", "using_quote")
761 expect = "%s/using_quote" % urllib.quote("make sure")
762 result = urllib.pathname2url(given)
763 self.assertEqual(expect, result,
764 "pathname2url() failed; %s != %s" %
765 (expect, result))
766 given = "make+sure/using_unquote"
767 expect = os.path.join("make+sure", "using_unquote")
768 result = urllib.url2pathname(given)
769 self.assertEqual(expect, result,
770 "url2pathname() failed; %s != %s" %
771 (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +0000772
Senthil Kumarana99b7612011-04-14 12:54:35 +0800773 @unittest.skipUnless(sys.platform == 'win32',
774 'test specific to the nturl2path library')
775 def test_ntpath(self):
776 given = ('/C:/', '///C:/', '/C|//')
777 expect = 'C:\\'
778 for url in given:
779 result = urllib.url2pathname(url)
780 self.assertEqual(expect, result,
781 'nturl2path.url2pathname() failed; %s != %s' %
782 (expect, result))
783 given = '///C|/path'
784 expect = 'C:\\path'
785 result = urllib.url2pathname(given)
786 self.assertEqual(expect, result,
787 'nturl2path.url2pathname() failed; %s != %s' %
788 (expect, result))
789
Senthil Kumaran5e95e762009-03-30 21:51:50 +0000790class Utility_Tests(unittest.TestCase):
791 """Testcase to test the various utility functions in the urllib."""
Serhiy Storchakaf0b630b2015-03-02 16:31:57 +0200792 # In Python 3 this test class is moved to test_urlparse.
793
794 def test_splittype(self):
795 splittype = urllib.splittype
796 self.assertEqual(splittype('type:opaquestring'), ('type', 'opaquestring'))
797 self.assertEqual(splittype('opaquestring'), (None, 'opaquestring'))
798 self.assertEqual(splittype(':opaquestring'), (None, ':opaquestring'))
799 self.assertEqual(splittype('type:'), ('type', ''))
800 self.assertEqual(splittype('type:opaque:string'), ('type', 'opaque:string'))
801
802 def test_splithost(self):
803 splithost = urllib.splithost
804 self.assertEqual(splithost('//www.example.org:80/foo/bar/baz.html'),
805 ('www.example.org:80', '/foo/bar/baz.html'))
806 self.assertEqual(splithost('//www.example.org:80'),
807 ('www.example.org:80', ''))
808 self.assertEqual(splithost('/foo/bar/baz.html'),
809 (None, '/foo/bar/baz.html'))
810
811 def test_splituser(self):
812 splituser = urllib.splituser
813 self.assertEqual(splituser('User:Pass@www.python.org:080'),
814 ('User:Pass', 'www.python.org:080'))
815 self.assertEqual(splituser('@www.python.org:080'),
816 ('', 'www.python.org:080'))
817 self.assertEqual(splituser('www.python.org:080'),
818 (None, 'www.python.org:080'))
819 self.assertEqual(splituser('User:Pass@'),
820 ('User:Pass', ''))
821 self.assertEqual(splituser('User@example.com:Pass@www.python.org:080'),
822 ('User@example.com:Pass', 'www.python.org:080'))
Senthil Kumaran5e95e762009-03-30 21:51:50 +0000823
824 def test_splitpasswd(self):
Serhiy Storchakaf0b630b2015-03-02 16:31:57 +0200825 # Some of the password examples are not sensible, but it is added to
826 # confirming to RFC2617 and addressing issue4675.
827 splitpasswd = urllib.splitpasswd
828 self.assertEqual(splitpasswd('user:ab'), ('user', 'ab'))
829 self.assertEqual(splitpasswd('user:a\nb'), ('user', 'a\nb'))
830 self.assertEqual(splitpasswd('user:a\tb'), ('user', 'a\tb'))
831 self.assertEqual(splitpasswd('user:a\rb'), ('user', 'a\rb'))
832 self.assertEqual(splitpasswd('user:a\fb'), ('user', 'a\fb'))
833 self.assertEqual(splitpasswd('user:a\vb'), ('user', 'a\vb'))
834 self.assertEqual(splitpasswd('user:a:b'), ('user', 'a:b'))
835 self.assertEqual(splitpasswd('user:a b'), ('user', 'a b'))
836 self.assertEqual(splitpasswd('user 2:ab'), ('user 2', 'ab'))
837 self.assertEqual(splitpasswd('user+1:a+b'), ('user+1', 'a+b'))
838 self.assertEqual(splitpasswd('user:'), ('user', ''))
839 self.assertEqual(splitpasswd('user'), ('user', None))
840 self.assertEqual(splitpasswd(':ab'), ('', 'ab'))
Senthil Kumaran5e95e762009-03-30 21:51:50 +0000841
Serhiy Storchaka326b5ab2014-01-18 18:30:09 +0200842 def test_splitport(self):
843 splitport = urllib.splitport
844 self.assertEqual(splitport('parrot:88'), ('parrot', '88'))
845 self.assertEqual(splitport('parrot'), ('parrot', None))
846 self.assertEqual(splitport('parrot:'), ('parrot', None))
847 self.assertEqual(splitport('127.0.0.1'), ('127.0.0.1', None))
848 self.assertEqual(splitport('parrot:cheese'), ('parrot:cheese', None))
Serhiy Storchakaf0b630b2015-03-02 16:31:57 +0200849 self.assertEqual(splitport('[::1]:88'), ('[::1]', '88'))
850 self.assertEqual(splitport('[::1]'), ('[::1]', None))
851 self.assertEqual(splitport(':88'), ('', '88'))
Serhiy Storchaka326b5ab2014-01-18 18:30:09 +0200852
853 def test_splitnport(self):
854 splitnport = urllib.splitnport
855 self.assertEqual(splitnport('parrot:88'), ('parrot', 88))
856 self.assertEqual(splitnport('parrot'), ('parrot', -1))
857 self.assertEqual(splitnport('parrot', 55), ('parrot', 55))
858 self.assertEqual(splitnport('parrot:'), ('parrot', -1))
859 self.assertEqual(splitnport('parrot:', 55), ('parrot', 55))
860 self.assertEqual(splitnport('127.0.0.1'), ('127.0.0.1', -1))
861 self.assertEqual(splitnport('127.0.0.1', 55), ('127.0.0.1', 55))
862 self.assertEqual(splitnport('parrot:cheese'), ('parrot', None))
863 self.assertEqual(splitnport('parrot:cheese', 55), ('parrot', None))
864
Serhiy Storchakaf0b630b2015-03-02 16:31:57 +0200865 def test_splitquery(self):
866 # Normal cases are exercised by other tests; ensure that we also
867 # catch cases with no port specified (testcase ensuring coverage)
868 splitquery = urllib.splitquery
869 self.assertEqual(splitquery('http://python.org/fake?foo=bar'),
870 ('http://python.org/fake', 'foo=bar'))
871 self.assertEqual(splitquery('http://python.org/fake?foo=bar?'),
872 ('http://python.org/fake?foo=bar', ''))
873 self.assertEqual(splitquery('http://python.org/fake'),
874 ('http://python.org/fake', None))
875 self.assertEqual(splitquery('?foo=bar'), ('', 'foo=bar'))
876
877 def test_splittag(self):
878 splittag = urllib.splittag
879 self.assertEqual(splittag('http://example.com?foo=bar#baz'),
880 ('http://example.com?foo=bar', 'baz'))
881 self.assertEqual(splittag('http://example.com?foo=bar#'),
882 ('http://example.com?foo=bar', ''))
883 self.assertEqual(splittag('#baz'), ('', 'baz'))
884 self.assertEqual(splittag('http://example.com?foo=bar'),
885 ('http://example.com?foo=bar', None))
886 self.assertEqual(splittag('http://example.com?foo=bar#baz#boo'),
887 ('http://example.com?foo=bar#baz', 'boo'))
888
889 def test_splitattr(self):
890 splitattr = urllib.splitattr
891 self.assertEqual(splitattr('/path;attr1=value1;attr2=value2'),
892 ('/path', ['attr1=value1', 'attr2=value2']))
893 self.assertEqual(splitattr('/path;'), ('/path', ['']))
894 self.assertEqual(splitattr(';attr1=value1;attr2=value2'),
895 ('', ['attr1=value1', 'attr2=value2']))
896 self.assertEqual(splitattr('/path'), ('/path', []))
897
898 def test_splitvalue(self):
899 # Normal cases are exercised by other tests; test pathological cases
900 # with no key/value pairs. (testcase ensuring coverage)
901 splitvalue = urllib.splitvalue
902 self.assertEqual(splitvalue('foo=bar'), ('foo', 'bar'))
903 self.assertEqual(splitvalue('foo='), ('foo', ''))
904 self.assertEqual(splitvalue('=bar'), ('', 'bar'))
905 self.assertEqual(splitvalue('foobar'), ('foobar', None))
906 self.assertEqual(splitvalue('foo=bar=baz'), ('foo', 'bar=baz'))
907
908 def test_toBytes(self):
909 result = urllib.toBytes(u'http://www.python.org')
910 self.assertEqual(result, 'http://www.python.org')
911 self.assertRaises(UnicodeError, urllib.toBytes,
912 test_support.u(r'http://www.python.org/medi\u00e6val'))
913
914 def test_unwrap(self):
915 url = urllib.unwrap('<URL:type://host/path>')
916 self.assertEqual(url, 'type://host/path')
917
Senthil Kumaran5e95e762009-03-30 21:51:50 +0000918
Senthil Kumaran7c2867f2009-04-21 03:24:19 +0000919class URLopener_Tests(unittest.TestCase):
920 """Testcase to test the open method of URLopener class."""
921
922 def test_quoted_open(self):
923 class DummyURLopener(urllib.URLopener):
924 def open_spam(self, url):
925 return url
926
927 self.assertEqual(DummyURLopener().open(
928 'spam://example/ /'),'//example/%20/')
929
Senthil Kumaran18d5a692010-02-20 22:05:34 +0000930 # test the safe characters are not quoted by urlopen
931 self.assertEqual(DummyURLopener().open(
932 "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"),
933 "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/")
934
Senthil Kumaran7c2867f2009-04-21 03:24:19 +0000935
Facundo Batistad9880d02007-05-25 04:20:22 +0000936# Just commented them out.
937# Can't really tell why keep failing in windows and sparc.
Ezio Melottic2077b02011-03-16 12:34:31 +0200938# Everywhere else they work ok, but on those machines, sometimes
Facundo Batistad9880d02007-05-25 04:20:22 +0000939# fail in one of the tests, sometimes in other. I have a linux, and
940# the tests go ok.
Ezio Melotti419e23c2013-08-17 16:56:09 +0300941# If anybody has one of the problematic environments, please help!
Facundo Batistad9880d02007-05-25 04:20:22 +0000942# . Facundo
943#
944# def server(evt):
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000945# import socket, time
Facundo Batistad9880d02007-05-25 04:20:22 +0000946# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
947# serv.settimeout(3)
948# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
949# serv.bind(("", 9093))
950# serv.listen(5)
951# try:
952# conn, addr = serv.accept()
953# conn.send("1 Hola mundo\n")
954# cantdata = 0
955# while cantdata < 13:
956# data = conn.recv(13-cantdata)
957# cantdata += len(data)
958# time.sleep(.3)
959# conn.send("2 No more lines\n")
960# conn.close()
961# except socket.timeout:
962# pass
963# finally:
964# serv.close()
965# evt.set()
966#
967# class FTPWrapperTests(unittest.TestCase):
968#
969# def setUp(self):
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000970# import ftplib, time, threading
Facundo Batistad9880d02007-05-25 04:20:22 +0000971# ftplib.FTP.port = 9093
972# self.evt = threading.Event()
973# threading.Thread(target=server, args=(self.evt,)).start()
974# time.sleep(.1)
975#
976# def tearDown(self):
977# self.evt.wait()
978#
979# def testBasic(self):
980# # connects
981# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000982# ftp.close()
Facundo Batistad9880d02007-05-25 04:20:22 +0000983#
984# def testTimeoutNone(self):
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000985# # global default timeout is ignored
986# import socket
Serhiy Storchaka528bed82014-02-08 14:49:55 +0200987# self.assertIsNone(socket.getdefaulttimeout())
Facundo Batistad9880d02007-05-25 04:20:22 +0000988# socket.setdefaulttimeout(30)
989# try:
990# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
991# finally:
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000992# socket.setdefaulttimeout(None)
Facundo Batistad9880d02007-05-25 04:20:22 +0000993# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000994# ftp.close()
Facundo Batistad9880d02007-05-25 04:20:22 +0000995#
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000996# def testTimeoutDefault(self):
997# # global default timeout is used
998# import socket
Serhiy Storchaka528bed82014-02-08 14:49:55 +0200999# self.assertIsNone(socket.getdefaulttimeout())
Facundo Batista4f1b1ed2008-05-29 16:39:26 +00001000# socket.setdefaulttimeout(30)
1001# try:
1002# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
1003# finally:
1004# socket.setdefaulttimeout(None)
1005# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1006# ftp.close()
1007#
1008# def testTimeoutValue(self):
1009# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
1010# timeout=30)
1011# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
1012# ftp.close()
Facundo Batista711a54e2007-05-24 17:50:54 +00001013
Skip Montanaro080c9972001-01-28 21:12:22 +00001014
1015
Brett Cannon74bfd702003-04-25 09:39:47 +00001016def test_main():
Brett Cannon8bb8fa52008-07-02 01:57:08 +00001017 import warnings
Brett Cannon672237d2008-09-09 00:49:16 +00001018 with warnings.catch_warnings():
Brett Cannon8bb8fa52008-07-02 01:57:08 +00001019 warnings.filterwarnings('ignore', ".*urllib\.urlopen.*Python 3.0",
1020 DeprecationWarning)
1021 test_support.run_unittest(
1022 urlopen_FileTests,
1023 urlopen_HttpTests,
1024 urlretrieve_FileTests,
Senthil Kumaran87e58552011-11-01 02:44:45 +08001025 urlretrieve_HttpTests,
Benjamin Peterson2c7470d2008-09-21 21:27:51 +00001026 ProxyTests,
Brett Cannon8bb8fa52008-07-02 01:57:08 +00001027 QuotingTests,
1028 UnquotingTests,
1029 urlencode_Tests,
1030 Pathname_Tests,
Senthil Kumaran5e95e762009-03-30 21:51:50 +00001031 Utility_Tests,
Senthil Kumaran7c2867f2009-04-21 03:24:19 +00001032 URLopener_Tests,
Brett Cannon8bb8fa52008-07-02 01:57:08 +00001033 #FTPWrapperTests,
1034 )
Brett Cannon74bfd702003-04-25 09:39:47 +00001035
1036
1037
1038if __name__ == '__main__':
1039 test_main()