blob: 7c4b1f7097861d61f8a3bfc091a50d648889e029 [file] [log] [blame]
Skip Montanaro89feabc2003-03-30 04:54:24 +00001import unittest
2from test import test_support
3
4import socket
Brett Cannona71319e2003-05-14 02:18:31 +00005import urllib
Skip Montanaro89feabc2003-03-30 04:54:24 +00006import sys
Brett Cannona71319e2003-05-14 02:18:31 +00007import os
Senthil Kumaran1b7f9e52010-05-01 08:01:56 +00008import time
9
Benjamin Petersonb2064732014-11-23 20:55:24 -060010try:
11 import ssl
12except ImportError:
13 ssl = None
14
15here = os.path.dirname(__file__)
16# Self-signed cert file for self-signed.pythontest.net
17CERT_selfsigned_pythontestdotnet = os.path.join(here, 'selfsigned_pythontestdotnet.pem')
18
Ezio Melottia2d46532010-01-30 07:22:54 +000019mimetools = test_support.import_module("mimetools", deprecated=True)
Skip Montanaro89feabc2003-03-30 04:54:24 +000020
Neal Norwitz5be30672008-01-26 05:54:48 +000021
22def _open_with_retry(func, host, *args, **kwargs):
23 # Connecting to remote hosts is flaky. Make it more robust
24 # by retrying the connection several times.
25 for i in range(3):
26 try:
27 return func(host, *args, **kwargs)
28 except IOError, last_exc:
29 continue
30 except:
31 raise
32 raise last_exc
33
34
Skip Montanaro89feabc2003-03-30 04:54:24 +000035class URLTimeoutTest(unittest.TestCase):
36
37 TIMEOUT = 10.0
38
39 def setUp(self):
40 socket.setdefaulttimeout(self.TIMEOUT)
41
42 def tearDown(self):
43 socket.setdefaulttimeout(None)
44
45 def testURLread(self):
Ned Deilyc7275332014-03-26 23:25:02 -070046 f = _open_with_retry(urllib.urlopen, "http://www.example.com/")
Skip Montanaro89feabc2003-03-30 04:54:24 +000047 x = f.read()
48
Brett Cannona71319e2003-05-14 02:18:31 +000049class urlopenNetworkTests(unittest.TestCase):
50 """Tests urllib.urlopen using the network.
Tim Peters813cec92003-05-16 15:35:10 +000051
Brett Cannona71319e2003-05-14 02:18:31 +000052 These tests are not exhaustive. Assuming that testing using files does a
53 good job overall of some of the basic interface features. There are no
54 tests exercising the optional 'data' and 'proxies' arguments. No tests
55 for transparent redirection have been written.
Tim Peters813cec92003-05-16 15:35:10 +000056
Brett Cannona71319e2003-05-14 02:18:31 +000057 setUp is not used for always constructing a connection to
Ned Deilyc7275332014-03-26 23:25:02 -070058 http://www.example.com/ since there a few tests that don't use that address
Brett Cannona71319e2003-05-14 02:18:31 +000059 and making a connection is expensive enough to warrant minimizing unneeded
60 connections.
Tim Peters813cec92003-05-16 15:35:10 +000061
Brett Cannona71319e2003-05-14 02:18:31 +000062 """
63
Neal Norwitz5be30672008-01-26 05:54:48 +000064 def urlopen(self, *args):
65 return _open_with_retry(urllib.urlopen, *args)
66
Brett Cannona71319e2003-05-14 02:18:31 +000067 def test_basic(self):
68 # Simple test expected to pass.
Ned Deilyc7275332014-03-26 23:25:02 -070069 open_url = self.urlopen("http://www.example.com/")
Brett Cannona71319e2003-05-14 02:18:31 +000070 for attr in ("read", "readline", "readlines", "fileno", "close",
71 "info", "geturl"):
Benjamin Peterson5c8da862009-06-30 22:57:08 +000072 self.assertTrue(hasattr(open_url, attr), "object returned from "
Brett Cannona71319e2003-05-14 02:18:31 +000073 "urlopen lacks the %s attribute" % attr)
74 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000075 self.assertTrue(open_url.read(), "calling 'read' failed")
Brett Cannona71319e2003-05-14 02:18:31 +000076 finally:
77 open_url.close()
78
79 def test_readlines(self):
80 # Test both readline and readlines.
Ned Deilyc7275332014-03-26 23:25:02 -070081 open_url = self.urlopen("http://www.example.com/")
Brett Cannona71319e2003-05-14 02:18:31 +000082 try:
Ezio Melottib0f5adc2010-01-24 16:58:36 +000083 self.assertIsInstance(open_url.readline(), basestring,
84 "readline did not return a string")
85 self.assertIsInstance(open_url.readlines(), list,
86 "readlines did not return a list")
Brett Cannona71319e2003-05-14 02:18:31 +000087 finally:
88 open_url.close()
89
90 def test_info(self):
91 # Test 'info'.
Ned Deilyc7275332014-03-26 23:25:02 -070092 open_url = self.urlopen("http://www.example.com/")
Brett Cannona71319e2003-05-14 02:18:31 +000093 try:
94 info_obj = open_url.info()
95 finally:
96 open_url.close()
Ezio Melottib0f5adc2010-01-24 16:58:36 +000097 self.assertIsInstance(info_obj, mimetools.Message,
98 "object returned by 'info' is not an "
99 "instance of mimetools.Message")
Brett Cannona71319e2003-05-14 02:18:31 +0000100 self.assertEqual(info_obj.getsubtype(), "html")
101
102 def test_geturl(self):
103 # Make sure same URL as opened is returned by geturl.
Ned Deilyc7275332014-03-26 23:25:02 -0700104 URL = "http://www.example.com/"
Neal Norwitz5be30672008-01-26 05:54:48 +0000105 open_url = self.urlopen(URL)
Brett Cannona71319e2003-05-14 02:18:31 +0000106 try:
107 gotten_url = open_url.geturl()
108 finally:
109 open_url.close()
110 self.assertEqual(gotten_url, URL)
111
Georg Brandl9b0d46d2008-01-20 11:43:03 +0000112 def test_getcode(self):
113 # test getcode() with the fancy opener to get 404 error codes
Ned Deilyc7275332014-03-26 23:25:02 -0700114 URL = "http://www.example.com/XXXinvalidXXX"
Georg Brandl9b0d46d2008-01-20 11:43:03 +0000115 open_url = urllib.FancyURLopener().open(URL)
116 try:
117 code = open_url.getcode()
118 finally:
119 open_url.close()
120 self.assertEqual(code, 404)
121
Zachary Ware1f702212013-12-10 14:09:20 -0600122 @unittest.skipIf(sys.platform in ('win32',), 'not appropriate for Windows')
123 @unittest.skipUnless(hasattr(os, 'fdopen'), 'os.fdopen not available')
Brett Cannona71319e2003-05-14 02:18:31 +0000124 def test_fileno(self):
125 # Make sure fd returned by fileno is valid.
Ned Deilyc7275332014-03-26 23:25:02 -0700126 open_url = self.urlopen("http://www.example.com/")
Tim Peters813cec92003-05-16 15:35:10 +0000127 fd = open_url.fileno()
128 FILE = os.fdopen(fd)
129 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000130 self.assertTrue(FILE.read(), "reading from file created using fd "
Tim Peters813cec92003-05-16 15:35:10 +0000131 "returned by fileno failed")
132 finally:
133 FILE.close()
Brett Cannona71319e2003-05-14 02:18:31 +0000134
135 def test_bad_address(self):
136 # Make sure proper exception is raised when connecting to a bogus
137 # address.
Antoine Pitroua4d58d22011-07-08 19:14:19 +0200138 bogus_domain = "sadflkjsasf.i.nvali.d"
139 try:
140 socket.gethostbyname(bogus_domain)
141 except socket.gaierror:
142 pass
143 else:
144 # This happens with some overzealous DNS providers such as OpenDNS
145 self.skipTest("%r should not resolve for test to work" % bogus_domain)
Brett Cannona71319e2003-05-14 02:18:31 +0000146 self.assertRaises(IOError,
Tim Peters0aab0022003-09-20 22:16:26 +0000147 # SF patch 809915: In Sep 2003, VeriSign started
148 # highjacking invalid .com and .net addresses to
149 # boost traffic to their own site. This test
150 # started failing then. One hopes the .invalid
151 # domain will be spared to serve its defined
152 # purpose.
153 # urllib.urlopen, "http://www.sadflkjsasadf.com/")
Antoine Pitroucc5b64a2008-12-15 00:39:51 +0000154 urllib.urlopen, "http://sadflkjsasf.i.nvali.d/")
Brett Cannona71319e2003-05-14 02:18:31 +0000155
156class urlretrieveNetworkTests(unittest.TestCase):
157 """Tests urllib.urlretrieve using the network."""
158
Neal Norwitz5be30672008-01-26 05:54:48 +0000159 def urlretrieve(self, *args):
160 return _open_with_retry(urllib.urlretrieve, *args)
161
Brett Cannona71319e2003-05-14 02:18:31 +0000162 def test_basic(self):
163 # Test basic functionality.
Ned Deilyc7275332014-03-26 23:25:02 -0700164 file_location,info = self.urlretrieve("http://www.example.com/")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000165 self.assertTrue(os.path.exists(file_location), "file location returned by"
Brett Cannona71319e2003-05-14 02:18:31 +0000166 " urlretrieve is not a valid path")
167 FILE = file(file_location)
168 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000169 self.assertTrue(FILE.read(), "reading from the file location returned"
Jeremy Hyltonbd9f5202003-07-17 16:31:00 +0000170 " by urlretrieve failed")
Brett Cannona71319e2003-05-14 02:18:31 +0000171 finally:
172 FILE.close()
173 os.unlink(file_location)
174
175 def test_specified_path(self):
176 # Make sure that specifying the location of the file to write to works.
Ned Deilyc7275332014-03-26 23:25:02 -0700177 file_location,info = self.urlretrieve("http://www.example.com/",
Neal Norwitz5be30672008-01-26 05:54:48 +0000178 test_support.TESTFN)
Brett Cannona71319e2003-05-14 02:18:31 +0000179 self.assertEqual(file_location, test_support.TESTFN)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000180 self.assertTrue(os.path.exists(file_location))
Brett Cannona71319e2003-05-14 02:18:31 +0000181 FILE = file(file_location)
182 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000183 self.assertTrue(FILE.read(), "reading from temporary file failed")
Brett Cannona71319e2003-05-14 02:18:31 +0000184 finally:
185 FILE.close()
186 os.unlink(file_location)
187
188 def test_header(self):
189 # Make sure header returned as 2nd value from urlretrieve is good.
Ned Deilyc7275332014-03-26 23:25:02 -0700190 file_location, header = self.urlretrieve("http://www.example.com/")
Brett Cannona71319e2003-05-14 02:18:31 +0000191 os.unlink(file_location)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000192 self.assertIsInstance(header, mimetools.Message,
193 "header is not an instance of mimetools.Message")
Tim Peters813cec92003-05-16 15:35:10 +0000194
Senthil Kumaran1b7f9e52010-05-01 08:01:56 +0000195 def test_data_header(self):
Ned Deilyc7275332014-03-26 23:25:02 -0700196 logo = "http://www.example.com/"
Senthil Kumaran1b7f9e52010-05-01 08:01:56 +0000197 file_location, fileheaders = self.urlretrieve(logo)
198 os.unlink(file_location)
199 datevalue = fileheaders.getheader('Date')
200 dateformat = '%a, %d %b %Y %H:%M:%S GMT'
201 try:
202 time.strptime(datevalue, dateformat)
203 except ValueError:
204 self.fail('Date value not in %r format', dateformat)
205
Brett Cannona71319e2003-05-14 02:18:31 +0000206
Benjamin Petersonb2064732014-11-23 20:55:24 -0600207@unittest.skipIf(ssl is None, "requires ssl")
208class urlopen_HttpsTests(unittest.TestCase):
209
210 def test_context_argument(self):
211 context = ssl.create_default_context(cafile=CERT_selfsigned_pythontestdotnet)
212 response = urllib.urlopen("https://self-signed.pythontest.net", context=context)
213 self.assertIn("Python", response.read())
214
Brett Cannona71319e2003-05-14 02:18:31 +0000215
Skip Montanaro89feabc2003-03-30 04:54:24 +0000216def test_main():
217 test_support.requires('network')
Florent Xicluna6257a7b2010-03-31 22:01:03 +0000218 with test_support.check_py3k_warnings(
219 ("urllib.urlopen.. has been removed", DeprecationWarning)):
Brett Cannon8bb8fa52008-07-02 01:57:08 +0000220 test_support.run_unittest(URLTimeoutTest,
221 urlopenNetworkTests,
Benjamin Petersonb2064732014-11-23 20:55:24 -0600222 urlretrieveNetworkTests,
223 urlopen_HttpsTests)
Skip Montanaro89feabc2003-03-30 04:54:24 +0000224
225if __name__ == "__main__":
226 test_main()