blob: fae7e4d2bfb9ec5c6a2286781a53d6ffac729020 [file] [log] [blame]
Jeremy Hylton5d9c3032004-08-07 17:40:50 +00001#!/usr/bin/env python
2
3import unittest
4from test import test_support
Thomas Wouters477c8d52006-05-27 19:21:47 +00005from test.test_urllib2 import sanepathname2url
Jeremy Hylton5d9c3032004-08-07 17:40:50 +00006
7import socket
8import urllib2
9import sys
10import os
11import mimetools
12
13class URLTimeoutTest(unittest.TestCase):
14
15 TIMEOUT = 10.0
16
17 def setUp(self):
18 socket.setdefaulttimeout(self.TIMEOUT)
19
20 def tearDown(self):
21 socket.setdefaulttimeout(None)
22
23 def testURLread(self):
24 f = urllib2.urlopen("http://www.python.org/")
25 x = f.read()
26
Thomas Wouters477c8d52006-05-27 19:21:47 +000027
28class AuthTests(unittest.TestCase):
29 """Tests urllib2 authentication features."""
30
31## Disabled at the moment since there is no page under python.org which
32## could be used to HTTP authentication.
33#
34# def test_basic_auth(self):
35# import httplib
36#
37# test_url = "http://www.python.org/test/test_urllib2/basic_auth"
38# test_hostport = "www.python.org"
39# test_realm = 'Test Realm'
40# test_user = 'test.test_urllib2net'
41# test_password = 'blah'
42#
43# # failure
44# try:
45# urllib2.urlopen(test_url)
46# except urllib2.HTTPError, exc:
47# self.assertEqual(exc.code, 401)
48# else:
49# self.fail("urlopen() should have failed with 401")
50#
51# # success
52# auth_handler = urllib2.HTTPBasicAuthHandler()
53# auth_handler.add_password(test_realm, test_hostport,
54# test_user, test_password)
55# opener = urllib2.build_opener(auth_handler)
56# f = opener.open('http://localhost/')
57# response = urllib2.urlopen("http://www.python.org/")
58#
59# # The 'userinfo' URL component is deprecated by RFC 3986 for security
60# # reasons, let's not implement it! (it's already implemented for proxy
61# # specification strings (that is, URLs or authorities specifying a
62# # proxy), so we must keep that)
63# self.assertRaises(httplib.InvalidURL,
64# urllib2.urlopen, "http://evil:thing@example.com")
65
66
Thomas Woutersb2137042007-02-01 18:02:27 +000067class CloseSocketTest(unittest.TestCase):
68
69 def test_close(self):
70 import socket, httplib, gc
71
72 # calling .close() on urllib2's response objects should close the
73 # underlying socket
74
75 # delve deep into response to fetch socket._socketobject
76 response = urllib2.urlopen("http://www.python.org/")
77 abused_fileobject = response.fp
Jeremy Hyltonec0c5082007-08-03 21:03:02 +000078 httpresponse = abused_fileobject.raw
Thomas Woutersb2137042007-02-01 18:02:27 +000079 self.assert_(httpresponse.__class__ is httplib.HTTPResponse)
80 fileobject = httpresponse.fp
Thomas Woutersb2137042007-02-01 18:02:27 +000081
82 self.assert_(not fileobject.closed)
83 response.close()
84 self.assert_(fileobject.closed)
85
Jeremy Hylton5d9c3032004-08-07 17:40:50 +000086class urlopenNetworkTests(unittest.TestCase):
87 """Tests urllib2.urlopen using the network.
88
89 These tests are not exhaustive. Assuming that testing using files does a
90 good job overall of some of the basic interface features. There are no
91 tests exercising the optional 'data' and 'proxies' arguments. No tests
92 for transparent redirection have been written.
93
94 setUp is not used for always constructing a connection to
95 http://www.python.org/ since there a few tests that don't use that address
96 and making a connection is expensive enough to warrant minimizing unneeded
97 connections.
98
99 """
100
101 def test_basic(self):
102 # Simple test expected to pass.
103 open_url = urllib2.urlopen("http://www.python.org/")
104 for attr in ("read", "close", "info", "geturl"):
105 self.assert_(hasattr(open_url, attr), "object returned from "
106 "urlopen lacks the %s attribute" % attr)
107 try:
108 self.assert_(open_url.read(), "calling 'read' failed")
109 finally:
110 open_url.close()
111
112 def test_info(self):
113 # Test 'info'.
114 open_url = urllib2.urlopen("http://www.python.org/")
115 try:
116 info_obj = open_url.info()
117 finally:
118 open_url.close()
119 self.assert_(isinstance(info_obj, mimetools.Message),
120 "object returned by 'info' is not an instance of "
121 "mimetools.Message")
122 self.assertEqual(info_obj.getsubtype(), "html")
123
124 def test_geturl(self):
125 # Make sure same URL as opened is returned by geturl.
126 URL = "http://www.python.org/"
127 open_url = urllib2.urlopen(URL)
128 try:
129 gotten_url = open_url.geturl()
130 finally:
131 open_url.close()
132 self.assertEqual(gotten_url, URL)
133
134 def test_bad_address(self):
135 # Make sure proper exception is raised when connecting to a bogus
136 # address.
137 self.assertRaises(IOError,
138 # SF patch 809915: In Sep 2003, VeriSign started
139 # highjacking invalid .com and .net addresses to
140 # boost traffic to their own site. This test
141 # started failing then. One hopes the .invalid
142 # domain will be spared to serve its defined
143 # purpose.
144 # urllib2.urlopen, "http://www.sadflkjsasadf.com/")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000145 urllib2.urlopen, "http://www.python.invalid./")
Jeremy Hylton5d9c3032004-08-07 17:40:50 +0000146
Thomas Wouters477c8d52006-05-27 19:21:47 +0000147
148class OtherNetworkTests(unittest.TestCase):
149 def setUp(self):
150 if 0: # for debugging
151 import logging
152 logger = logging.getLogger("test_urllib2net")
153 logger.addHandler(logging.StreamHandler())
154
155 def test_range (self):
156 req = urllib2.Request("http://www.python.org",
157 headers={'Range': 'bytes=20-39'})
158 result = urllib2.urlopen(req)
159 data = result.read()
160 self.assertEqual(len(data), 20)
161
162 # XXX The rest of these tests aren't very good -- they don't check much.
163 # They do sometimes catch some major disasters, though.
164
165 def test_ftp(self):
166 urls = [
Gregory P. Smithc111d9f2007-09-09 23:55:55 +0000167 'ftp://ftp.kernel.org/pub/linux/kernel/README',
168 'ftp://ftp.kernel.org/pub/linux/kernel/non-existant-file',
169 #'ftp://ftp.kernel.org/pub/leenox/kernel/test',
Thomas Wouters477c8d52006-05-27 19:21:47 +0000170 'ftp://gatekeeper.research.compaq.com/pub/DEC/SRC'
171 '/research-reports/00README-Legal-Rules-Regs',
172 ]
173 self._test_urls(urls, self._extra_handlers())
174
Thomas Wouters477c8d52006-05-27 19:21:47 +0000175 def test_file(self):
176 TESTFN = test_support.TESTFN
177 f = open(TESTFN, 'w')
178 try:
179 f.write('hi there\n')
180 f.close()
181 urls = [
182 'file:'+sanepathname2url(os.path.abspath(TESTFN)),
Gregory P. Smithc111d9f2007-09-09 23:55:55 +0000183 ('file:///nonsensename/etc/passwd', None, urllib2.URLError),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000184 ]
185 self._test_urls(urls, self._extra_handlers())
186 finally:
187 os.remove(TESTFN)
188
189 def test_http(self):
190 urls = [
191 'http://www.espn.com/', # redirect
192 'http://www.python.org/Spanish/Inquistion/',
193 ('http://www.python.org/cgi-bin/faqw.py',
194 'query=pythonistas&querytype=simple&casefold=yes&req=search', None),
195 'http://www.python.org/',
196 ]
197 self._test_urls(urls, self._extra_handlers())
198
199 # XXX Following test depends on machine configurations that are internal
200 # to CNRI. Need to set up a public server with the right authentication
201 # configuration for test purposes.
202
203## def test_cnri(self):
204## if socket.gethostname() == 'bitdiddle':
205## localhost = 'bitdiddle.cnri.reston.va.us'
206## elif socket.gethostname() == 'bitdiddle.concentric.net':
207## localhost = 'localhost'
208## else:
209## localhost = None
210## if localhost is not None:
211## urls = [
212## 'file://%s/etc/passwd' % localhost,
213## 'http://%s/simple/' % localhost,
214## 'http://%s/digest/' % localhost,
215## 'http://%s/not/found.h' % localhost,
216## ]
217
218## bauth = HTTPBasicAuthHandler()
219## bauth.add_password('basic_test_realm', localhost, 'jhylton',
220## 'password')
221## dauth = HTTPDigestAuthHandler()
222## dauth.add_password('digest_test_realm', localhost, 'jhylton',
223## 'password')
224
225## self._test_urls(urls, self._extra_handlers()+[bauth, dauth])
226
227 def _test_urls(self, urls, handlers):
228 import socket
229 import time
230 import logging
231 debug = logging.getLogger("test_urllib2").debug
232
233 urllib2.install_opener(urllib2.build_opener(*handlers))
234
235 for url in urls:
236 if isinstance(url, tuple):
237 url, req, expected_err = url
238 else:
239 req = expected_err = None
240 debug(url)
241 try:
242 f = urllib2.urlopen(url, req)
Gregory P. Smithc111d9f2007-09-09 23:55:55 +0000243 except EnvironmentError as err:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000244 debug(err)
245 if expected_err:
Gregory P. Smithc111d9f2007-09-09 23:55:55 +0000246 msg = ("Didn't get expected error(s) %s for %s %s, got %s: %s" %
247 (expected_err, url, req, type(err), err))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000248 self.assert_(isinstance(err, expected_err), msg)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000249 else:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000250 with test_support.transient_internet():
251 buf = f.read()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000252 f.close()
253 debug("read %d bytes" % len(buf))
254 debug("******** next url coming up...")
255 time.sleep(0.1)
256
257 def _extra_handlers(self):
258 handlers = []
259
Thomas Wouters477c8d52006-05-27 19:21:47 +0000260 cfh = urllib2.CacheFTPHandler()
261 cfh.setTimeout(1)
262 handlers.append(cfh)
263
264 return handlers
265
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000266class TimeoutTest(unittest.TestCase):
267 def test_http_basic(self):
268 u = urllib2.urlopen("http://www.python.org")
Jeremy Hyltoncf2f4192007-08-03 20:31:38 +0000269 self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000270
271 def test_http_NoneWithdefault(self):
272 prev = socket.getdefaulttimeout()
273 socket.setdefaulttimeout(60)
274 try:
275 u = urllib2.urlopen("http://www.python.org", timeout=None)
Jeremy Hyltoncf2f4192007-08-03 20:31:38 +0000276 self.assertTrue(u.fp.raw.fp._sock.gettimeout(), 60)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000277 finally:
278 socket.setdefaulttimeout(prev)
279
280 def test_http_Value(self):
281 u = urllib2.urlopen("http://www.python.org", timeout=120)
Jeremy Hyltoncf2f4192007-08-03 20:31:38 +0000282 self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 120)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000283
284 def test_http_NoneNodefault(self):
285 u = urllib2.urlopen("http://www.python.org", timeout=None)
Jeremy Hyltoncf2f4192007-08-03 20:31:38 +0000286 self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000287
288 def test_ftp_basic(self):
289 u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/")
Jeremy Hyltoncf2f4192007-08-03 20:31:38 +0000290 self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000291
292 def test_ftp_NoneWithdefault(self):
293 prev = socket.getdefaulttimeout()
294 socket.setdefaulttimeout(60)
295 try:
Jeremy Hyltoncf2f4192007-08-03 20:31:38 +0000296 u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/",
297 timeout=None)
298 self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000299 finally:
300 socket.setdefaulttimeout(prev)
301
302 def test_ftp_NoneNodefault(self):
Jeremy Hyltoncf2f4192007-08-03 20:31:38 +0000303 u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/",
304 timeout=None)
305 self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000306
307 def test_ftp_Value(self):
308 u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/", timeout=60)
Jeremy Hyltoncf2f4192007-08-03 20:31:38 +0000309 self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000310
Thomas Wouters477c8d52006-05-27 19:21:47 +0000311
Jeremy Hylton5d9c3032004-08-07 17:40:50 +0000312def test_main():
313 test_support.requires("network")
Thomas Woutersb2137042007-02-01 18:02:27 +0000314 test_support.run_unittest(URLTimeoutTest,
315 urlopenNetworkTests,
316 AuthTests,
317 OtherNetworkTests,
318 CloseSocketTest,
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000319 TimeoutTest,
Thomas Woutersb2137042007-02-01 18:02:27 +0000320 )
Jeremy Hylton5d9c3032004-08-07 17:40:50 +0000321
322if __name__ == "__main__":
323 test_main()