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