14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test import test_support 34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport os 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport socket 64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport StringIO 74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport urllib2 94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom urllib2 import Request, OpenerDirector 104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# XXX 124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Request 134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# CacheFTPHandler (hard to write) 144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# parse_keqv_list, parse_http_list, HTTPDigestAuthHandler 154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TrivialTests(unittest.TestCase): 174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_trivial(self): 184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # A couple trivial tests 194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, urllib2.urlopen, 'bogus url') 214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # XXX Name hacking to get this to work on Windows. 234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fname = os.path.abspath(urllib2.__file__).replace('\\', '/') 244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # And more hacking to get it to work on MacOS. This assumes 264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # urllib.pathname2url works, unfortunately... 274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if os.name == 'riscos': 284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import string 294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fname = os.expand(fname) 304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fname = fname.translate(string.maketrans("/.", "./")) 314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if os.name == 'nt': 334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao file_url = "file:///%s" % fname 344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao file_url = "file://%s" % fname 364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f = urllib2.urlopen(file_url) 384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao buf = f.read() 404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f.close() 414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_parse_http_list(self): 434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tests = [('a,b,c', ['a', 'b', 'c']), 444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('path"o,l"og"i"cal, example', ['path"o,l"og"i"cal', 'example']), 454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('a, b, "c", "d", "e,f", g, h', ['a', 'b', '"c"', '"d"', '"e,f"', 'g', 'h']), 464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('a="b\\"c", d="e\\,f", g="h\\\\i"', ['a="b"c"', 'd="e,f"', 'g="h\\i"'])] 474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for string, list in tests: 484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(urllib2.parse_http_list(string), list) 494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_request_headers_dict(): 524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao The Request.headers dictionary is not a documented interface. It should 544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao stay that way, because the complete set of headers are only accessible 554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao through the .get_header(), .has_header(), .header_items() interface. 564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao However, .headers pre-dates those methods, and so real code will be using 574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao the dictionary. 584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao The introduction in 2.4 of those methods was a mistake for the same reason: 604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao code that previously saw all (urllib2 user)-provided headers in .headers 614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao now sees only a subset (and the function interface is ugly and incomplete). 624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao A better change would have been to replace .headers dict with a dict 634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao subclass (or UserDict.DictMixin instance?) that preserved the .headers 644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao interface and also provided access to the "unredirected" headers. It's 654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao probably too late to fix that, though. 664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Check .capitalize() case normalization: 694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> url = "http://example.com" 714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> Request(url, headers={"Spam-eggs": "blah"}).headers["Spam-eggs"] 724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'blah' 734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> Request(url, headers={"spam-EggS": "blah"}).headers["Spam-eggs"] 744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'blah' 754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Currently, Request(url, "Spam-eggs").headers["Spam-Eggs"] raises KeyError, 774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao but that could be changed in future. 784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_request_headers_methods(): 824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Note the case normalization of header names here, to .capitalize()-case. 844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao This should be preserved for backwards-compatibility. (In the HTTP case, 854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao normalization to .title()-case is done by urllib2 before sending headers to 864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao httplib). 874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> url = "http://example.com" 894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> r = Request(url, headers={"Spam-eggs": "blah"}) 904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> r.has_header("Spam-eggs") 914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao True 924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> r.header_items() 934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [('Spam-eggs', 'blah')] 944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> r.add_header("Foo-Bar", "baz") 954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> items = r.header_items() 964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> items.sort() 974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> items 984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [('Foo-bar', 'baz'), ('Spam-eggs', 'blah')] 994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Note that e.g. r.has_header("spam-EggS") is currently False, and 1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r.get_header("spam-EggS") returns None, but that could be changed in 1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao future. 1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> r.has_header("Not-there") 1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao False 1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> print r.get_header("Not-there") 1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao None 1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> r.get_header("Not-there", "default") 1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'default' 1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_password_manager(self): 1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr = urllib2.HTTPPasswordMgr() 1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add = mgr.add_password 1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("Some Realm", "http://example.com/", "joe", "password") 1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("Some Realm", "http://example.com/ni", "ni", "ni") 1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("c", "http://example.com/foo", "foo", "ni") 1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("c", "http://example.com/bar", "bar", "nini") 1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("b", "http://example.com/", "first", "blah") 1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("b", "http://example.com/", "second", "spam") 1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("a", "http://example.com", "1", "a") 1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("Some Realm", "http://c.example.com:3128", "3", "c") 1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("Some Realm", "d.example.com", "4", "d") 1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("Some Realm", "e.example.com:3128", "5", "e") 1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "example.com") 1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('joe', 'password') 1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "http://example.com") 1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('joe', 'password') 1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "http://example.com/") 1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('joe', 'password') 1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "http://example.com/spam") 1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('joe', 'password') 1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "http://example.com/spam/spam") 1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('joe', 'password') 1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("c", "http://example.com/foo") 1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('foo', 'ni') 1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("c", "http://example.com/bar") 1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('bar', 'nini') 1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Actually, this is really undefined ATM 1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao## Currently, we use the highest-level path where more than one match: 1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao## >>> mgr.find_user_password("Some Realm", "http://example.com/ni") 1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao## ('joe', 'password') 1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Use latest add_password() in case of conflict: 1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("b", "http://example.com/") 1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('second', 'spam') 1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao No special relationship between a.example.com and example.com: 1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("a", "http://example.com/") 1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('1', 'a') 1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("a", "http://a.example.com/") 1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (None, None) 1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Ports: 1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "c.example.com") 1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (None, None) 1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "c.example.com:3128") 1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('3', 'c') 1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "http://c.example.com:3128") 1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('3', 'c') 1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "d.example.com") 1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('4', 'd') 1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("Some Realm", "e.example.com:3128") 1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('5', 'e') 1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_password_manager_default_port(self): 1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr = urllib2.HTTPPasswordMgr() 1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add = mgr.add_password 1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao The point to note here is that we can't guess the default port if there's 1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao no scheme. This applies to both add_password and find_user_password. 1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("f", "http://g.example.com:80", "10", "j") 1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("g", "http://h.example.com", "11", "k") 1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("h", "i.example.com:80", "12", "l") 1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> add("i", "j.example.com", "13", "m") 1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("f", "g.example.com:100") 1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (None, None) 1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("f", "g.example.com:80") 1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('10', 'j') 1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("f", "g.example.com") 1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (None, None) 1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("f", "http://g.example.com:100") 1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (None, None) 1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("f", "http://g.example.com:80") 2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('10', 'j') 2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("f", "http://g.example.com") 2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('10', 'j') 2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("g", "h.example.com") 2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('11', 'k') 2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("g", "h.example.com:80") 2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('11', 'k') 2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("g", "http://h.example.com:80") 2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('11', 'k') 2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("h", "i.example.com") 2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (None, None) 2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("h", "i.example.com:80") 2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('12', 'l') 2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("h", "http://i.example.com:80") 2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('12', 'l') 2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("i", "j.example.com") 2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('13', 'm') 2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("i", "j.example.com:80") 2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (None, None) 2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("i", "http://j.example.com") 2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ('13', 'm') 2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> mgr.find_user_password("i", "http://j.example.com:80") 2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (None, None) 2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockOpener: 2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao addheaders = [] 2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def open(self, req, data=None,timeout=socket._GLOBAL_DEFAULT_TIMEOUT): 2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.req, self.data, self.timeout = req, data, timeout 2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def error(self, proto, *args): 2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.proto, self.args = proto, args 2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockFile: 2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def read(self, count=None): pass 2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def readline(self, count=None): pass 2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def close(self): pass 2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockHeaders(dict): 2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def getheaders(self, name): 2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.values() 2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockResponse(StringIO.StringIO): 2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, code, msg, headers, data, url=None): 2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao StringIO.StringIO.__init__(self, data) 2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.code, self.msg, self.headers, self.url = code, msg, headers, url 2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def info(self): 2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.headers 2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def geturl(self): 2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.url 2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockCookieJar: 2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def add_cookie_header(self, request): 2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.ach_req = request 2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def extract_cookies(self, response, request): 2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.ec_req, self.ec_r = request, response 2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass FakeMethod: 2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, meth_name, action, handle): 2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.meth_name = meth_name 2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.handle = handle 2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.action = action 2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __call__(self, *args): 2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.handle(self.meth_name, self.action, *args) 2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockHTTPResponse: 2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, fp, msg, status, reason): 2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.fp = fp 2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.msg = msg 2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.status = status 2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.reason = reason 2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def read(self): 2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return '' 2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockHTTPClass: 2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self): 2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.req_headers = [] 2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.data = None 2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.raise_on_endheaders = False 2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tunnel_headers = {} 2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): 2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.host = host 2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.timeout = timeout 2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self 2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def set_debuglevel(self, level): 2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.level = level 2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def set_tunnel(self, host, port=None, headers=None): 2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tunnel_host = host 2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tunnel_port = port 2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if headers: 2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tunnel_headers = headers 2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tunnel_headers.clear() 2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def request(self, method, url, body=None, headers=None): 2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.method = method 2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.selector = url 3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if headers is not None: 3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.req_headers += headers.items() 3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.req_headers.sort() 3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if body: 3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.data = body 3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.raise_on_endheaders: 3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import socket 3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise socket.error() 3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def getresponse(self): 3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return MockHTTPResponse(MockFile(), {}, 200, "OK") 3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def close(self): 3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockHandler: 3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # useful for testing handler machinery 3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # see add_ordered_mock_handlers() docstring 3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handler_order = 500 3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, methods): 3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._define_methods(methods) 3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def _define_methods(self, methods): 3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for spec in methods: 3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if len(spec) == 2: name, action = spec 3244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: name, action = spec, None 3254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth = FakeMethod(name, action, self.handle) 3264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao setattr(self.__class__, name, meth) 3274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def handle(self, fn_name, action, *args, **kwds): 3284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.parent.calls.append((self, fn_name, args, kwds)) 3294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if action is None: 3304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 3314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif action == "return self": 3324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self 3334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif action == "return response": 3344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao res = MockResponse(200, "OK", {}, "") 3354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return res 3364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif action == "return request": 3374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return Request("http://blah/") 3384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif action.startswith("error"): 3394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao code = action[action.rfind(" ")+1:] 3404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 3414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao code = int(code) 3424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except ValueError: 3434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 3444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao res = MockResponse(200, "OK", {}, "") 3454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.parent.error("http", args[0], res, code, "", {}) 3464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif action == "raise": 3474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise urllib2.URLError("blah") 3484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert False 3494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def close(self): pass 3504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def add_parent(self, parent): 3514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.parent = parent 3524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.parent.calls = [] 3534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __lt__(self, other): 3544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not hasattr(other, "handler_order"): 3554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # No handler_order, leave in original order. Yuck. 3564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return True 3574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.handler_order < other.handler_order 3584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef add_ordered_mock_handlers(opener, meth_spec): 3604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Create MockHandlers and add them to an OpenerDirector. 3614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth_spec: list of lists of tuples and strings defining methods to define 3634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao on handlers. eg: 3644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [["http_error", "ftp_open"], ["http_open"]] 3664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao defines methods .http_error() and .ftp_open() on one handler, and 3684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao .http_open() on another. These methods just record their arguments and 3694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None. Using a tuple instead of a string causes the method to 3704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao perform some action (see MockHandler.handle()), eg: 3714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [["http_error"], [("http_open", "return request")]] 3734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao defines .http_error() on one handler (which simply returns None), and 3754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao .http_open() on another handler, which returns a Request object. 3764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 3784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = [] 3794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao count = 0 3804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for meths in meth_spec: 3814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class MockHandlerSubclass(MockHandler): pass 3824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = MockHandlerSubclass(meths) 3834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h.handler_order += count 3844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h.add_parent(opener) 3854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao count = count + 1 3864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers.append(h) 3874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(h) 3884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return handlers 3894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef build_test_opener(*handler_instances): 3914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener = OpenerDirector() 3924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for h in handler_instances: 3934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(h) 3944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return opener 3954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockHTTPHandler(urllib2.BaseHandler): 3974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # useful for testing redirections and auth 3984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # sends supplied headers and code as first response 3994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # sends 200 OK as second response 4004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, code, headers): 4014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.code = code 4024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.headers = headers 4034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.reset() 4044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def reset(self): 4054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._count = 0 4064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.requests = [] 4074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def http_open(self, req): 4084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import mimetools, httplib, copy 4094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from StringIO import StringIO 4104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.requests.append(copy.deepcopy(req)) 4114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self._count == 0: 4124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._count = self._count + 1 4134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao name = httplib.responses[self.code] 4144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao msg = mimetools.Message(StringIO(self.headers)) 4154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.parent.error( 4164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http", req, MockFile(), self.code, name, msg) 4174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 4184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.req = req 4194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao msg = mimetools.Message(StringIO("\r\n\r\n")) 4204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return MockResponse(200, "OK", msg, "", req.get_full_url()) 4214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockHTTPSHandler(urllib2.AbstractHTTPHandler): 4234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Useful for testing the Proxy-Authorization request by verifying the 4244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # properties of httpcon 4254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self): 4274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urllib2.AbstractHTTPHandler.__init__(self) 4284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.httpconn = MockHTTPClass() 4294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def https_open(self, req): 4314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.do_open(self.httpconn, req) 4324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MockPasswordManager: 4344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def add_password(self, realm, uri, user, password): 4354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.realm = realm 4364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.url = uri 4374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.user = user 4384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.password = password 4394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def find_user_password(self, realm, authuri): 4404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.target_realm = realm 4414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.target_url = authuri 4424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.user, self.password 4434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass OpenerDirectorTests(unittest.TestCase): 4464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_add_non_handler(self): 4484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class NonHandler(object): 4494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 4504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, 4514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao OpenerDirector().add_handler, NonHandler()) 4524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_badly_named_methods(self): 4544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # test work-around for three methods that accidentally follow the 4554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # naming conventions for handler methods 4564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # (*_open() / *_request() / *_response()) 4574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # These used to call the accidentally-named methods, causing a 4594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # TypeError in real code; here, returning self from these mock 4604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # methods would either cause no exception, or AttributeError. 4614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from urllib2 import URLError 4634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 4654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth_spec = [ 4664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("do_open", "return self"), ("proxy_open", "return self")], 4674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("redirect_request", "return self")], 4684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 4694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = add_ordered_mock_handlers(o, meth_spec) 4704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.add_handler(urllib2.UnknownHandler()) 4714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for scheme in "do", "proxy", "redirect": 4724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(URLError, o.open, scheme+"://example.com/") 4734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_handled(self): 4754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # handler returning non-None means no more handlers will be called 4764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 4774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth_spec = [ 4784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ["http_open", "ftp_open", "http_error_302"], 4794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ["ftp_open"], 4804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_open", "return self")], 4814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_open", "return self")], 4824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 4834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = add_ordered_mock_handlers(o, meth_spec) 4844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://example.com/") 4864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open(req) 4874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Second .http_open() gets called, third doesn't, since second returned 4884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # non-None. Handlers without .http_open() never get any methods called 4894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # on them. 4904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # In fact, second mock handler defining .http_open() returns self 4914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # (instead of response), which becomes the OpenerDirector's return 4924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # value. 4934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(r, handlers[2]) 4944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao calls = [(handlers[0], "http_open"), (handlers[2], "http_open")] 4954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for expected, got in zip(calls, o.calls): 4964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handler, name, args, kwds = got 4974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((handler, name), expected) 4984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(args, (req,)) 4994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_handler_order(self): 5014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 5024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = [] 5034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for meths, handler_order in [ 5044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ([("http_open", "return self")], 500), 5054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (["http_open"], 0), 5064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]: 5074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class MockHandlerSubclass(MockHandler): pass 5084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = MockHandlerSubclass(meths) 5094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h.handler_order = handler_order 5104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers.append(h) 5114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.add_handler(h) 5124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open("http://example.com/") 5144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # handlers called in reverse order, thanks to their sort order 5154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.calls[0][0], handlers[1]) 5164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.calls[1][0], handlers[0]) 5174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_raise(self): 5194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # raising URLError stops processing of request 5204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 5214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth_spec = [ 5224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_open", "raise")], 5234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_open", "return self")], 5244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 5254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = add_ordered_mock_handlers(o, meth_spec) 5264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://example.com/") 5284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(urllib2.URLError, o.open, req) 5294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.calls, [(handlers[0], "http_open", (req,), {})]) 5304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao## def test_error(self): 5324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao## # XXX this doesn't actually seem to be used in standard library, 5334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao## # but should really be tested anyway... 5344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_http_error(self): 5364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # XXX http_error_default 5374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # http errors are a special case 5384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 5394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth_spec = [ 5404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_open", "error 302")], 5414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_error_400", "raise"), "http_open"], 5424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_error_302", "return response"), "http_error_303", 5434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http_error"], 5444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_error_302")], 5454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 5464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = add_ordered_mock_handlers(o, meth_spec) 5474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Unknown: 5494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __eq__(self, other): return True 5504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://example.com/") 5524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open(req) 5534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert len(o.calls) == 2 5544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao calls = [(handlers[0], "http_open", (req,)), 5554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (handlers[2], "http_error_302", 5564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (req, Unknown(), 302, "", {}))] 5574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for expected, got in zip(calls, o.calls): 5584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handler, method_name, args = expected 5594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((handler, method_name), got[:2]) 5604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(args, got[2]) 5614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_processors(self): 5634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # *_request / *_response methods get called appropriately 5644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 5654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth_spec = [ 5664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_request", "return request"), 5674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("http_response", "return response")], 5684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_request", "return request"), 5694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("http_response", "return response")], 5704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 5714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = add_ordered_mock_handlers(o, meth_spec) 5724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://example.com/") 5744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open(req) 5754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # processor methods are called on *all* handlers that define them, 5764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # not just the first handler that handles the request 5774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao calls = [ 5784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (handlers[0], "http_request"), (handlers[1], "http_request"), 5794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (handlers[0], "http_response"), (handlers[1], "http_response")] 5804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i, (handler, name, args, kwds) in enumerate(o.calls): 5824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if i < 2: 5834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # *_request 5844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((handler, name), calls[i]) 5854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(args), 1) 5864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(args[0], Request) 5874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 5884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # *_response 5894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((handler, name), calls[i]) 5904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(args), 2) 5914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(args[0], Request) 5924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # response from opener.open is None, because there's no 5934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # handler that defines http_open to handle it 5944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(args[1] is None or 5954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao isinstance(args[1], MockResponse)) 5964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef sanepathname2url(path): 5994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import urllib 6004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urlpath = urllib.pathname2url(path) 6014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if os.name == "nt" and urlpath.startswith("///"): 6024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urlpath = urlpath[2:] 6034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # XXX don't ask me about the mac... 6044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return urlpath 6054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass HandlerTests(unittest.TestCase): 6074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_ftp(self): 6094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class MockFTPWrapper: 6104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, data): self.data = data 6114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def retrfile(self, filename, filetype): 6124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.filename, self.filetype = filename, filetype 6134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return StringIO.StringIO(self.data), len(self.data) 6144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def close(self): pass 6154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class NullFTPHandler(urllib2.FTPHandler): 6174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, data): self.data = data 6184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def connect_ftp(self, user, passwd, host, port, dirs, 6194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timeout=socket._GLOBAL_DEFAULT_TIMEOUT): 6204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.user, self.passwd = user, passwd 6214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.host, self.port = host, port 6224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.dirs = dirs 6234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.ftpwrapper = MockFTPWrapper(self.data) 6244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.ftpwrapper 6254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import ftplib 6274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao data = "rheum rhaponicum" 6284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = NullFTPHandler(data) 6294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 6304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for url, host, port, user, passwd, type_, dirs, filename, mimetype in [ 6324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("ftp://localhost/foo/bar/baz.html", 6334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "localhost", ftplib.FTP_PORT, "", "", "I", 6344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ["foo", "bar"], "baz.html", "text/html"), 6354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("ftp://parrot@localhost/foo/bar/baz.html", 6364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "localhost", ftplib.FTP_PORT, "parrot", "", "I", 6374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ["foo", "bar"], "baz.html", "text/html"), 6384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("ftp://%25parrot@localhost/foo/bar/baz.html", 6394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "localhost", ftplib.FTP_PORT, "%parrot", "", "I", 6404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ["foo", "bar"], "baz.html", "text/html"), 6414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("ftp://%2542parrot@localhost/foo/bar/baz.html", 6424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "localhost", ftplib.FTP_PORT, "%42parrot", "", "I", 6434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ["foo", "bar"], "baz.html", "text/html"), 6444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("ftp://localhost:80/foo/bar/", 6454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "localhost", 80, "", "", "D", 6464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ["foo", "bar"], "", None), 6474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("ftp://localhost/baz.gif;type=a", 6484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "localhost", ftplib.FTP_PORT, "", "", "A", 6494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [], "baz.gif", None), # XXX really this should guess image/gif 6504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]: 6514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(url) 6524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.timeout = None 6534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = h.ftp_open(req) 6544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # ftp authentication not yet implemented by FTPHandler 6554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(h.user, user) 6564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(h.passwd, passwd) 6574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(h.host, socket.gethostbyname(host)) 6584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(h.port, port) 6594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(h.dirs, dirs) 6604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(h.ftpwrapper.filename, filename) 6614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(h.ftpwrapper.filetype, type_) 6624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao headers = r.info() 6634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(headers.get("Content-type"), mimetype) 6644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(int(headers["Content-length"]), len(data)) 6654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_file(self): 6674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import rfc822, socket 6684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.FileHandler() 6694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 6704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao TESTFN = test_support.TESTFN 6724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urlpath = sanepathname2url(os.path.abspath(TESTFN)) 6734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao towrite = "hello, world\n" 6744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urls = [ 6754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "file://localhost%s" % urlpath, 6764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "file://%s" % urlpath, 6774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "file://%s%s" % (socket.gethostbyname('localhost'), urlpath), 6784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 6794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 6804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao localaddr = socket.gethostbyname(socket.gethostname()) 6814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except socket.gaierror: 6824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao localaddr = '' 6834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if localaddr: 6844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urls.append("file://%s%s" % (localaddr, urlpath)) 6854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for url in urls: 6874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f = open(TESTFN, "wb") 6884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 6894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 6904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f.write(towrite) 6914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 6924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f.close() 6934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = h.file_open(Request(url)) 6954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 6964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao data = r.read() 6974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao headers = r.info() 6984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao respurl = r.geturl() 6994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 7004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r.close() 7014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao stats = os.stat(TESTFN) 7024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao modified = rfc822.formatdate(stats.st_mtime) 7034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 7044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao os.remove(TESTFN) 7054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(data, towrite) 7064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(headers["Content-type"], "text/plain") 7074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(headers["Content-length"], "13") 7084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(headers["Last-modified"], modified) 7094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(respurl, url) 7104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for url in [ 7124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "file://localhost:80%s" % urlpath, 7134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "file:///file_does_not_exist.txt", 7144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "file://%s:80%s/%s" % (socket.gethostbyname('localhost'), 7154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao os.getcwd(), TESTFN), 7164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "file://somerandomhost.ontheinternet.com%s/%s" % 7174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (os.getcwd(), TESTFN), 7184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]: 7194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 7204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f = open(TESTFN, "wb") 7214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 7224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f.write(towrite) 7234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 7244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f.close() 7254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(urllib2.URLError, 7274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h.file_open, Request(url)) 7284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 7294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao os.remove(TESTFN) 7304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.FileHandler() 7324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 7334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # XXXX why does // mean ftp (and /// mean not ftp!), and where 7344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # is file: scheme specified? I think this is really a bug, and 7354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # what was intended was to distinguish between URLs like: 7364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # file:/blah.txt (a file) 7374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # file://localhost/blah.txt (a file) 7384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # file:///blah.txt (a file) 7394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # file://ftp.example.com/blah.txt (an ftp URL) 7404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for url, ftp in [ 7414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("file://ftp.example.com//foo.txt", True), 7424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("file://ftp.example.com///foo.txt", False), 7434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# XXXX bug: fails with OSError, should be URLError 7444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("file://ftp.example.com/foo.txt", False), 7454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("file://somehost//foo/something.txt", True), 7464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("file://localhost//foo/something.txt", False), 7474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]: 7484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(url) 7494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 7504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h.file_open(req) 7514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # XXXX remove OSError when bug fixed 7524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except (urllib2.URLError, OSError): 7534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not ftp) 7544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 7554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(o.req is req) 7564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.type, "ftp") 7574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.type == "ftp", ftp) 7584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_http(self): 7604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.AbstractHTTPHandler() 7624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 7634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao url = "http://example.com/" 7654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for method, data in [("GET", None), ("POST", "blah")]: 7664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(url, data, {"Foo": "bar"}) 7674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.timeout = None 7684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_unredirected_header("Spam", "eggs") 7694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao http = MockHTTPClass() 7704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = h.do_open(http, req) 7714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # result attributes 7734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r.read; r.readline # wrapped MockFile methods 7744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r.info; r.geturl # addinfourl methods 7754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r.code, r.msg == 200, "OK" # added from MockHTTPClass.getreply() 7764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hdrs = r.info() 7774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hdrs.get; hdrs.has_key # r.info() gives dict from .getreply() 7784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(r.geturl(), url) 7794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(http.host, "example.com") 7814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(http.level, 0) 7824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(http.method, method) 7834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(http.selector, "/") 7844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(http.req_headers, 7854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("Connection", "close"), 7864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("Foo", "bar"), ("Spam", "eggs")]) 7874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(http.data, data) 7884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check socket.error converted to URLError 7904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao http.raise_on_endheaders = True 7914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(urllib2.URLError, h.do_open, http, req) 7924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check adding of standard headers 7944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.addheaders = [("Spam", "eggs")] 7954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for data in "", None: # POST, GET 7964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://example.com/", data) 7974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = MockResponse(200, "OK", {}, "") 7984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newreq = h.do_request_(req) 7994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if data is None: # GET 8004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotIn("Content-length", req.unredirected_hdrs) 8014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotIn("Content-type", req.unredirected_hdrs) 8024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: # POST 8034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.unredirected_hdrs["Content-length"], "0") 8044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.unredirected_hdrs["Content-type"], 8054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "application/x-www-form-urlencoded") 8064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # XXX the details of Host could be better tested 8074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.unredirected_hdrs["Host"], "example.com") 8084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.unredirected_hdrs["Spam"], "eggs") 8094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # don't clobber existing headers 8114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_unredirected_header("Content-length", "foo") 8124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_unredirected_header("Content-type", "bar") 8134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_unredirected_header("Host", "baz") 8144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_unredirected_header("Spam", "foo") 8154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newreq = h.do_request_(req) 8164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.unredirected_hdrs["Content-length"], "foo") 8174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.unredirected_hdrs["Content-type"], "bar") 8184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.unredirected_hdrs["Host"], "baz") 8194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.unredirected_hdrs["Spam"], "foo") 8204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_http_doubleslash(self): 8224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Checks that the presence of an unnecessary double slash in a url doesn't break anything 8234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Previously, a double slash directly after the host could cause incorrect parsing of the url 8244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.AbstractHTTPHandler() 8254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 8264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao data = "" 8284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ds_urls = [ 8294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://example.com/foo/bar/baz.html", 8304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://example.com//foo/bar/baz.html", 8314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://example.com/foo//bar/baz.html", 8324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://example.com/foo/bar//baz.html", 8334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 8344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for ds_url in ds_urls: 8364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ds_req = Request(ds_url, data) 8374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check whether host is determined correctly if there is no proxy 8394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao np_ds_req = h.do_request_(ds_req) 8404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(np_ds_req.unredirected_hdrs["Host"],"example.com") 8414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check whether host is determined correctly if there is a proxy 8434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ds_req.set_proxy("someproxy:3128",None) 8444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao p_ds_req = h.do_request_(ds_req) 8454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(p_ds_req.unredirected_hdrs["Host"],"example.com") 8464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_fixpath_in_weirdurls(self): 8484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Issue4493: urllib2 to supply '/' when to urls where path does not 8494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # start with'/' 8504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.AbstractHTTPHandler() 8524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 8534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao weird_url = 'http://www.python.org?getspam' 8554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(weird_url) 8564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newreq = h.do_request_(req) 8574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(newreq.get_host(),'www.python.org') 8584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(newreq.get_selector(),'/?getspam') 8594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao url_without_path = 'http://www.python.org' 8614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(url_without_path) 8624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newreq = h.do_request_(req) 8634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(newreq.get_host(),'www.python.org') 8644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(newreq.get_selector(),'') 8654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_errors(self): 8674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.HTTPErrorProcessor() 8684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 8694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao url = "http://example.com/" 8714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(url) 8724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # all 2xx are passed through 8734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = MockResponse(200, "OK", {}, "", url) 8744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newr = h.http_response(req, r) 8754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(r is newr) 8764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not hasattr(o, "proto")) # o.error not called 8774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = MockResponse(202, "Accepted", {}, "", url) 8784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newr = h.http_response(req, r) 8794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(r is newr) 8804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not hasattr(o, "proto")) # o.error not called 8814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = MockResponse(206, "Partial content", {}, "", url) 8824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newr = h.http_response(req, r) 8834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(r is newr) 8844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not hasattr(o, "proto")) # o.error not called 8854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # anything else calls o.error (and MockOpener returns None, here) 8864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = MockResponse(502, "Bad gateway", {}, "", url) 8874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(h.http_response(req, r) is None) 8884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.proto, "http") # o.error called 8894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.args, (req, r, 502, "Bad gateway", {})) 8904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_cookies(self): 8924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cj = MockCookieJar() 8934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.HTTPCookieProcessor(cj) 8944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 8954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://example.com/") 8974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = MockResponse(200, "OK", {}, "") 8984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newreq = h.http_request(req) 8994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(cj.ach_req is req is newreq) 9004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_origin_req_host(), "example.com") 9014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not req.is_unverifiable()) 9024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newr = h.http_response(req, r) 9034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(cj.ec_req is req) 9044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(cj.ec_r is r is newr) 9054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_redirect(self): 9074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from_url = "http://example.com/a.html" 9084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao to_url = "http://example.com/b.html" 9094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.HTTPRedirectHandler() 9104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 9114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # ordinary redirect behaviour 9134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for code in 301, 302, 303, 307: 9144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for data in None, "blah\nblah\n": 9154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao method = getattr(h, "http_error_%s" % code) 9164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(from_url, data) 9174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_header("Nonsense", "viking=withhold") 9184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT 9194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if data is not None: 9204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_header("Content-Length", str(len(data))) 9214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_unredirected_header("Spam", "spam") 9224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 9234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao method(req, MockFile(), code, "Blah", 9244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao MockHeaders({"location": to_url})) 9254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except urllib2.HTTPError: 9264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 307 in response to POST requires user OK 9274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(code == 307 and data is not None) 9284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.req.get_full_url(), to_url) 9294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 9304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.req.get_method(), "GET") 9314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except AttributeError: 9324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not o.req.has_data()) 9334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # now it's a GET, there should not be headers regarding content 9354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # (possibly dragged from before being a POST) 9364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao headers = [x.lower() for x in o.req.headers] 9374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotIn("content-length", headers) 9384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotIn("content-type", headers) 9394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.req.headers["Nonsense"], 9414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "viking=withhold") 9424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotIn("Spam", o.req.headers) 9434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotIn("Spam", o.req.unredirected_hdrs) 9444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # loop detection 9464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(from_url) 9474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT 9484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def redirect(h, req, url=to_url): 9494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h.http_error_302(req, MockFile(), 302, "Blah", 9504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao MockHeaders({"location": url})) 9514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Note that the *original* request shares the same record of 9524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # redirections with the sub-requests caused by the redirections. 9534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # detect infinite loop redirect of a URL to itself 9554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(from_url, origin_req_host="example.com") 9564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao count = 0 9574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT 9584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 9594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao while 1: 9604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao redirect(h, req, "http://example.com/") 9614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao count = count + 1 9624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except urllib2.HTTPError: 9634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # don't stop until max_repeats, because cookies may introduce state 9644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(count, urllib2.HTTPRedirectHandler.max_repeats) 9654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # detect endless non-repeating chain of redirects 9674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(from_url, origin_req_host="example.com") 9684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao count = 0 9694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT 9704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 9714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao while 1: 9724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao redirect(h, req, "http://example.com/%d" % count) 9734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao count = count + 1 9744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except urllib2.HTTPError: 9754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(count, 9764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urllib2.HTTPRedirectHandler.max_redirections) 9774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_invalid_redirect(self): 9794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from_url = "http://example.com/a.html" 9804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao valid_schemes = ['http', 'https', 'ftp'] 9814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao invalid_schemes = ['file', 'imap', 'ldap'] 9824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao schemeless_url = "example.com/b.html" 9834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h = urllib2.HTTPRedirectHandler() 9844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = h.parent = MockOpener() 9854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(from_url) 9864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT 9874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for scheme in invalid_schemes: 9894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao invalid_url = scheme + '://' + schemeless_url 9904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(urllib2.HTTPError, h.http_error_302, 9914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req, MockFile(), 302, "Security Loophole", 9924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao MockHeaders({"location": invalid_url})) 9934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for scheme in valid_schemes: 9954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao valid_url = scheme + '://' + schemeless_url 9964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h.http_error_302(req, MockFile(), 302, "That's fine", 9974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao MockHeaders({"location": valid_url})) 9984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(o.req.get_full_url(), valid_url) 9994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_cookie_redirect(self): 10014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # cookies shouldn't leak into redirected requests 10024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from cookielib import CookieJar 10034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from test.test_cookielib import interact_netscape 10054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cj = CookieJar() 10074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao interact_netscape(cj, "http://www.example.com/", "spam=eggs") 10084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hh = MockHTTPHandler(302, "Location: http://www.cracker.com/\r\n\r\n") 10094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hdeh = urllib2.HTTPDefaultErrorHandler() 10104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hrh = urllib2.HTTPRedirectHandler() 10114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cp = urllib2.HTTPCookieProcessor(cj) 10124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_test_opener(hh, hdeh, hrh, cp) 10134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.open("http://www.example.com/") 10144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not hh.req.has_header("Cookie")) 10154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_redirect_fragment(self): 10174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao redirected_url = 'http://www.example.com/index.html#OK\r\n\r\n' 10184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hh = MockHTTPHandler(302, 'Location: ' + redirected_url) 10194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hdeh = urllib2.HTTPDefaultErrorHandler() 10204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hrh = urllib2.HTTPRedirectHandler() 10214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_test_opener(hh, hdeh, hrh) 10224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fp = o.open('http://www.example.com') 10234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(fp.geturl(), redirected_url.strip()) 10244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_proxy(self): 10264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 10274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ph = urllib2.ProxyHandler(dict(http="proxy.example.com:3128")) 10284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.add_handler(ph) 10294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth_spec = [ 10304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("http_open", "return response")] 10314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 10324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = add_ordered_mock_handlers(o, meth_spec) 10334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://acme.example.com/") 10354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "acme.example.com") 10364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open(req) 10374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "proxy.example.com:3128") 10384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual([(handlers[0], "http_open")], 10404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [tup[0:2] for tup in o.calls]) 10414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_proxy_no_proxy(self): 10434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao os.environ['no_proxy'] = 'python.org' 10444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 10454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ph = urllib2.ProxyHandler(dict(http="proxy.example.com")) 10464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.add_handler(ph) 10474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://www.perl.org/") 10484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "www.perl.org") 10494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open(req) 10504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "proxy.example.com") 10514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://www.python.org") 10524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "www.python.org") 10534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open(req) 10544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "www.python.org") 10554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao del os.environ['no_proxy'] 10564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_proxy_https(self): 10594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 10604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ph = urllib2.ProxyHandler(dict(https='proxy.example.com:3128')) 10614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.add_handler(ph) 10624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth_spec = [ 10634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [("https_open","return response")] 10644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 10654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao handlers = add_ordered_mock_handlers(o, meth_spec) 10664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("https://www.example.com/") 10674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "www.example.com") 10684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open(req) 10694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "proxy.example.com:3128") 10704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual([(handlers[0], "https_open")], 10714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [tup[0:2] for tup in o.calls]) 10724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_proxy_https_proxy_authorization(self): 10744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = OpenerDirector() 10754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ph = urllib2.ProxyHandler(dict(https='proxy.example.com:3128')) 10764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.add_handler(ph) 10774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao https_handler = MockHTTPSHandler() 10784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o.add_handler(https_handler) 10794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("https://www.example.com/") 10804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_header("Proxy-Authorization","FooBar") 10814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req.add_header("User-Agent","Grail") 10824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "www.example.com") 10834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsNone(req._tunnel_host) 10844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = o.open(req) 10854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify Proxy-Authorization gets tunneled to request. 10864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # httpsconn req_headers do not have the Proxy-Authorization header but 10874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the req will have. 10884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotIn(("Proxy-Authorization","FooBar"), 10894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao https_handler.httpconn.req_headers) 10904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIn(("User-Agent","Grail"), 10914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao https_handler.httpconn.req_headers) 10924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsNotNone(req._tunnel_host) 10934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_host(), "proxy.example.com:3128") 10944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_header("Proxy-authorization"),"FooBar") 10954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_auth(self, quote_char='"'): 10974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener = OpenerDirector() 10984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao password_manager = MockPasswordManager() 10994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao auth_handler = urllib2.HTTPBasicAuthHandler(password_manager) 11004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm = "ACME Widget Store" 11014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao http_handler = MockHTTPHandler( 11024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 401, 'WWW-Authenticate: Basic realm=%s%s%s\r\n\r\n' % 11034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (quote_char, realm, quote_char) ) 11044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(auth_handler) 11054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(http_handler) 11064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._test_basic_auth(opener, auth_handler, "Authorization", 11074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm, http_handler, password_manager, 11084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://acme.example.com/protected", 11094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://acme.example.com/protected" 11104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ) 11114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_auth_with_single_quoted_realm(self): 11134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.test_basic_auth(quote_char="'") 11144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_auth_with_unquoted_realm(self): 11164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener = OpenerDirector() 11174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao password_manager = MockPasswordManager() 11184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao auth_handler = urllib2.HTTPBasicAuthHandler(password_manager) 11194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm = "ACME Widget Store" 11204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao http_handler = MockHTTPHandler( 11214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 401, 'WWW-Authenticate: Basic realm=%s\r\n\r\n' % realm) 11224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(auth_handler) 11234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(http_handler) 11244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao msg = "Basic Auth Realm was unquoted" 11254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao with test_support.check_warnings((msg, UserWarning)): 11264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._test_basic_auth(opener, auth_handler, "Authorization", 11274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm, http_handler, password_manager, 11284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://acme.example.com/protected", 11294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://acme.example.com/protected" 11304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ) 11314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_proxy_basic_auth(self): 11344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener = OpenerDirector() 11354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ph = urllib2.ProxyHandler(dict(http="proxy.example.com:3128")) 11364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(ph) 11374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao password_manager = MockPasswordManager() 11384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao auth_handler = urllib2.ProxyBasicAuthHandler(password_manager) 11394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm = "ACME Networks" 11404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao http_handler = MockHTTPHandler( 11414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm) 11424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(auth_handler) 11434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(http_handler) 11444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._test_basic_auth(opener, auth_handler, "Proxy-authorization", 11454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm, http_handler, password_manager, 11464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://acme.example.com:3128/protected", 11474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "proxy.example.com:3128", 11484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ) 11494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_and_digest_auth_handlers(self): 11514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # HTTPDigestAuthHandler raised an exception if it couldn't handle a 40* 11524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # response (http://python.org/sf/1479302), where it should instead 11534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # return None to allow another handler (especially 11544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # HTTPBasicAuthHandler) to handle the response. 11554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Also (http://python.org/sf/14797027, RFC 2617 section 1.2), we must 11574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # try digest first (since it's the strongest auth scheme), so we record 11584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # order of calls here to check digest comes first: 11594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class RecordingOpenerDirector(OpenerDirector): 11604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self): 11614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao OpenerDirector.__init__(self) 11624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.recorded = [] 11634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def record(self, info): 11644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.recorded.append(info) 11654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class TestDigestAuthHandler(urllib2.HTTPDigestAuthHandler): 11664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def http_error_401(self, *args, **kwds): 11674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.parent.record("digest") 11684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urllib2.HTTPDigestAuthHandler.http_error_401(self, 11694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao *args, **kwds) 11704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class TestBasicAuthHandler(urllib2.HTTPBasicAuthHandler): 11714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def http_error_401(self, *args, **kwds): 11724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.parent.record("basic") 11734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao urllib2.HTTPBasicAuthHandler.http_error_401(self, 11744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao *args, **kwds) 11754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener = RecordingOpenerDirector() 11774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao password_manager = MockPasswordManager() 11784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao digest_handler = TestDigestAuthHandler(password_manager) 11794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao basic_handler = TestBasicAuthHandler(password_manager) 11804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm = "ACME Networks" 11814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao http_handler = MockHTTPHandler( 11824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 401, 'WWW-Authenticate: Basic realm="%s"\r\n\r\n' % realm) 11834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(basic_handler) 11844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(digest_handler) 11854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao opener.add_handler(http_handler) 11864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check basic auth isn't blocked by digest handler failing 11884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._test_basic_auth(opener, basic_handler, "Authorization", 11894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm, http_handler, password_manager, 11904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://acme.example.com/protected", 11914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "http://acme.example.com/protected", 11924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ) 11934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check digest was tried before basic (twice, because 11944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # _test_basic_auth called .open() twice) 11954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(opener.recorded, ["digest", "basic"]*2) 11964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def _test_basic_auth(self, opener, auth_handler, auth_header, 11984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao realm, http_handler, password_manager, 11994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao request_url, protected_url): 12004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import base64 12014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao user, password = "wile", "coyote" 12024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # .add_password() fed through to password manager 12044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao auth_handler.add_password(realm, request_url, user, password) 12054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(realm, password_manager.realm) 12064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(request_url, password_manager.url) 12074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(user, password_manager.user) 12084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(password, password_manager.password) 12094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = opener.open(request_url) 12114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # should have asked the password manager for the username/password 12134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(password_manager.target_realm, realm) 12144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(password_manager.target_url, protected_url) 12154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # expect one request without authorization, then one with 12174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(http_handler.requests), 2) 12184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertFalse(http_handler.requests[0].has_header(auth_header)) 12194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao userpass = '%s:%s' % (user, password) 12204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao auth_hdr_value = 'Basic '+base64.encodestring(userpass).strip() 12214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(http_handler.requests[1].get_header(auth_header), 12224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao auth_hdr_value) 12234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(http_handler.requests[1].unredirected_hdrs[auth_header], 12244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao auth_hdr_value) 12254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # if the password manager can't find a password, the handler won't 12264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # handle the HTTP auth error 12274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao password_manager.user = password_manager.password = None 12284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao http_handler.reset() 12294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = opener.open(request_url) 12304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(http_handler.requests), 1) 12314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertFalse(http_handler.requests[0].has_header(auth_header)) 12324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MiscTests(unittest.TestCase): 12344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_build_opener(self): 12364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class MyHTTPHandler(urllib2.HTTPHandler): pass 12374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class FooHandler(urllib2.BaseHandler): 12384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def foo_open(self): pass 12394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class BarHandler(urllib2.BaseHandler): 12404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def bar_open(self): pass 12414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao build_opener = urllib2.build_opener 12434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_opener(FooHandler, BarHandler) 12454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, FooHandler) 12464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, BarHandler) 12474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # can take a mix of classes and instances 12494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_opener(FooHandler, BarHandler()) 12504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, FooHandler) 12514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, BarHandler) 12524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # subclasses of default handlers override default handlers 12544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_opener(MyHTTPHandler) 12554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, MyHTTPHandler) 12564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # a particular case of overriding: default handlers can be passed 12584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # in explicitly 12594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_opener() 12604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, urllib2.HTTPHandler) 12614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_opener(urllib2.HTTPHandler) 12624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, urllib2.HTTPHandler) 12634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_opener(urllib2.HTTPHandler()) 12644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, urllib2.HTTPHandler) 12654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Issue2670: multiple handlers sharing the same base class 12674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class MyOtherHTTPHandler(urllib2.HTTPHandler): pass 12684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao o = build_opener(MyHTTPHandler, MyOtherHTTPHandler) 12694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, MyHTTPHandler) 12704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.opener_has_handler(o, MyOtherHTTPHandler) 12714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def opener_has_handler(self, opener, handler_class): 12734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for h in opener.handlers: 12744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if h.__class__ == handler_class: 12754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao break 12764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 12774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(False) 12784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass RequestTests(unittest.TestCase): 12804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def setUp(self): 12824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.get = urllib2.Request("http://www.python.org/~jeremy/") 12834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.post = urllib2.Request("http://www.python.org/~jeremy/", 12844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "data", 12854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao headers={"X-Test": "test"}) 12864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_method(self): 12884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("POST", self.post.get_method()) 12894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("GET", self.get.get_method()) 12904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_add_data(self): 12924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not self.get.has_data()) 12934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("GET", self.get.get_method()) 12944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.get.add_data("spam") 12954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(self.get.has_data()) 12964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("POST", self.get.get_method()) 12974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_get_full_url(self): 12994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("http://www.python.org/~jeremy/", 13004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.get.get_full_url()) 13014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_selector(self): 13034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("/~jeremy/", self.get.get_selector()) 13044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = urllib2.Request("http://www.python.org/") 13054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("/", req.get_selector()) 13064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_get_type(self): 13084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("http", self.get.get_type()) 13094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_get_host(self): 13114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("www.python.org", self.get.get_host()) 13124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_get_host_unquote(self): 13144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = urllib2.Request("http://www.%70ython.org/") 13154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("www.python.org", req.get_host()) 13164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_proxy(self): 13184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not self.get.has_proxy()) 13194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.get.set_proxy("www.perl.org", "http") 13204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(self.get.has_proxy()) 13214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("www.python.org", self.get.get_origin_req_host()) 13224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("www.perl.org", self.get.get_host()) 13234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_wrapped_url(self): 13254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("<URL:http://www.python.org>") 13264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("www.python.org", req.get_host()) 13274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_url_fragment(self): 13294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://www.python.org/?qs=query#fragment=true") 13304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("/?qs=query", req.get_selector()) 13314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request("http://www.python.org/#fun=true") 13324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual("/", req.get_selector()) 13334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Issue 11703: geturl() omits fragment in the original URL. 13354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao url = 'http://docs.python.org/library/urllib2.html#OK' 13364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao req = Request(url) 13374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(req.get_full_url(), url) 13384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_HTTPError_interface(self): 13404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 13414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Issue 13211 reveals that HTTPError didn't implement the URLError 13424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao interface even though HTTPError is a subclass of URLError. 13434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> err = urllib2.HTTPError(msg='something bad happened', url=None, code=None, hdrs=None, fp=None) 13454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> assert hasattr(err, 'reason') 13464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao >>> err.reason 13474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'something bad happened' 13484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 13494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_HTTPError_interface_call(self): 13514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 13524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Issue 15701= - HTTPError interface has info method available from URLError. 13534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 13544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao err = urllib2.HTTPError(msg='something bad happened', url=None, 13554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao code=None, hdrs='Content-Length:42', fp=None) 13564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(hasattr(err, 'reason')) 13574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert hasattr(err, 'reason') 13584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert hasattr(err, 'info') 13594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert callable(err.info) 13604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 13614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao err.info() 13624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except AttributeError: 13634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.fail("err.info() failed") 13644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(err.info(), "Content-Length:42") 13654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_main(verbose=None): 13674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from test import test_urllib2 13684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_support.run_doctest(test_urllib2, verbose) 13694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_support.run_doctest(urllib2, verbose) 13704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tests = (TrivialTests, 13714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao OpenerDirectorTests, 13724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao HandlerTests, 13734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao MiscTests, 13744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao RequestTests) 13754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_support.run_unittest(*tests) 13764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == "__main__": 13784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_main(verbose=True) 1379