blob: 9cc96971fbb0e3d1d4a42e7711fdab410e126d47 [file] [log] [blame]
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00003
Christian Heimes05e8be12008-02-23 18:30:17 +00004import os
Guido van Rossum34d19282007-08-09 01:03:29 +00005import io
Georg Brandlf78e02b2008-06-10 17:40:04 +00006import socket
Jeremy Hyltone3e61042001-05-09 15:50:25 +00007
Jeremy Hylton1afc1692008-06-18 20:49:58 +00008import urllib.request
9from urllib.request import Request, OpenerDirector
Jeremy Hyltone3e61042001-05-09 15:50:25 +000010
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +000011# XXX
12# Request
13# CacheFTPHandler (hard to write)
Thomas Wouters477c8d52006-05-27 19:21:47 +000014# parse_keqv_list, parse_http_list, HTTPDigestAuthHandler
Jeremy Hyltone3e61042001-05-09 15:50:25 +000015
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +000016class TrivialTests(unittest.TestCase):
17 def test_trivial(self):
18 # A couple trivial tests
Guido van Rossume2ae77b2001-10-24 20:42:55 +000019
Jeremy Hylton1afc1692008-06-18 20:49:58 +000020 self.assertRaises(ValueError, urllib.request.urlopen, 'bogus url')
Tim Peters861adac2001-07-16 20:49:49 +000021
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +000022 # XXX Name hacking to get this to work on Windows.
Jeremy Hylton1afc1692008-06-18 20:49:58 +000023 fname = os.path.abspath(urllib.request.__file__).replace('\\', '/')
Senthil Kumarand587e302010-01-10 17:45:52 +000024
Senthil Kumarand587e302010-01-10 17:45:52 +000025 if os.name == 'nt':
26 file_url = "file:///%s" % fname
27 else:
28 file_url = "file://%s" % fname
29
Jeremy Hylton1afc1692008-06-18 20:49:58 +000030 f = urllib.request.urlopen(file_url)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +000031
32 buf = f.read()
33 f.close()
Tim Petersf5f32b42005-07-17 23:16:17 +000034
Georg Brandle1b13d22005-08-24 22:20:32 +000035 def test_parse_http_list(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +000036 tests = [
37 ('a,b,c', ['a', 'b', 'c']),
38 ('path"o,l"og"i"cal, example', ['path"o,l"og"i"cal', 'example']),
39 ('a, b, "c", "d", "e,f", g, h',
40 ['a', 'b', '"c"', '"d"', '"e,f"', 'g', 'h']),
41 ('a="b\\"c", d="e\\,f", g="h\\\\i"',
42 ['a="b"c"', 'd="e,f"', 'g="h\\i"'])]
Georg Brandle1b13d22005-08-24 22:20:32 +000043 for string, list in tests:
Florent Xicluna419e3842010-08-08 16:16:07 +000044 self.assertEqual(urllib.request.parse_http_list(string), list)
Georg Brandle1b13d22005-08-24 22:20:32 +000045
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +000046
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000047def test_request_headers_dict():
48 """
49 The Request.headers dictionary is not a documented interface. It should
50 stay that way, because the complete set of headers are only accessible
51 through the .get_header(), .has_header(), .header_items() interface.
52 However, .headers pre-dates those methods, and so real code will be using
53 the dictionary.
54
55 The introduction in 2.4 of those methods was a mistake for the same reason:
56 code that previously saw all (urllib2 user)-provided headers in .headers
57 now sees only a subset (and the function interface is ugly and incomplete).
58 A better change would have been to replace .headers dict with a dict
59 subclass (or UserDict.DictMixin instance?) that preserved the .headers
60 interface and also provided access to the "unredirected" headers. It's
61 probably too late to fix that, though.
62
63
64 Check .capitalize() case normalization:
65
66 >>> url = "http://example.com"
67 >>> Request(url, headers={"Spam-eggs": "blah"}).headers["Spam-eggs"]
68 'blah'
69 >>> Request(url, headers={"spam-EggS": "blah"}).headers["Spam-eggs"]
70 'blah'
71
72 Currently, Request(url, "Spam-eggs").headers["Spam-Eggs"] raises KeyError,
73 but that could be changed in future.
74
75 """
76
77def test_request_headers_methods():
78 """
79 Note the case normalization of header names here, to .capitalize()-case.
80 This should be preserved for backwards-compatibility. (In the HTTP case,
81 normalization to .title()-case is done by urllib2 before sending headers to
Georg Brandl24420152008-05-26 16:32:26 +000082 http.client).
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000083
84 >>> url = "http://example.com"
85 >>> r = Request(url, headers={"Spam-eggs": "blah"})
86 >>> r.has_header("Spam-eggs")
87 True
88 >>> r.header_items()
89 [('Spam-eggs', 'blah')]
90 >>> r.add_header("Foo-Bar", "baz")
Guido van Rossumcc2b0162007-02-11 06:12:03 +000091 >>> items = sorted(r.header_items())
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000092 >>> items
93 [('Foo-bar', 'baz'), ('Spam-eggs', 'blah')]
94
95 Note that e.g. r.has_header("spam-EggS") is currently False, and
96 r.get_header("spam-EggS") returns None, but that could be changed in
97 future.
98
99 >>> r.has_header("Not-there")
100 False
Guido van Rossum7131f842007-02-09 20:13:25 +0000101 >>> print(r.get_header("Not-there"))
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000102 None
103 >>> r.get_header("Not-there", "default")
104 'default'
105
106 """
107
108
Thomas Wouters477c8d52006-05-27 19:21:47 +0000109def test_password_manager(self):
110 """
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000111 >>> mgr = urllib.request.HTTPPasswordMgr()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000112 >>> add = mgr.add_password
113 >>> add("Some Realm", "http://example.com/", "joe", "password")
114 >>> add("Some Realm", "http://example.com/ni", "ni", "ni")
115 >>> add("c", "http://example.com/foo", "foo", "ni")
116 >>> add("c", "http://example.com/bar", "bar", "nini")
117 >>> add("b", "http://example.com/", "first", "blah")
118 >>> add("b", "http://example.com/", "second", "spam")
119 >>> add("a", "http://example.com", "1", "a")
120 >>> add("Some Realm", "http://c.example.com:3128", "3", "c")
121 >>> add("Some Realm", "d.example.com", "4", "d")
122 >>> add("Some Realm", "e.example.com:3128", "5", "e")
123
124 >>> mgr.find_user_password("Some Realm", "example.com")
125 ('joe', 'password')
126 >>> mgr.find_user_password("Some Realm", "http://example.com")
127 ('joe', 'password')
128 >>> mgr.find_user_password("Some Realm", "http://example.com/")
129 ('joe', 'password')
130 >>> mgr.find_user_password("Some Realm", "http://example.com/spam")
131 ('joe', 'password')
132 >>> mgr.find_user_password("Some Realm", "http://example.com/spam/spam")
133 ('joe', 'password')
134 >>> mgr.find_user_password("c", "http://example.com/foo")
135 ('foo', 'ni')
136 >>> mgr.find_user_password("c", "http://example.com/bar")
137 ('bar', 'nini')
138
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000139 Actually, this is really undefined ATM
140## Currently, we use the highest-level path where more than one match:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000141
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000142## >>> mgr.find_user_password("Some Realm", "http://example.com/ni")
143## ('joe', 'password')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000144
145 Use latest add_password() in case of conflict:
146
147 >>> mgr.find_user_password("b", "http://example.com/")
148 ('second', 'spam')
149
150 No special relationship between a.example.com and example.com:
151
152 >>> mgr.find_user_password("a", "http://example.com/")
153 ('1', 'a')
154 >>> mgr.find_user_password("a", "http://a.example.com/")
155 (None, None)
156
157 Ports:
158
159 >>> mgr.find_user_password("Some Realm", "c.example.com")
160 (None, None)
161 >>> mgr.find_user_password("Some Realm", "c.example.com:3128")
162 ('3', 'c')
163 >>> mgr.find_user_password("Some Realm", "http://c.example.com:3128")
164 ('3', 'c')
165 >>> mgr.find_user_password("Some Realm", "d.example.com")
166 ('4', 'd')
167 >>> mgr.find_user_password("Some Realm", "e.example.com:3128")
168 ('5', 'e')
169
170 """
171 pass
172
173
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000174def test_password_manager_default_port(self):
175 """
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000176 >>> mgr = urllib.request.HTTPPasswordMgr()
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000177 >>> add = mgr.add_password
178
179 The point to note here is that we can't guess the default port if there's
180 no scheme. This applies to both add_password and find_user_password.
181
182 >>> add("f", "http://g.example.com:80", "10", "j")
183 >>> add("g", "http://h.example.com", "11", "k")
184 >>> add("h", "i.example.com:80", "12", "l")
185 >>> add("i", "j.example.com", "13", "m")
186 >>> mgr.find_user_password("f", "g.example.com:100")
187 (None, None)
188 >>> mgr.find_user_password("f", "g.example.com:80")
189 ('10', 'j')
190 >>> mgr.find_user_password("f", "g.example.com")
191 (None, None)
192 >>> mgr.find_user_password("f", "http://g.example.com:100")
193 (None, None)
194 >>> mgr.find_user_password("f", "http://g.example.com:80")
195 ('10', 'j')
196 >>> mgr.find_user_password("f", "http://g.example.com")
197 ('10', 'j')
198 >>> mgr.find_user_password("g", "h.example.com")
199 ('11', 'k')
200 >>> mgr.find_user_password("g", "h.example.com:80")
201 ('11', 'k')
202 >>> mgr.find_user_password("g", "http://h.example.com:80")
203 ('11', 'k')
204 >>> mgr.find_user_password("h", "i.example.com")
205 (None, None)
206 >>> mgr.find_user_password("h", "i.example.com:80")
207 ('12', 'l')
208 >>> mgr.find_user_password("h", "http://i.example.com:80")
209 ('12', 'l')
210 >>> mgr.find_user_password("i", "j.example.com")
211 ('13', 'm')
212 >>> mgr.find_user_password("i", "j.example.com:80")
213 (None, None)
214 >>> mgr.find_user_password("i", "http://j.example.com")
215 ('13', 'm')
216 >>> mgr.find_user_password("i", "http://j.example.com:80")
217 (None, None)
218
219 """
220
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000221class MockOpener:
222 addheaders = []
Senthil Kumaranfb8cc2f2009-07-19 02:44:19 +0000223 def open(self, req, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
224 self.req, self.data, self.timeout = req, data, timeout
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000225 def error(self, proto, *args):
226 self.proto, self.args = proto, args
227
228class MockFile:
229 def read(self, count=None): pass
230 def readline(self, count=None): pass
231 def close(self): pass
232
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000233class MockHeaders(dict):
234 def getheaders(self, name):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000235 return list(self.values())
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000236
Guido van Rossum34d19282007-08-09 01:03:29 +0000237class MockResponse(io.StringIO):
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000238 def __init__(self, code, msg, headers, data, url=None):
Guido van Rossum34d19282007-08-09 01:03:29 +0000239 io.StringIO.__init__(self, data)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000240 self.code, self.msg, self.headers, self.url = code, msg, headers, url
241 def info(self):
242 return self.headers
243 def geturl(self):
244 return self.url
245
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000246class MockCookieJar:
247 def add_cookie_header(self, request):
248 self.ach_req = request
249 def extract_cookies(self, response, request):
250 self.ec_req, self.ec_r = request, response
251
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000252class FakeMethod:
253 def __init__(self, meth_name, action, handle):
254 self.meth_name = meth_name
255 self.handle = handle
256 self.action = action
257 def __call__(self, *args):
258 return self.handle(self.meth_name, self.action, *args)
259
Senthil Kumaran47fff872009-12-20 07:10:31 +0000260class MockHTTPResponse(io.IOBase):
261 def __init__(self, fp, msg, status, reason):
262 self.fp = fp
263 self.msg = msg
264 self.status = status
265 self.reason = reason
266 self.code = 200
267
268 def read(self):
269 return ''
270
271 def info(self):
272 return {}
273
274 def geturl(self):
275 return self.url
276
277
278class MockHTTPClass:
279 def __init__(self):
280 self.level = 0
281 self.req_headers = []
282 self.data = None
283 self.raise_on_endheaders = False
284 self._tunnel_headers = {}
285
286 def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
287 self.host = host
288 self.timeout = timeout
289 return self
290
291 def set_debuglevel(self, level):
292 self.level = level
293
294 def set_tunnel(self, host, port=None, headers=None):
295 self._tunnel_host = host
296 self._tunnel_port = port
297 if headers:
298 self._tunnel_headers = headers
299 else:
300 self._tunnel_headers.clear()
301
Benjamin Peterson3d5b8db2009-12-24 01:14:05 +0000302 def request(self, method, url, body=None, headers=None):
Senthil Kumaran47fff872009-12-20 07:10:31 +0000303 self.method = method
304 self.selector = url
Benjamin Peterson3d5b8db2009-12-24 01:14:05 +0000305 if headers is not None:
306 self.req_headers += headers.items()
Senthil Kumaran47fff872009-12-20 07:10:31 +0000307 self.req_headers.sort()
308 if body:
309 self.data = body
310 if self.raise_on_endheaders:
311 import socket
312 raise socket.error()
313 def getresponse(self):
314 return MockHTTPResponse(MockFile(), {}, 200, "OK")
315
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000316class MockHandler:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317 # useful for testing handler machinery
318 # see add_ordered_mock_handlers() docstring
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000319 handler_order = 500
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000320 def __init__(self, methods):
321 self._define_methods(methods)
322 def _define_methods(self, methods):
323 for spec in methods:
324 if len(spec) == 2: name, action = spec
325 else: name, action = spec, None
326 meth = FakeMethod(name, action, self.handle)
327 setattr(self.__class__, name, meth)
328 def handle(self, fn_name, action, *args, **kwds):
329 self.parent.calls.append((self, fn_name, args, kwds))
330 if action is None:
331 return None
332 elif action == "return self":
333 return self
334 elif action == "return response":
335 res = MockResponse(200, "OK", {}, "")
336 return res
337 elif action == "return request":
338 return Request("http://blah/")
339 elif action.startswith("error"):
340 code = action[action.rfind(" ")+1:]
341 try:
342 code = int(code)
343 except ValueError:
344 pass
345 res = MockResponse(200, "OK", {}, "")
346 return self.parent.error("http", args[0], res, code, "", {})
347 elif action == "raise":
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000348 raise urllib.error.URLError("blah")
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000349 assert False
350 def close(self): pass
351 def add_parent(self, parent):
352 self.parent = parent
353 self.parent.calls = []
354 def __lt__(self, other):
355 if not hasattr(other, "handler_order"):
356 # No handler_order, leave in original order. Yuck.
357 return True
358 return self.handler_order < other.handler_order
359
360def add_ordered_mock_handlers(opener, meth_spec):
361 """Create MockHandlers and add them to an OpenerDirector.
362
363 meth_spec: list of lists of tuples and strings defining methods to define
364 on handlers. eg:
365
366 [["http_error", "ftp_open"], ["http_open"]]
367
368 defines methods .http_error() and .ftp_open() on one handler, and
369 .http_open() on another. These methods just record their arguments and
370 return None. Using a tuple instead of a string causes the method to
371 perform some action (see MockHandler.handle()), eg:
372
373 [["http_error"], [("http_open", "return request")]]
374
375 defines .http_error() on one handler (which simply returns None), and
376 .http_open() on another handler, which returns a Request object.
377
378 """
379 handlers = []
380 count = 0
381 for meths in meth_spec:
382 class MockHandlerSubclass(MockHandler): pass
383 h = MockHandlerSubclass(meths)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000384 h.handler_order += count
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000385 h.add_parent(opener)
386 count = count + 1
387 handlers.append(h)
388 opener.add_handler(h)
389 return handlers
390
Thomas Wouters477c8d52006-05-27 19:21:47 +0000391def build_test_opener(*handler_instances):
392 opener = OpenerDirector()
393 for h in handler_instances:
394 opener.add_handler(h)
395 return opener
396
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000397class MockHTTPHandler(urllib.request.BaseHandler):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000398 # useful for testing redirections and auth
399 # sends supplied headers and code as first response
400 # sends 200 OK as second response
401 def __init__(self, code, headers):
402 self.code = code
403 self.headers = headers
404 self.reset()
405 def reset(self):
406 self._count = 0
407 self.requests = []
408 def http_open(self, req):
Barry Warsaw820c1202008-06-12 04:06:45 +0000409 import email, http.client, copy
Guido van Rossum34d19282007-08-09 01:03:29 +0000410 from io import StringIO
Thomas Wouters477c8d52006-05-27 19:21:47 +0000411 self.requests.append(copy.deepcopy(req))
412 if self._count == 0:
413 self._count = self._count + 1
Georg Brandl24420152008-05-26 16:32:26 +0000414 name = http.client.responses[self.code]
Barry Warsaw820c1202008-06-12 04:06:45 +0000415 msg = email.message_from_string(self.headers)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000416 return self.parent.error(
417 "http", req, MockFile(), self.code, name, msg)
418 else:
419 self.req = req
Barry Warsaw820c1202008-06-12 04:06:45 +0000420 msg = email.message_from_string("\r\n\r\n")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000421 return MockResponse(200, "OK", msg, "", req.get_full_url())
422
Senthil Kumaran47fff872009-12-20 07:10:31 +0000423class MockHTTPSHandler(urllib.request.AbstractHTTPHandler):
424 # Useful for testing the Proxy-Authorization request by verifying the
425 # properties of httpcon
Benjamin Peterson3d5b8db2009-12-24 01:14:05 +0000426
427 def __init__(self):
428 urllib.request.AbstractHTTPHandler.__init__(self)
429 self.httpconn = MockHTTPClass()
430
Senthil Kumaran47fff872009-12-20 07:10:31 +0000431 def https_open(self, req):
432 return self.do_open(self.httpconn, req)
433
Thomas Wouters477c8d52006-05-27 19:21:47 +0000434class MockPasswordManager:
435 def add_password(self, realm, uri, user, password):
436 self.realm = realm
437 self.url = uri
438 self.user = user
439 self.password = password
440 def find_user_password(self, realm, authuri):
441 self.target_realm = realm
442 self.target_url = authuri
443 return self.user, self.password
444
445
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000446class OpenerDirectorTests(unittest.TestCase):
447
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000448 def test_add_non_handler(self):
449 class NonHandler(object):
450 pass
451 self.assertRaises(TypeError,
452 OpenerDirector().add_handler, NonHandler())
453
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000454 def test_badly_named_methods(self):
455 # test work-around for three methods that accidentally follow the
456 # naming conventions for handler methods
457 # (*_open() / *_request() / *_response())
458
459 # These used to call the accidentally-named methods, causing a
460 # TypeError in real code; here, returning self from these mock
461 # methods would either cause no exception, or AttributeError.
462
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000463 from urllib.error import URLError
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000464
465 o = OpenerDirector()
466 meth_spec = [
467 [("do_open", "return self"), ("proxy_open", "return self")],
468 [("redirect_request", "return self")],
469 ]
470 handlers = add_ordered_mock_handlers(o, meth_spec)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000471 o.add_handler(urllib.request.UnknownHandler())
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000472 for scheme in "do", "proxy", "redirect":
473 self.assertRaises(URLError, o.open, scheme+"://example.com/")
474
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000475 def test_handled(self):
476 # handler returning non-None means no more handlers will be called
477 o = OpenerDirector()
478 meth_spec = [
479 ["http_open", "ftp_open", "http_error_302"],
480 ["ftp_open"],
481 [("http_open", "return self")],
482 [("http_open", "return self")],
483 ]
484 handlers = add_ordered_mock_handlers(o, meth_spec)
485
486 req = Request("http://example.com/")
487 r = o.open(req)
488 # Second .http_open() gets called, third doesn't, since second returned
489 # non-None. Handlers without .http_open() never get any methods called
490 # on them.
491 # In fact, second mock handler defining .http_open() returns self
492 # (instead of response), which becomes the OpenerDirector's return
493 # value.
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000494 self.assertEqual(r, handlers[2])
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000495 calls = [(handlers[0], "http_open"), (handlers[2], "http_open")]
496 for expected, got in zip(calls, o.calls):
497 handler, name, args, kwds = got
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000498 self.assertEqual((handler, name), expected)
499 self.assertEqual(args, (req,))
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000500
501 def test_handler_order(self):
502 o = OpenerDirector()
503 handlers = []
504 for meths, handler_order in [
505 ([("http_open", "return self")], 500),
506 (["http_open"], 0),
507 ]:
508 class MockHandlerSubclass(MockHandler): pass
509 h = MockHandlerSubclass(meths)
510 h.handler_order = handler_order
511 handlers.append(h)
512 o.add_handler(h)
513
514 r = o.open("http://example.com/")
515 # handlers called in reverse order, thanks to their sort order
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000516 self.assertEqual(o.calls[0][0], handlers[1])
517 self.assertEqual(o.calls[1][0], handlers[0])
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000518
519 def test_raise(self):
520 # raising URLError stops processing of request
521 o = OpenerDirector()
522 meth_spec = [
523 [("http_open", "raise")],
524 [("http_open", "return self")],
525 ]
526 handlers = add_ordered_mock_handlers(o, meth_spec)
527
528 req = Request("http://example.com/")
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000529 self.assertRaises(urllib.error.URLError, o.open, req)
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000530 self.assertEqual(o.calls, [(handlers[0], "http_open", (req,), {})])
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000531
532## def test_error(self):
533## # XXX this doesn't actually seem to be used in standard library,
534## # but should really be tested anyway...
535
536 def test_http_error(self):
537 # XXX http_error_default
538 # http errors are a special case
539 o = OpenerDirector()
540 meth_spec = [
541 [("http_open", "error 302")],
542 [("http_error_400", "raise"), "http_open"],
543 [("http_error_302", "return response"), "http_error_303",
544 "http_error"],
545 [("http_error_302")],
546 ]
547 handlers = add_ordered_mock_handlers(o, meth_spec)
548
549 class Unknown:
550 def __eq__(self, other): return True
551
552 req = Request("http://example.com/")
553 r = o.open(req)
554 assert len(o.calls) == 2
555 calls = [(handlers[0], "http_open", (req,)),
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000556 (handlers[2], "http_error_302",
557 (req, Unknown(), 302, "", {}))]
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000558 for expected, got in zip(calls, o.calls):
559 handler, method_name, args = expected
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000560 self.assertEqual((handler, method_name), got[:2])
561 self.assertEqual(args, got[2])
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000562
563 def test_processors(self):
564 # *_request / *_response methods get called appropriately
565 o = OpenerDirector()
566 meth_spec = [
567 [("http_request", "return request"),
568 ("http_response", "return response")],
569 [("http_request", "return request"),
570 ("http_response", "return response")],
571 ]
572 handlers = add_ordered_mock_handlers(o, meth_spec)
573
574 req = Request("http://example.com/")
575 r = o.open(req)
576 # processor methods are called on *all* handlers that define them,
577 # not just the first handler that handles the request
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000578 calls = [
579 (handlers[0], "http_request"), (handlers[1], "http_request"),
580 (handlers[0], "http_response"), (handlers[1], "http_response")]
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000581
582 for i, (handler, name, args, kwds) in enumerate(o.calls):
583 if i < 2:
584 # *_request
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000585 self.assertEqual((handler, name), calls[i])
586 self.assertEqual(len(args), 1)
Ezio Melottie9615932010-01-24 19:26:24 +0000587 self.assertIsInstance(args[0], Request)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000588 else:
589 # *_response
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000590 self.assertEqual((handler, name), calls[i])
591 self.assertEqual(len(args), 2)
Ezio Melottie9615932010-01-24 19:26:24 +0000592 self.assertIsInstance(args[0], Request)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000593 # response from opener.open is None, because there's no
594 # handler that defines http_open to handle it
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000595 self.assertTrue(args[1] is None or
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000596 isinstance(args[1], MockResponse))
597
598
Tim Peters58eb11c2004-01-18 20:29:55 +0000599def sanepathname2url(path):
Victor Stinner6c6f8512010-08-07 10:09:35 +0000600 try:
601 path.encode("utf8")
602 except UnicodeEncodeError:
603 raise unittest.SkipTest("path is not encodable to utf8")
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000604 urlpath = urllib.request.pathname2url(path)
Tim Peters58eb11c2004-01-18 20:29:55 +0000605 if os.name == "nt" and urlpath.startswith("///"):
606 urlpath = urlpath[2:]
607 # XXX don't ask me about the mac...
608 return urlpath
609
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000610class HandlerTests(unittest.TestCase):
611
612 def test_ftp(self):
613 class MockFTPWrapper:
614 def __init__(self, data): self.data = data
615 def retrfile(self, filename, filetype):
616 self.filename, self.filetype = filename, filetype
Guido van Rossum34d19282007-08-09 01:03:29 +0000617 return io.StringIO(self.data), len(self.data)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000618
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000619 class NullFTPHandler(urllib.request.FTPHandler):
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000620 def __init__(self, data): self.data = data
Georg Brandlf78e02b2008-06-10 17:40:04 +0000621 def connect_ftp(self, user, passwd, host, port, dirs,
622 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000623 self.user, self.passwd = user, passwd
624 self.host, self.port = host, port
625 self.dirs = dirs
626 self.ftpwrapper = MockFTPWrapper(self.data)
627 return self.ftpwrapper
628
Georg Brandlf78e02b2008-06-10 17:40:04 +0000629 import ftplib
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000630 data = "rheum rhaponicum"
631 h = NullFTPHandler(data)
632 o = h.parent = MockOpener()
633
Senthil Kumarandaa29d02010-11-18 15:36:41 +0000634 for url, host, port, user, passwd, type_, dirs, filename, mimetype in [
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000635 ("ftp://localhost/foo/bar/baz.html",
Senthil Kumarandaa29d02010-11-18 15:36:41 +0000636 "localhost", ftplib.FTP_PORT, "", "", "I",
637 ["foo", "bar"], "baz.html", "text/html"),
638 ("ftp://parrot@localhost/foo/bar/baz.html",
639 "localhost", ftplib.FTP_PORT, "parrot", "", "I",
640 ["foo", "bar"], "baz.html", "text/html"),
641 ("ftp://%25parrot@localhost/foo/bar/baz.html",
642 "localhost", ftplib.FTP_PORT, "%parrot", "", "I",
643 ["foo", "bar"], "baz.html", "text/html"),
644 ("ftp://%2542parrot@localhost/foo/bar/baz.html",
645 "localhost", ftplib.FTP_PORT, "%42parrot", "", "I",
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000646 ["foo", "bar"], "baz.html", "text/html"),
Kurt B. Kaiser3f7cb5d2004-07-11 17:14:13 +0000647 ("ftp://localhost:80/foo/bar/",
Senthil Kumarandaa29d02010-11-18 15:36:41 +0000648 "localhost", 80, "", "", "D",
Kurt B. Kaiser3f7cb5d2004-07-11 17:14:13 +0000649 ["foo", "bar"], "", None),
650 ("ftp://localhost/baz.gif;type=a",
Senthil Kumarandaa29d02010-11-18 15:36:41 +0000651 "localhost", ftplib.FTP_PORT, "", "", "A",
Kurt B. Kaiser3f7cb5d2004-07-11 17:14:13 +0000652 [], "baz.gif", None), # XXX really this should guess image/gif
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000653 ]:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000654 req = Request(url)
655 req.timeout = None
656 r = h.ftp_open(req)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000657 # ftp authentication not yet implemented by FTPHandler
Senthil Kumarandaa29d02010-11-18 15:36:41 +0000658 self.assertEqual(h.user, user)
659 self.assertEqual(h.passwd, passwd)
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000660 self.assertEqual(h.host, socket.gethostbyname(host))
661 self.assertEqual(h.port, port)
662 self.assertEqual(h.dirs, dirs)
663 self.assertEqual(h.ftpwrapper.filename, filename)
664 self.assertEqual(h.ftpwrapper.filetype, type_)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000665 headers = r.info()
Kurt B. Kaiser3f7cb5d2004-07-11 17:14:13 +0000666 self.assertEqual(headers.get("Content-type"), mimetype)
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000667 self.assertEqual(int(headers["Content-length"]), len(data))
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000668
669 def test_file(self):
Benjamin Petersona0c0a4a2008-06-12 22:15:50 +0000670 import email.utils, socket
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000671 h = urllib.request.FileHandler()
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000672 o = h.parent = MockOpener()
673
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000674 TESTFN = support.TESTFN
Tim Peters58eb11c2004-01-18 20:29:55 +0000675 urlpath = sanepathname2url(os.path.abspath(TESTFN))
Guido van Rossum6a2ccd02007-07-16 20:51:57 +0000676 towrite = b"hello, world\n"
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000677 urls = [
Tim Peters58eb11c2004-01-18 20:29:55 +0000678 "file://localhost%s" % urlpath,
679 "file://%s" % urlpath,
680 "file://%s%s" % (socket.gethostbyname('localhost'), urlpath),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000681 ]
682 try:
683 localaddr = socket.gethostbyname(socket.gethostname())
684 except socket.gaierror:
685 localaddr = ''
686 if localaddr:
687 urls.append("file://%s%s" % (localaddr, urlpath))
688
689 for url in urls:
Tim Peters58eb11c2004-01-18 20:29:55 +0000690 f = open(TESTFN, "wb")
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000691 try:
692 try:
693 f.write(towrite)
694 finally:
695 f.close()
696
697 r = h.file_open(Request(url))
698 try:
699 data = r.read()
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000700 headers = r.info()
Senthil Kumaran4fbed102010-05-08 03:29:09 +0000701 respurl = r.geturl()
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000702 finally:
703 r.close()
Tim Peters58eb11c2004-01-18 20:29:55 +0000704 stats = os.stat(TESTFN)
Benjamin Petersona0c0a4a2008-06-12 22:15:50 +0000705 modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000706 finally:
707 os.remove(TESTFN)
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000708 self.assertEqual(data, towrite)
709 self.assertEqual(headers["Content-type"], "text/plain")
710 self.assertEqual(headers["Content-length"], "13")
Tim Peters58eb11c2004-01-18 20:29:55 +0000711 self.assertEqual(headers["Last-modified"], modified)
Senthil Kumaran4fbed102010-05-08 03:29:09 +0000712 self.assertEqual(respurl, url)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000713
714 for url in [
Tim Peters58eb11c2004-01-18 20:29:55 +0000715 "file://localhost:80%s" % urlpath,
Guido van Rossumd8faa362007-04-27 19:54:29 +0000716 "file:///file_does_not_exist.txt",
717 "file://%s:80%s/%s" % (socket.gethostbyname('localhost'),
718 os.getcwd(), TESTFN),
719 "file://somerandomhost.ontheinternet.com%s/%s" %
720 (os.getcwd(), TESTFN),
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000721 ]:
722 try:
Tim Peters58eb11c2004-01-18 20:29:55 +0000723 f = open(TESTFN, "wb")
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000724 try:
725 f.write(towrite)
726 finally:
727 f.close()
728
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000729 self.assertRaises(urllib.error.URLError,
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000730 h.file_open, Request(url))
731 finally:
732 os.remove(TESTFN)
733
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000734 h = urllib.request.FileHandler()
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000735 o = h.parent = MockOpener()
736 # XXXX why does // mean ftp (and /// mean not ftp!), and where
737 # is file: scheme specified? I think this is really a bug, and
738 # what was intended was to distinguish between URLs like:
739 # file:/blah.txt (a file)
740 # file://localhost/blah.txt (a file)
741 # file:///blah.txt (a file)
742 # file://ftp.example.com/blah.txt (an ftp URL)
743 for url, ftp in [
Senthil Kumaran383c32d2010-10-14 11:57:35 +0000744 ("file://ftp.example.com//foo.txt", False),
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000745 ("file://ftp.example.com///foo.txt", False),
746# XXXX bug: fails with OSError, should be URLError
747 ("file://ftp.example.com/foo.txt", False),
Senthil Kumaran383c32d2010-10-14 11:57:35 +0000748 ("file://somehost//foo/something.txt", False),
Senthil Kumaran2ef16322010-07-11 03:12:43 +0000749 ("file://localhost//foo/something.txt", False),
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000750 ]:
751 req = Request(url)
752 try:
753 h.file_open(req)
754 # XXXX remove OSError when bug fixed
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000755 except (urllib.error.URLError, OSError):
Florent Xicluna419e3842010-08-08 16:16:07 +0000756 self.assertFalse(ftp)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000757 else:
Florent Xicluna419e3842010-08-08 16:16:07 +0000758 self.assertIs(o.req, req)
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000759 self.assertEqual(req.type, "ftp")
Senthil Kumaran2ef16322010-07-11 03:12:43 +0000760 self.assertEqual(req.type is "ftp", ftp)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000761
762 def test_http(self):
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000763
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000764 h = urllib.request.AbstractHTTPHandler()
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000765 o = h.parent = MockOpener()
766
767 url = "http://example.com/"
768 for method, data in [("GET", None), ("POST", "blah")]:
769 req = Request(url, data, {"Foo": "bar"})
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000770 req.timeout = None
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000771 req.add_unredirected_header("Spam", "eggs")
772 http = MockHTTPClass()
773 r = h.do_open(http, req)
774
775 # result attributes
776 r.read; r.readline # wrapped MockFile methods
777 r.info; r.geturl # addinfourl methods
778 r.code, r.msg == 200, "OK" # added from MockHTTPClass.getreply()
779 hdrs = r.info()
Guido van Rossume2b70bc2006-08-18 22:13:04 +0000780 hdrs.get; hdrs.__contains__ # r.info() gives dict from .getreply()
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000781 self.assertEqual(r.geturl(), url)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000782
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000783 self.assertEqual(http.host, "example.com")
784 self.assertEqual(http.level, 0)
785 self.assertEqual(http.method, method)
786 self.assertEqual(http.selector, "/")
787 self.assertEqual(http.req_headers,
Jeremy Hyltonb3ee6f92004-02-24 19:40:35 +0000788 [("Connection", "close"),
789 ("Foo", "bar"), ("Spam", "eggs")])
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000790 self.assertEqual(http.data, data)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000791
792 # check socket.error converted to URLError
793 http.raise_on_endheaders = True
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000794 self.assertRaises(urllib.error.URLError, h.do_open, http, req)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000795
796 # check adding of standard headers
797 o.addheaders = [("Spam", "eggs")]
798 for data in "", None: # POST, GET
799 req = Request("http://example.com/", data)
800 r = MockResponse(200, "OK", {}, "")
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000801 newreq = h.do_request_(req)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000802 if data is None: # GET
Benjamin Peterson577473f2010-01-19 00:09:57 +0000803 self.assertNotIn("Content-length", req.unredirected_hdrs)
804 self.assertNotIn("Content-type", req.unredirected_hdrs)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000805 else: # POST
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000806 self.assertEqual(req.unredirected_hdrs["Content-length"], "0")
807 self.assertEqual(req.unredirected_hdrs["Content-type"],
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000808 "application/x-www-form-urlencoded")
809 # XXX the details of Host could be better tested
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000810 self.assertEqual(req.unredirected_hdrs["Host"], "example.com")
811 self.assertEqual(req.unredirected_hdrs["Spam"], "eggs")
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000812
813 # don't clobber existing headers
814 req.add_unredirected_header("Content-length", "foo")
815 req.add_unredirected_header("Content-type", "bar")
816 req.add_unredirected_header("Host", "baz")
817 req.add_unredirected_header("Spam", "foo")
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000818 newreq = h.do_request_(req)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000819 self.assertEqual(req.unredirected_hdrs["Content-length"], "foo")
820 self.assertEqual(req.unredirected_hdrs["Content-type"], "bar")
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000821 self.assertEqual(req.unredirected_hdrs["Host"], "baz")
822 self.assertEqual(req.unredirected_hdrs["Spam"], "foo")
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000823
Facundo Batista72dc1ea2008-08-16 14:44:32 +0000824 def test_http_doubleslash(self):
825 # Checks the presence of any unnecessary double slash in url does not
826 # break anything. Previously, a double slash directly after the host
827 # could could cause incorrect parsing.
828 h = urllib.request.AbstractHTTPHandler()
829 o = h.parent = MockOpener()
830
831 data = ""
832 ds_urls = [
833 "http://example.com/foo/bar/baz.html",
834 "http://example.com//foo/bar/baz.html",
835 "http://example.com/foo//bar/baz.html",
836 "http://example.com/foo/bar//baz.html"
837 ]
838
839 for ds_url in ds_urls:
840 ds_req = Request(ds_url, data)
841
842 # Check whether host is determined correctly if there is no proxy
843 np_ds_req = h.do_request_(ds_req)
844 self.assertEqual(np_ds_req.unredirected_hdrs["Host"],"example.com")
845
846 # Check whether host is determined correctly if there is a proxy
847 ds_req.set_proxy("someproxy:3128",None)
848 p_ds_req = h.do_request_(ds_req)
849 self.assertEqual(p_ds_req.unredirected_hdrs["Host"],"example.com")
850
Senthil Kumaranc2958622010-11-22 04:48:26 +0000851 def test_fixpath_in_weirdurls(self):
852 # Issue4493: urllib2 to supply '/' when to urls where path does not
853 # start with'/'
854
855 h = urllib.request.AbstractHTTPHandler()
856 o = h.parent = MockOpener()
857
858 weird_url = 'http://www.python.org?getspam'
859 req = Request(weird_url)
860 newreq = h.do_request_(req)
861 self.assertEqual(newreq.host,'www.python.org')
862 self.assertEqual(newreq.selector,'/?getspam')
863
864 url_without_path = 'http://www.python.org'
865 req = Request(url_without_path)
866 newreq = h.do_request_(req)
867 self.assertEqual(newreq.host,'www.python.org')
868 self.assertEqual(newreq.selector,'')
869
Facundo Batista72dc1ea2008-08-16 14:44:32 +0000870
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000871 def test_errors(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000872 h = urllib.request.HTTPErrorProcessor()
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000873 o = h.parent = MockOpener()
874
875 url = "http://example.com/"
876 req = Request(url)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000877 # all 2xx are passed through
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000878 r = MockResponse(200, "OK", {}, "", url)
879 newr = h.http_response(req, r)
Florent Xicluna419e3842010-08-08 16:16:07 +0000880 self.assertIs(r, newr)
881 self.assertFalse(hasattr(o, "proto")) # o.error not called
Guido van Rossumd8faa362007-04-27 19:54:29 +0000882 r = MockResponse(202, "Accepted", {}, "", url)
883 newr = h.http_response(req, r)
Florent Xicluna419e3842010-08-08 16:16:07 +0000884 self.assertIs(r, newr)
885 self.assertFalse(hasattr(o, "proto")) # o.error not called
Guido van Rossumd8faa362007-04-27 19:54:29 +0000886 r = MockResponse(206, "Partial content", {}, "", url)
887 newr = h.http_response(req, r)
Florent Xicluna419e3842010-08-08 16:16:07 +0000888 self.assertIs(r, newr)
889 self.assertFalse(hasattr(o, "proto")) # o.error not called
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000890 # anything else calls o.error (and MockOpener returns None, here)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000891 r = MockResponse(502, "Bad gateway", {}, "", url)
Florent Xicluna419e3842010-08-08 16:16:07 +0000892 self.assertIsNone(h.http_response(req, r))
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000893 self.assertEqual(o.proto, "http") # o.error called
Guido van Rossumd8faa362007-04-27 19:54:29 +0000894 self.assertEqual(o.args, (req, r, 502, "Bad gateway", {}))
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000895
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000896 def test_cookies(self):
897 cj = MockCookieJar()
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000898 h = urllib.request.HTTPCookieProcessor(cj)
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000899 o = h.parent = MockOpener()
900
901 req = Request("http://example.com/")
902 r = MockResponse(200, "OK", {}, "")
903 newreq = h.http_request(req)
Florent Xicluna419e3842010-08-08 16:16:07 +0000904 self.assertIs(cj.ach_req, req)
905 self.assertIs(cj.ach_req, newreq)
906 self.assertEqual(req.get_origin_req_host(), "example.com")
907 self.assertFalse(req.is_unverifiable())
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000908 newr = h.http_response(req, r)
Florent Xicluna419e3842010-08-08 16:16:07 +0000909 self.assertIs(cj.ec_req, req)
910 self.assertIs(cj.ec_r, r)
911 self.assertIs(r, newr)
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000912
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000913 def test_redirect(self):
914 from_url = "http://example.com/a.html"
915 to_url = "http://example.com/b.html"
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000916 h = urllib.request.HTTPRedirectHandler()
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000917 o = h.parent = MockOpener()
918
919 # ordinary redirect behaviour
920 for code in 301, 302, 303, 307:
921 for data in None, "blah\nblah\n":
922 method = getattr(h, "http_error_%s" % code)
923 req = Request(from_url, data)
Senthil Kumaranfb8cc2f2009-07-19 02:44:19 +0000924 req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000925 req.add_header("Nonsense", "viking=withhold")
Christian Heimes77c02eb2008-02-09 02:18:51 +0000926 if data is not None:
927 req.add_header("Content-Length", str(len(data)))
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000928 req.add_unredirected_header("Spam", "spam")
929 try:
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000930 method(req, MockFile(), code, "Blah",
931 MockHeaders({"location": to_url}))
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000932 except urllib.error.HTTPError:
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000933 # 307 in response to POST requires user OK
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000934 self.assertTrue(code == 307 and data is not None)
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000935 self.assertEqual(o.req.get_full_url(), to_url)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000936 try:
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000937 self.assertEqual(o.req.get_method(), "GET")
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000938 except AttributeError:
Florent Xicluna419e3842010-08-08 16:16:07 +0000939 self.assertFalse(o.req.has_data())
Christian Heimes77c02eb2008-02-09 02:18:51 +0000940
941 # now it's a GET, there should not be headers regarding content
942 # (possibly dragged from before being a POST)
943 headers = [x.lower() for x in o.req.headers]
Benjamin Peterson577473f2010-01-19 00:09:57 +0000944 self.assertNotIn("content-length", headers)
945 self.assertNotIn("content-type", headers)
Christian Heimes77c02eb2008-02-09 02:18:51 +0000946
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000947 self.assertEqual(o.req.headers["Nonsense"],
948 "viking=withhold")
Benjamin Peterson577473f2010-01-19 00:09:57 +0000949 self.assertNotIn("Spam", o.req.headers)
950 self.assertNotIn("Spam", o.req.unredirected_hdrs)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000951
952 # loop detection
953 req = Request(from_url)
Senthil Kumaranfb8cc2f2009-07-19 02:44:19 +0000954 req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000955 def redirect(h, req, url=to_url):
956 h.http_error_302(req, MockFile(), 302, "Blah",
957 MockHeaders({"location": url}))
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000958 # Note that the *original* request shares the same record of
959 # redirections with the sub-requests caused by the redirections.
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000960
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000961 # detect infinite loop redirect of a URL to itself
962 req = Request(from_url, origin_req_host="example.com")
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000963 count = 0
Senthil Kumaranfb8cc2f2009-07-19 02:44:19 +0000964 req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000965 try:
966 while 1:
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000967 redirect(h, req, "http://example.com/")
968 count = count + 1
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000969 except urllib.error.HTTPError:
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000970 # don't stop until max_repeats, because cookies may introduce state
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000971 self.assertEqual(count, urllib.request.HTTPRedirectHandler.max_repeats)
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000972
973 # detect endless non-repeating chain of redirects
974 req = Request(from_url, origin_req_host="example.com")
975 count = 0
Senthil Kumaranfb8cc2f2009-07-19 02:44:19 +0000976 req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000977 try:
978 while 1:
979 redirect(h, req, "http://example.com/%d" % count)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000980 count = count + 1
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000981 except urllib.error.HTTPError:
Jeremy Hyltondf38ea92003-12-17 20:42:38 +0000982 self.assertEqual(count,
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000983 urllib.request.HTTPRedirectHandler.max_redirections)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +0000984
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000985 def test_cookie_redirect(self):
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000986 # cookies shouldn't leak into redirected requests
Georg Brandl24420152008-05-26 16:32:26 +0000987 from http.cookiejar import CookieJar
988 from test.test_http_cookiejar import interact_netscape
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000989
990 cj = CookieJar()
991 interact_netscape(cj, "http://www.example.com/", "spam=eggs")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000992 hh = MockHTTPHandler(302, "Location: http://www.cracker.com/\r\n\r\n")
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000993 hdeh = urllib.request.HTTPDefaultErrorHandler()
994 hrh = urllib.request.HTTPRedirectHandler()
995 cp = urllib.request.HTTPCookieProcessor(cj)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000996 o = build_test_opener(hh, hdeh, hrh, cp)
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000997 o.open("http://www.example.com/")
Florent Xicluna419e3842010-08-08 16:16:07 +0000998 self.assertFalse(hh.req.has_header("Cookie"))
Martin v. Löwis2a6ba902004-05-31 18:22:40 +0000999
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001000 def test_proxy(self):
1001 o = OpenerDirector()
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001002 ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001003 o.add_handler(ph)
1004 meth_spec = [
1005 [("http_open", "return response")]
1006 ]
1007 handlers = add_ordered_mock_handlers(o, meth_spec)
1008
1009 req = Request("http://acme.example.com/")
1010 self.assertEqual(req.get_host(), "acme.example.com")
1011 r = o.open(req)
1012 self.assertEqual(req.get_host(), "proxy.example.com:3128")
1013
1014 self.assertEqual([(handlers[0], "http_open")],
1015 [tup[0:2] for tup in o.calls])
1016
Senthil Kumaran7bb04972009-10-11 04:58:55 +00001017 def test_proxy_no_proxy(self):
1018 os.environ['no_proxy'] = 'python.org'
1019 o = OpenerDirector()
1020 ph = urllib.request.ProxyHandler(dict(http="proxy.example.com"))
1021 o.add_handler(ph)
1022 req = Request("http://www.perl.org/")
1023 self.assertEqual(req.get_host(), "www.perl.org")
1024 r = o.open(req)
1025 self.assertEqual(req.get_host(), "proxy.example.com")
1026 req = Request("http://www.python.org")
1027 self.assertEqual(req.get_host(), "www.python.org")
1028 r = o.open(req)
1029 self.assertEqual(req.get_host(), "www.python.org")
1030 del os.environ['no_proxy']
1031
1032
Senthil Kumaran97f0c6b2009-07-25 04:24:38 +00001033 def test_proxy_https(self):
1034 o = OpenerDirector()
1035 ph = urllib.request.ProxyHandler(dict(https="proxy.example.com:3128"))
1036 o.add_handler(ph)
1037 meth_spec = [
1038 [("https_open", "return response")]
1039 ]
1040 handlers = add_ordered_mock_handlers(o, meth_spec)
1041
1042 req = Request("https://www.example.com/")
1043 self.assertEqual(req.get_host(), "www.example.com")
1044 r = o.open(req)
1045 self.assertEqual(req.get_host(), "proxy.example.com:3128")
1046 self.assertEqual([(handlers[0], "https_open")],
1047 [tup[0:2] for tup in o.calls])
1048
Senthil Kumaran47fff872009-12-20 07:10:31 +00001049 def test_proxy_https_proxy_authorization(self):
1050 o = OpenerDirector()
1051 ph = urllib.request.ProxyHandler(dict(https='proxy.example.com:3128'))
1052 o.add_handler(ph)
1053 https_handler = MockHTTPSHandler()
1054 o.add_handler(https_handler)
1055 req = Request("https://www.example.com/")
1056 req.add_header("Proxy-Authorization","FooBar")
1057 req.add_header("User-Agent","Grail")
1058 self.assertEqual(req.get_host(), "www.example.com")
1059 self.assertIsNone(req._tunnel_host)
1060 r = o.open(req)
1061 # Verify Proxy-Authorization gets tunneled to request.
1062 # httpsconn req_headers do not have the Proxy-Authorization header but
1063 # the req will have.
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001064 self.assertNotIn(("Proxy-Authorization","FooBar"),
Senthil Kumaran47fff872009-12-20 07:10:31 +00001065 https_handler.httpconn.req_headers)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001066 self.assertIn(("User-Agent","Grail"),
1067 https_handler.httpconn.req_headers)
Senthil Kumaran47fff872009-12-20 07:10:31 +00001068 self.assertIsNotNone(req._tunnel_host)
1069 self.assertEqual(req.get_host(), "proxy.example.com:3128")
1070 self.assertEqual(req.get_header("Proxy-authorization"),"FooBar")
Senthil Kumaran97f0c6b2009-07-25 04:24:38 +00001071
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001072 def test_basic_auth(self, quote_char='"'):
Thomas Wouters477c8d52006-05-27 19:21:47 +00001073 opener = OpenerDirector()
1074 password_manager = MockPasswordManager()
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001075 auth_handler = urllib.request.HTTPBasicAuthHandler(password_manager)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001076 realm = "ACME Widget Store"
1077 http_handler = MockHTTPHandler(
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001078 401, 'WWW-Authenticate: Basic realm=%s%s%s\r\n\r\n' %
1079 (quote_char, realm, quote_char) )
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001080 opener.add_handler(auth_handler)
1081 opener.add_handler(http_handler)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001082 self._test_basic_auth(opener, auth_handler, "Authorization",
1083 realm, http_handler, password_manager,
1084 "http://acme.example.com/protected",
1085 "http://acme.example.com/protected",
1086 )
1087
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001088 def test_basic_auth_with_single_quoted_realm(self):
1089 self.test_basic_auth(quote_char="'")
1090
Thomas Wouters477c8d52006-05-27 19:21:47 +00001091 def test_proxy_basic_auth(self):
1092 opener = OpenerDirector()
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001093 ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128"))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001094 opener.add_handler(ph)
1095 password_manager = MockPasswordManager()
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001096 auth_handler = urllib.request.ProxyBasicAuthHandler(password_manager)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001097 realm = "ACME Networks"
1098 http_handler = MockHTTPHandler(
1099 407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001100 opener.add_handler(auth_handler)
1101 opener.add_handler(http_handler)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001102 self._test_basic_auth(opener, auth_handler, "Proxy-authorization",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001103 realm, http_handler, password_manager,
1104 "http://acme.example.com:3128/protected",
1105 "proxy.example.com:3128",
1106 )
1107
1108 def test_basic_and_digest_auth_handlers(self):
1109 # HTTPDigestAuthHandler threw an exception if it couldn't handle a 40*
1110 # response (http://python.org/sf/1479302), where it should instead
1111 # return None to allow another handler (especially
1112 # HTTPBasicAuthHandler) to handle the response.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001113
1114 # Also (http://python.org/sf/14797027, RFC 2617 section 1.2), we must
1115 # try digest first (since it's the strongest auth scheme), so we record
1116 # order of calls here to check digest comes first:
1117 class RecordingOpenerDirector(OpenerDirector):
1118 def __init__(self):
1119 OpenerDirector.__init__(self)
1120 self.recorded = []
1121 def record(self, info):
1122 self.recorded.append(info)
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001123 class TestDigestAuthHandler(urllib.request.HTTPDigestAuthHandler):
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001124 def http_error_401(self, *args, **kwds):
1125 self.parent.record("digest")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001126 urllib.request.HTTPDigestAuthHandler.http_error_401(self,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001127 *args, **kwds)
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001128 class TestBasicAuthHandler(urllib.request.HTTPBasicAuthHandler):
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001129 def http_error_401(self, *args, **kwds):
1130 self.parent.record("basic")
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001131 urllib.request.HTTPBasicAuthHandler.http_error_401(self,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001132 *args, **kwds)
1133
1134 opener = RecordingOpenerDirector()
Thomas Wouters477c8d52006-05-27 19:21:47 +00001135 password_manager = MockPasswordManager()
1136 digest_handler = TestDigestAuthHandler(password_manager)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001137 basic_handler = TestBasicAuthHandler(password_manager)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001138 realm = "ACME Networks"
1139 http_handler = MockHTTPHandler(
1140 401, 'WWW-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001141 opener.add_handler(basic_handler)
1142 opener.add_handler(digest_handler)
1143 opener.add_handler(http_handler)
1144
1145 # check basic auth isn't blocked by digest handler failing
Thomas Wouters477c8d52006-05-27 19:21:47 +00001146 self._test_basic_auth(opener, basic_handler, "Authorization",
1147 realm, http_handler, password_manager,
1148 "http://acme.example.com/protected",
1149 "http://acme.example.com/protected",
1150 )
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001151 # check digest was tried before basic (twice, because
1152 # _test_basic_auth called .open() twice)
1153 self.assertEqual(opener.recorded, ["digest", "basic"]*2)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001154
1155 def _test_basic_auth(self, opener, auth_handler, auth_header,
1156 realm, http_handler, password_manager,
1157 request_url, protected_url):
Christian Heimes05e8be12008-02-23 18:30:17 +00001158 import base64
Thomas Wouters477c8d52006-05-27 19:21:47 +00001159 user, password = "wile", "coyote"
Thomas Wouters477c8d52006-05-27 19:21:47 +00001160
1161 # .add_password() fed through to password manager
1162 auth_handler.add_password(realm, request_url, user, password)
1163 self.assertEqual(realm, password_manager.realm)
1164 self.assertEqual(request_url, password_manager.url)
1165 self.assertEqual(user, password_manager.user)
1166 self.assertEqual(password, password_manager.password)
1167
1168 r = opener.open(request_url)
1169
1170 # should have asked the password manager for the username/password
1171 self.assertEqual(password_manager.target_realm, realm)
1172 self.assertEqual(password_manager.target_url, protected_url)
1173
1174 # expect one request without authorization, then one with
1175 self.assertEqual(len(http_handler.requests), 2)
1176 self.assertFalse(http_handler.requests[0].has_header(auth_header))
Guido van Rossum98b349f2007-08-27 21:47:52 +00001177 userpass = bytes('%s:%s' % (user, password), "ascii")
Guido van Rossum98297ee2007-11-06 21:34:58 +00001178 auth_hdr_value = ('Basic ' +
Georg Brandl706824f2009-06-04 09:42:55 +00001179 base64.encodebytes(userpass).strip().decode())
Thomas Wouters477c8d52006-05-27 19:21:47 +00001180 self.assertEqual(http_handler.requests[1].get_header(auth_header),
1181 auth_hdr_value)
Senthil Kumaranca2fc9e2010-02-24 16:53:16 +00001182 self.assertEqual(http_handler.requests[1].unredirected_hdrs[auth_header],
1183 auth_hdr_value)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001184 # if the password manager can't find a password, the handler won't
1185 # handle the HTTP auth error
1186 password_manager.user = password_manager.password = None
1187 http_handler.reset()
1188 r = opener.open(request_url)
1189 self.assertEqual(len(http_handler.requests), 1)
1190 self.assertFalse(http_handler.requests[0].has_header(auth_header))
1191
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001192class MiscTests(unittest.TestCase):
1193
1194 def test_build_opener(self):
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001195 class MyHTTPHandler(urllib.request.HTTPHandler): pass
1196 class FooHandler(urllib.request.BaseHandler):
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001197 def foo_open(self): pass
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001198 class BarHandler(urllib.request.BaseHandler):
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001199 def bar_open(self): pass
1200
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001201 build_opener = urllib.request.build_opener
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001202
1203 o = build_opener(FooHandler, BarHandler)
1204 self.opener_has_handler(o, FooHandler)
1205 self.opener_has_handler(o, BarHandler)
1206
1207 # can take a mix of classes and instances
1208 o = build_opener(FooHandler, BarHandler())
1209 self.opener_has_handler(o, FooHandler)
1210 self.opener_has_handler(o, BarHandler)
1211
1212 # subclasses of default handlers override default handlers
1213 o = build_opener(MyHTTPHandler)
1214 self.opener_has_handler(o, MyHTTPHandler)
1215
1216 # a particular case of overriding: default handlers can be passed
1217 # in explicitly
1218 o = build_opener()
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001219 self.opener_has_handler(o, urllib.request.HTTPHandler)
1220 o = build_opener(urllib.request.HTTPHandler)
1221 self.opener_has_handler(o, urllib.request.HTTPHandler)
1222 o = build_opener(urllib.request.HTTPHandler())
1223 self.opener_has_handler(o, urllib.request.HTTPHandler)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001224
Christian Heimes81ee3ef2008-05-04 22:42:01 +00001225 # Issue2670: multiple handlers sharing the same base class
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001226 class MyOtherHTTPHandler(urllib.request.HTTPHandler): pass
Christian Heimes81ee3ef2008-05-04 22:42:01 +00001227 o = build_opener(MyHTTPHandler, MyOtherHTTPHandler)
1228 self.opener_has_handler(o, MyHTTPHandler)
1229 self.opener_has_handler(o, MyOtherHTTPHandler)
1230
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001231 def opener_has_handler(self, opener, handler_class):
Florent Xicluna419e3842010-08-08 16:16:07 +00001232 self.assertTrue(any(h.__class__ == handler_class
1233 for h in opener.handlers))
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001234
Benjamin Peterson6ebe78f2008-12-21 00:06:59 +00001235class RequestTests(unittest.TestCase):
1236
1237 def setUp(self):
1238 self.get = Request("http://www.python.org/~jeremy/")
1239 self.post = Request("http://www.python.org/~jeremy/",
1240 "data",
1241 headers={"X-Test": "test"})
1242
1243 def test_method(self):
1244 self.assertEqual("POST", self.post.get_method())
1245 self.assertEqual("GET", self.get.get_method())
1246
1247 def test_add_data(self):
Florent Xicluna419e3842010-08-08 16:16:07 +00001248 self.assertFalse(self.get.has_data())
Benjamin Peterson6ebe78f2008-12-21 00:06:59 +00001249 self.assertEqual("GET", self.get.get_method())
1250 self.get.add_data("spam")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001251 self.assertTrue(self.get.has_data())
Benjamin Peterson6ebe78f2008-12-21 00:06:59 +00001252 self.assertEqual("POST", self.get.get_method())
1253
1254 def test_get_full_url(self):
1255 self.assertEqual("http://www.python.org/~jeremy/",
1256 self.get.get_full_url())
1257
1258 def test_selector(self):
1259 self.assertEqual("/~jeremy/", self.get.get_selector())
1260 req = Request("http://www.python.org/")
1261 self.assertEqual("/", req.get_selector())
1262
1263 def test_get_type(self):
1264 self.assertEqual("http", self.get.get_type())
1265
1266 def test_get_host(self):
1267 self.assertEqual("www.python.org", self.get.get_host())
1268
1269 def test_get_host_unquote(self):
1270 req = Request("http://www.%70ython.org/")
1271 self.assertEqual("www.python.org", req.get_host())
1272
1273 def test_proxy(self):
Florent Xicluna419e3842010-08-08 16:16:07 +00001274 self.assertFalse(self.get.has_proxy())
Benjamin Peterson6ebe78f2008-12-21 00:06:59 +00001275 self.get.set_proxy("www.perl.org", "http")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001276 self.assertTrue(self.get.has_proxy())
Benjamin Peterson6ebe78f2008-12-21 00:06:59 +00001277 self.assertEqual("www.python.org", self.get.get_origin_req_host())
1278 self.assertEqual("www.perl.org", self.get.get_host())
1279
Senthil Kumarand95cc752010-08-08 11:27:53 +00001280 def test_wrapped_url(self):
1281 req = Request("<URL:http://www.python.org>")
1282 self.assertEqual("www.python.org", req.get_host())
1283
1284 def test_urlwith_fragment(self):
1285 req = Request("http://www.python.org/?qs=query#fragment=true")
1286 self.assertEqual("/?qs=query", req.get_selector())
1287 req = Request("http://www.python.org/#fun=true")
1288 self.assertEqual("/", req.get_selector())
1289
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001290
1291def test_main(verbose=None):
Thomas Wouters477c8d52006-05-27 19:21:47 +00001292 from test import test_urllib2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001293 support.run_doctest(test_urllib2, verbose)
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001294 support.run_doctest(urllib.request, verbose)
Andrew M. Kuchlingbd3200f2004-06-29 13:15:46 +00001295 tests = (TrivialTests,
1296 OpenerDirectorTests,
1297 HandlerTests,
Benjamin Peterson6ebe78f2008-12-21 00:06:59 +00001298 MiscTests,
1299 RequestTests)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001300 support.run_unittest(*tests)
Jeremy Hyltonc1be59f2003-12-14 05:27:34 +00001301
1302if __name__ == "__main__":
1303 test_main(verbose=True)